maxUsedValInHistogramData

maxUsedValInHistogramData

我正在尝试使用openCV在C++中重新实现matlab imregionalmax(),我在网站上进行了搜索,并在此处找到了一些有趣的答案Find local maxima in grayscale image using OpenCV,到目前为止,最好的一个属于Doga Siyli,但是有2个“怪异”功能。第一个是:SANITYCHECK(squareSize,3,1),另一个是:maxUsedValInHistogramData(dst,false);
(“怪异”是指我不认为这两个是OpenCV的功能。)

我的问题是:

我用SANITYCHECK(squaresize,3,1)替换了assert(squareSize >= 3);,用maxUsedValInHistogramData(dst,false);替换了minmaxLoc,但是该程序无法正常工作,尤其是第二个程序,因为minmaxLoc返回全局值,而Doga的目的是寻找局部值。

那么如何使代码正常工作呢?

我是C++和OpenCV的新手,并且我还在学习,对您的帮助将不胜感激。

这是他的代码,供您仔细查看(他的解释很清楚)

    void localMaxima(cv::Mat src, cv::Mat &dst, int squareSize)
{
if (squareSize == 0)
{
    dst = src.clone();
    return;
}

Mat m0;
dst = src.clone();
Point maxLoc(0, 0);

//1.Be sure to have at least 3x3 for at least looking at 1 pixel close neighbours
//  Also the window must be <odd>x<odd>
SANITYCHECK(squareSize, 3, 1);
int sqrCenter = (squareSize - 1) / 2;

//2.Create the localWindow mask to get things done faster
//  When we find a local maxima we will multiply the subwindow with this MASK
//  So that we will not search for those 0 values again and again
Mat localWindowMask = Mat::zeros(Size(squareSize, squareSize), CV_8U);//boolean
localWindowMask.at<unsigned char>(sqrCenter, sqrCenter) = 1;

//3.Find the threshold value to threshold the image
//this function here returns the peak of histogram of picture
//the picture is a thresholded picture it will have a lot of zero values in it
//so that the second boolean variable says :
//  (boolean) ? "return peak even if it is at 0" : "return peak discarding 0"
int thrshld = maxUsedValInHistogramData(dst, false);
threshold(dst, m0, thrshld, 1, THRESH_BINARY);

//4.Now delete all thresholded values from picture
dst = dst.mul(m0);

//put the src in the middle of the big array
for (int row = sqrCenter; row<dst.size().height - sqrCenter; row++)
    for (int col = sqrCenter; col<dst.size().width - sqrCenter; col++)
    {
        //1.if the value is zero it can not be a local maxima
        if (dst.at<unsigned char>(row, col) == 0)
            continue;
        //2.the value at (row,col) is not 0 so it can be a local maxima point
        m0 = dst.colRange(col - sqrCenter, col + sqrCenter + 1).rowRange(row - sqrCenter, row + sqrCenter + 1);
        minMaxLoc(m0, NULL, NULL, NULL, &maxLoc);
        //if the maximum location of this subWindow is at center
        //it means we found the local maxima
        //so we should delete the surrounding values which lies in the subWindow area
        //hence we will not try to find if a point is at localMaxima when already found a neighbour was
        if ((maxLoc.x == sqrCenter) && (maxLoc.y == sqrCenter))
        {
            m0 = m0.mul(localWindowMask);
            //we can skip the values that we already made 0 by the above function
            col += sqrCenter;
        }
    }
}

最佳答案

maxUsedValInHistogramData函数用于通过定义阈值thrshld来缩短计算时间。然后cv::threshold用于将thrshld下的dst图像的所有像素设置为零。

根据说明,阈值由最大直方图定义。此方法非常有效,因为会跳过设置为零的大部分图像:

if (dst.at<unsigned char>(row, col) == 0)
    continue;

但是,这也意味着未检测到thrshld下的局部最大值

您可以删除以下三行,并且该功能应该可以正常运行,但速度较慢:
int thrshld = maxUsedValInHistogramData(dst, false);
threshold(dst, m0, thrshld, 1, THRESH_BINARY);
dst = dst.mul(m0);

或编写一个函数来检测输入图像的直方图最大值

关于c++ - SANITYCHECK和maxUsedValInHistogramData,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30310685/

10-12 06:43