# Finding blob centers with keypoints or centroids?

The following pseudocode code works fine in reality, but I have a question concerning the appropriateness with what I am trying to do. I detect a few simple blobs ovoid to circular in nature, in a binary image. I am trying to find the blob centers:

``````Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);
...image aquisition (ImageRaw)
...convert to binary (bin_image)
detector->detect(bin_image, binKeypoints);
drawKeypoints(bin_image, binKeypoints, binimg_with_keypoints, Scalar(0, 0, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
``````

The keypoints returned: do they contain the center coordinates of the blobs detected or should I calculate the centroid of the blob using using an algorithm, a bounding box middle or even by applying a moments function? Where do I go from here to find center coords?

the keypoint center is already derived from the contour moments:

Hi thanks for the recommended solution. Would a “geometric solution” be acceptable as well as simpler? I basically find the leftmost, rightmost, lower-most, higher-most pixel coordinates of the blob in the image plane and calculate the rectangular center from this virtual bounding box. Assuming a relatively symmetrical blob which I am using. How can I find the coordinates marked with “?”
Pseudo:

``````Main
{
…
// per found blob
double Pixel_leftmost = ?
double Pixel_rightmost = ?
double Pixel_upmost = ?
double Pixel downmost = ?

double Width_blob = Pixel_rightmost - Pixel_leftmost
double Height_blob = Pixel_downmost - Pixel_upmost // avoid neg quant

double Ctr_x = Width_blob/2
double Ctr_y = Height_blob/2
…
}

``````

this is neither a recommendation, nor a solution.
just stating, how it works “under the hood”.

there is indeed a difference between the

• “center of gravity” (as calculated from moments())
• and the “geometric center” (the center of the bounding box, what your “pseudocode” above is trying to calculate)

what exactly do you require here (and why) ?

what exactly do you require here (and why) ?

I’ll have to do some reading about center of gravity versus geometric center and repost --honestly I don’t know the diff. I do know I want to avoid contours and to work with 1-2 round binary blobs that are moving. The algorithm should be light weight and with as few OpenCV fx calls as possible. I am presently using binary keypoints[x].x etc. as center image points but this is probably not right though close.

I’ve done a lot of reading on the two approaches above. Turns out it appears that the
keypoints already contain centroid coordinates that correlate with image points :

``````bin_with_keypoints[i].pt.x;
bin_with_keypoints[i].pt.y;

// or equivalent

bin_with_keypoints[i].pt;
bin_with_keypoints[i].pt;

``````

That’s fine. But I also want to find the blob centers using “moments” to compare as well. However I’m kneecapped immediately with an exception in the the first line of Moments m.

``````...code to aquire a frame (greyscale) and convert to binary. Tested = ok.
Moments m = moments(matBinImage, true);  // exception line
``````

Code snippet:

``````Moments m = moments(matBinImage, true);  // exception line
Point p(m.m10/m.m00, m.m01/m.m00);
//centroid coordinates
cout<<Mat(p) << std::endl;

``````

the keypoint positions are already calculated using moments, no reason to do it again.

and the exception is ?

please also be aware, that you only can calculate the moments of a single contour

Unhandled exception at 0x00007FFC290BA388 in Testver7.exe: Microsoft C++ exception: cv::Exception at memory location 0x0000002EB4BFEB60

please also be aware, that you only can calculate the moments of a single contour

I plan on using a single blob. Can this be considered as a single contour?

can you show your “matBinImage” ?
(and some code around that ?)

sure.

``````cv::Mat matBinaryImg;
threshold(imageUndistorted, matBinaryImg, 60, 255, THRESH_BINARY);
imshow("Binary Image:", matBinaryImg);
Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);
// Detect blobs
detector->detect(matBinaryImg, binKeypoints);
drawKeypoints(matBinaryImg, binKeypoints, bin_with_keypoints, Scalar(0, 0, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

``````