I'm trying to reimplement matlab imregionalmax()
in C++ with openCV, i did search on the site and found some interesting answers here Find local maxima in grayscale image using OpenCV and the best one so far belongs to Doga Siyli, but there are 2 "weird" functions. The first one is: SANITYCHECK(squareSize,3,1)
and the other one is : maxUsedValInHistogramData(dst,false);
.
(by "weird" i mean i don't think these two are OpenCV's function.)
My question is:
I replaced the SANITYCHECK(squaresize,3,1)
with assert(squareSize >= 3);
and maxUsedValInHistogramData(dst,false);
with minmaxLoc
but the program didn't work ,especially the second one because minmaxLoc
return global value while Doga's intention is to find the local values.
So how do i make the code work ?
I am new to C++ and OpenCV,and i'm still learning,any help willl be greatly appreciated.
Here is his code for a closer look( he did explain it quite clear)
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;
}
}
}