如何在图像中找到局部最大值和最小值

时间:2015-05-21 08:56:12

标签: java opencv image-processing mask javacv

我正在学习如何在图像中获得局部和全局最大值,并且据我们所知,在一个图像中只有一个全局最大值和一个全局最小值,并且我设法获得这些值及其相应位置图片。所以我的问题是:

  1. 如何获取图片中的局部最大值
  2. 如何获取图像中的局部最小值
  3. 正如您在下面的代码中看到的,我正在使用掩码,但在运行时我接收到下面提到的错误消息。所以请让我知道为什么我们需要面膜以及如何正确使用它。
  4. 更新

    第32行是:MinMaxLocResult s = Core.minMaxLoc(gsMat, mask);

    public static void main(String[] args) {
        MatFactory matFactory = new MatFactory();
        FilePathUtils.addInputPath(path_Obj);
        Mat bgrMat = matFactory.newMat(FilePathUtils.getInputFileFullPathList().get(0));
    
        Mat gsMat = SysUtils.rgbToGrayScaleMat(bgrMat);
        Log.D(TAG, "main", "gsMat.dump(): \n" + gsMat.dump());
    
        Mat mask = new Mat(new Size(3,3), CvType.CV_8U);//which type i should set for the mask
    
        MinMaxLocResult s = Core.minMaxLoc(gsMat, mask);
        Log.D(TAG, "main", "s.maxVal: " + s.maxVal);//to get the global maximum
        Log.D(TAG, "main", "s.minVal: " + s.minVal);//to get the global minimum
        Log.D(TAG, "main", "s.maxLoc: " + s.maxLoc);//to get the coordinates of the global maximum
        Log.D(TAG, "main", "s.minLoc: " + s.minLoc);//to get the coordinates of the global minimum
    }
    

    错误消息

    OpenCV Error: Assertion failed (A.size == arrays[i0]->size) in cv::NAryMatIterator::init, file ..\..\..\..\opencv\modules\core\src\matrix.cpp, line 3197
    Exception in thread "main" CvException [org.opencv.core.CvException: ..\..\..\..\opencv\modules\core\src\matrix.cpp:3197: error: (-215) A.size == arrays[i0]->size in function cv::NAryMatIterator::init
    ]
    at org.opencv.core.Core.n_minMaxLocManual(Native Method)
    at org.opencv.core.Core.minMaxLoc(Core.java:7919)
    at com.example.globallocalmaxima_00.MainClass.main(MainClass.java:32)
    

1 个答案:

答案 0 :(得分:1)

为了计算全局最小/最大值,您不需要完全使用mask

为了计算局部最小值/最大值,你可以做一点技巧。您需要执行扩张/侵蚀操作,然后将像素值与原始图像的值进行比较。如果原始图像和扩张/侵蚀图像的值相等,则该像素是局部最小值/最大值

代码如下:

Mat eroded = new Mat();
Mat dilated = new Mat();
Imgproc.erode(gsMat, eroded, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)));
Imgproc.dilate(gsMat, dilate, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)));

Mat localMin = new Mat(gsMat.size(), CvType.CV_8U, new Scalar(0));
Mat localMax = new Mat(gsMat.size(), CvType.CV_8U, new Scalar(0));

for (int i=0; i<gsMat.height; i++)
    for (int j=0; j<gsMat.width; j++)
    {
         if (gsMat.get(i,j) == eroded.get(i,j))
             localMin.put(i,j,255);
         if (gsMat.get(i,j) == dilated.get(i,j))
             localMax.put(i,j,255);
    }

请注意,我不是Java程序员。所以,代码只是算法的例证。