All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.algart.matrices.skeletons.ThinningTools Maven / Gradle / Ivy

Go to download

Open-source Java libraries, supporting generalized smart arrays and matrices with elements of any types, including a wide set of 2D-, 3D- and multidimensional image processing and other algorithms, working with arrays and matrices.

There is a newer version: 1.4.23
Show newest version
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2007-2024 Daniel Alievsky, AlgART Laboratory (http://algart.net)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package net.algart.matrices.skeletons;

import net.algart.arrays.*;
import net.algart.matrices.morphology.IterativeErosion;
import net.algart.math.patterns.Patterns;
import net.algart.math.IPoint;
import net.algart.math.functions.Func;

/**
 * Helper class (collection of functions) to simplify implementation of skeletization classes.
 */
class ThinningTools {
    private ThinningTools() {
    }

    static long estimatedNumberOfIterations(Matrix matrix, boolean topological) {
        int dc = matrix.dimCount();
        long n = IterativeErosion.estimatedNumberOfIterations(matrix,
                Patterns.newRectangularIntegerPattern(point(-1, -1, dc), point(1, 1, dc)));
        if (topological)
            n = Math.min(n, Long.MAX_VALUE / 8) * 8; // rotten heuristics
        return n;
    }

    private static long[] coordinates(int x, int y, int dimCount) {
        long[] coordinates = new long[dimCount];
        coordinates[0] = x;
        if (coordinates.length > 0)
            coordinates[1] = y;
        return coordinates;
    }

    private static IPoint point(int x, int y, int dimCount) {
        return IPoint.valueOf(coordinates(x, y, dimCount));
    }

    static Matrix[] shifts(Matrix bitMatrix, int[] xy) {
        assert xy.length % 2 == 0;
        Matrix[] result = new Matrix[xy.length / 2];
        for (int k = 0; k < result.length; k++) {
            result[k] = Matrices.asShifted(bitMatrix, coordinates(xy[2 * k], xy[2 * k + 1], bitMatrix.dimCount()));
        }
        return result;
    }

    static Matrix shift(Matrix bitMatrix, int[] xy) {
        return Matrices.asShifted(bitMatrix, coordinates(xy[0], xy[1], bitMatrix.dimCount())).cast(BitArray.class);
    }

    static Matrix or(Matrix... bitMatrices) {
        return Matrices.asFuncMatrix(Func.MAX, BitArray.class, Matrices.several(BitArray.class, bitMatrices));
    }

    static Matrix and(Matrix... bitMatrices) {
        return Matrices.asFuncMatrix(Func.MIN, BitArray.class, Matrices.several(BitArray.class, bitMatrices));
    }

    static Matrix andNot(Matrix a, Matrix b) {
        return Matrices.asFuncMatrix(Func.POSITIVE_DIFF, BitArray.class, a, b);
    }

    static Matrix not(Matrix bitMatrix) {
        return Matrices.asFuncMatrix(Func.REVERSE, BitArray.class, bitMatrix);
    }

    /*Repeat() 90 ==> 180,,270 */

    static int[][] rotate90(int[][] xy) {
        int[][] result = new int[xy.length][];
        for (int k = 0; k < result.length; k++) {
            result[k] = rotate90(xy[k]);
        }
        return result;
    }

    /*Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! */

    static int[][] rotate180(int[][] xy) {
        int[][] result = new int[xy.length][];
        for (int k = 0; k < result.length; k++) {
            result[k] = rotate180(xy[k]);
        }
        return result;
    }

    static int[][] rotate270(int[][] xy) {
        int[][] result = new int[xy.length][];
        for (int k = 0; k < result.length; k++) {
            result[k] = rotate270(xy[k]);
        }
        return result;
    }

    /*Repeat.AutoGeneratedEnd*/

    private static int[] rotate90(int[] xy) {
        int[] result = new int[xy.length];
        for (int k = 0; k < result.length; k += 2) {
            result[k] = -xy[k + 1];
            result[k + 1] = xy[k];
        }
        return result;
    }

    private static int[] rotate180(int[] xy) {
        int[] result = new int[xy.length];
        for (int k = 0; k < result.length; k += 2) {
            result[k] = -xy[k];
            result[k + 1] = -xy[k + 1];
        }
        return result;
    }

    private static int[] rotate270(int[] xy) {
        int[] result = new int[xy.length];
        for (int k = 0; k < result.length; k += 2) {
            result[k] = xy[k + 1];
            result[k + 1] = -xy[k];
        }
        return result;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy