SANITYCHECK and maxUsedValInHistogramData



我试图用openCV在c++中重新实现matlab imregionalmax(),我在网站上进行了搜索,并在这里找到了一些有趣的答案使用openCV在灰度图像中找到局部最大值,到目前为止最好的一个属于Doga Siyli,但有2个"奇怪"的函数。一个是:SANITYCHECK(squareSize,3,1),另一个是:maxUsedValInHistogramData(dst,false);。(这里的"奇怪"是指我不认为这两个是OpenCV的功能)

我的问题是:

我用assert(squareSize >= 3);代替了SANITYCHECK(squaresize,3,1),用minmaxLoc代替了maxUsedValInHistogramData(dst,false);,但程序没有工作,特别是第二个,因为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::thresholdthrshld下的dst图像的所有像素设置为零。

根据解释,阈值由直方图max定义。这种方法是有效的,因为图像的很大一部分(设置为零)会被跳过:

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);

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

相关内容

  • 没有找到相关文章

最新更新