Ask Your Question

Revision history [back]

Mostafa Sataki's solution was really helpful. However I could not find any java implementation for the same and so decided to implement the same logic in java. So this answer is for anyone looking for the same solution implemented in Java.

Logical order of processing remains the same 1- compute Laplacian of image .

2 - compute horizontal & vertical projection

3 - evaluation of changes in both directions.

4 - find the maximum peak Find in the side of the gradient image.

I can gladly explain what I did here if anyone wants to know more :)

public static Mat borderSubtracter(String file_path) {
        try{
            Mat rawImage = Imgcodecs.imread(file_path);
            Mat originalImage = rawImage.clone();

            Imgproc.cvtColor(rawImage, rawImage, Imgproc.COLOR_BGR2GRAY);
            Mat sobelX = new Mat();
            Mat sobelY = new Mat();
                    //Sobel in X and Y planes
            Imgproc.Sobel(rawImage, sobelX, CvType.CV_32FC1, 2, 0 ,5 , 0.1, Core.BORDER_DEFAULT);
            Imgproc.Sobel(rawImage, sobelY, CvType.CV_32FC1, 0, 2 , 5 , 0.1, Core.BORDER_DEFAULT);

            Mat summedImage = new Mat();
            Core.add(sobelX, sobelY, summedImage);
            sobelX.release();sobelY.release();

            Mat normalized = new Mat();

            Core.normalize(summedImage, normalized,0,255,Core.NORM_MINMAX,CvType.CV_8UC1);
            summedImage.release();

            Mat reducedX = new Mat();
            Core.reduce(normalized, reducedX, 0, Core.REDUCE_AVG,CvType.CV_8UC1);

            Mat reducedY = new Mat();
            Core.reduce(normalized, reducedY, 1, Core.REDUCE_AVG,CvType.CV_8UC1);
            normalized.release();

            Mat reducedSobelX = new Mat();
            Imgproc.Sobel(reducedX, reducedSobelX, reducedX.depth(), 2, 0);
            reducedX.release();

            Mat reducedSobelY = new Mat();
            Imgproc.Sobel(reducedY, reducedSobelY, reducedX.depth(), 0, 2);
            reducedY.release();
            //finding maximum values in both x and y planes
            Point peak_point;
            int half_pos = (int) reducedSobelX.total() / 2;

            Rect result = new Rect();

            MinMaxLocResult mmr = Core.minMaxLoc(reducedSobelX.colRange(new Range(0,half_pos)));
            peak_point = mmr.maxLoc;
            result.x = (int) peak_point.x;
            mmr = Core.minMaxLoc(reducedSobelX.colRange(new Range(half_pos, (int) reducedSobelX.total())));
            peak_point = mmr.maxLoc;
            result.width = (int) ( peak_point.x + half_pos - result.x);


            half_pos = (int) reducedSobelY.total() / 2;
            mmr = Core.minMaxLoc(reducedSobelY.rowRange(new Range(0,half_pos)));
            peak_point = mmr.maxLoc;
            result.y = (int) peak_point.y;

            mmr = Core.minMaxLoc(reducedSobelY.rowRange(new Range(half_pos, (int) reducedSobelY.total())));
            peak_point = mmr.maxLoc;
            result.height = (int)(peak_point.y + half_pos - result.y);

            Imgproc.rectangle(originalImage, result.br(), result.tl(), new Scalar(0,255,0), 5);
                    return originalImage;
        }catch (Exception e){
            System.out.println(e.toString());
        }