我正在尝试使用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/