From 48416f2842999c64420de086c02d94bf79735418 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 29 Sep 2026 17:58:03 +0200 Subject: [PATCH] Fix complex morphology --- .../morphology/ComplexMorphology.java | 64 +++++++++++++++++-- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/src/main/java/domain/image/processing/morphology/ComplexMorphology.java b/src/main/java/domain/image/processing/morphology/ComplexMorphology.java index 965b268..7278a2a 100644 --- a/src/main/java/domain/image/processing/morphology/ComplexMorphology.java +++ b/src/main/java/domain/image/processing/morphology/ComplexMorphology.java @@ -37,9 +37,11 @@ public class ComplexMorphology { while (true) { Mat dilated = new Mat(); + Imgproc.dilate(current, dilated, kernel); Mat next = new Mat(); + Core.min(dilated, maskMat, next); double difference = Core.norm(next, current, Core.NORM_INF); @@ -53,7 +55,13 @@ public class ComplexMorphology { } public static GrayScaleMatrix medianFilter(Image image, int tailleMasque) { - Mat input = toMat(image); + if (tailleMasque < 1 || tailleMasque % 2 == 0) { + throw new IllegalArgumentException( + "Median filter size must be a positive odd number" + ); + } + + Mat input = to8BitMat(image); Mat result = new Mat(); Imgproc.medianBlur(input, result, tailleMasque); @@ -61,6 +69,10 @@ public class ComplexMorphology { return toGrayScaleMatrix(result); } + /** + * Converts an image to a CV_64F grayscale matrix. + * Used by geodesic morphology operations. + */ private static Mat toMat(Image image) { GrayScaleMatrix gray = image.toGrayScale(); @@ -78,8 +90,39 @@ public class ComplexMorphology { return mat; } + /** + * Converts an image to an 8-bit grayscale matrix. + * Required by OpenCV medianBlur(). + */ + private static Mat to8BitMat(Image image) { + GrayScaleMatrix gray = image.toGrayScale(); + + int width = gray.getWidth(); + int height = gray.getHeight(); + + Mat mat = new Mat(height, width, CvType.CV_8UC1); + + double[][] data = gray.getRawData(); + + for (int y = 0; y < height; y++) { + byte[] row = new byte[width]; + + for (int x = 0; x < width; x++) { + int value = (int) Math.round(data[y][x]); + value = Math.clamp(value, 0, 255); + + row[x] = (byte) value; + } + + mat.put(y, 0, row); + } + + return mat; + } + private static Mat createKernel(int size) { - return Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(size, size)); + return Imgproc.getStructuringElement( Imgproc.MORPH_RECT, new Size(size, size) + ); } private static GrayScaleMatrix toGrayScaleMatrix(Mat mat) { @@ -88,9 +131,20 @@ public class ComplexMorphology { double[][] output = new double[height][width]; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - output[y][x] = mat.get(y, x)[0]; + if (mat.type() == CvType.CV_8UC1) { + for (int y = 0; y < height; y++) { + byte[] row = new byte[width]; + mat.get(y, 0, row); + + for (int x = 0; x < width; x++) { + output[y][x] = Byte.toUnsignedInt(row[x]); + } + } + } else { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + output[y][x] = mat.get(y, x)[0]; + } } }