# Finding blob centers with keypoints or centroids?

**URL:** <https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757>\
**Category:** C++\
**Created:** [August 13, 2021, 11:52pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757 "2021-08-13T23:52:25Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![rg0001](https://avatars.discourse-cdn.com/v4/letter/r/9dc877/32.png) [@rg0001](https://forum.opencv.org/u/rg0001)\
**Post date:** [August 13, 2021, 11:52pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/1 "2021-08-13T23:52:26Z")

</div>

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:

```auto
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?

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [August 14, 2021, 2:27pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/2 "2021-08-14T14:27:52Z")

</div>

the keypoint center is already derived from the contour moments:

> <https://github.com/opencv/opencv/blob/917cd13ce24cd89770b78769d7bc9729277ff4c8/modules/features2d/src/blobdetector.cpp#L271>

---

<div class="post-metadata">

**Author:** ![rg0001](https://avatars.discourse-cdn.com/v4/letter/r/9dc877/32.png) [@rg0001](https://forum.opencv.org/u/rg0001)\
**Post date:** [August 14, 2021, 5:22pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/3 "2021-08-14T17:22:05Z")

</div>

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:

```auto
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
…
}

```

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [August 14, 2021, 6:05pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/4 "2021-08-14T18:05:55Z")

</div>

> [@rg0001](#):
>
> thanks for the recommended solution

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

---

<div class="post-metadata">

**Author:** ![rg0001](https://avatars.discourse-cdn.com/v4/letter/r/9dc877/32.png) [@rg0001](https://forum.opencv.org/u/rg0001)\
**Post date:** [August 14, 2021, 7:13pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/5 "2021-08-14T19:13:40Z")

</div>

> 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 etc. as center image points but this is probably not right though close.

---

<div class="post-metadata">

**Author:** ![rg0001](https://avatars.discourse-cdn.com/v4/letter/r/9dc877/32.png) [@rg0001](https://forum.opencv.org/u/rg0001)\
**Post date:** [August 16, 2021, 4:14pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/6 "2021-08-16T16:14:49Z")

</div>

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 :

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

// or equivalent

bin_with_keypoints[i].pt[0];
bin_with_keypoints[i].pt[1];

```

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.

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

```

Code snippet:

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

```

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [August 16, 2021, 4:19pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/7 "2021-08-16T16:19:15Z")

</div>

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

> [@rg0001](#):
>
> ` // exception line`

and the exception is ?

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

---

<div class="post-metadata">

**Author:** ![rg0001](https://avatars.discourse-cdn.com/v4/letter/r/9dc877/32.png) [@rg0001](https://forum.opencv.org/u/rg0001)\
**Post date:** [August 16, 2021, 4:42pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/8 "2021-08-16T16:42:32Z")

</div>

> 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?

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [August 16, 2021, 4:47pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/9 "2021-08-16T16:47:07Z")

</div>

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

> [@rg0001](#):
>
> I plan on using a single blob. Can this be considered as a single contour?

sure.

---

<div class="post-metadata">

**Author:** ![rg0001](https://avatars.discourse-cdn.com/v4/letter/r/9dc877/32.png) [@rg0001](https://forum.opencv.org/u/rg0001)\
**Post date:** [August 16, 2021, 5:08pm UTC](https://forum.opencv.org/t/finding-blob-centers-with-keypoints-or-centroids/4757/10 "2021-08-16T17:08:28Z")

</div>

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

```

 ![opencv_forum_pic](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/0/04e067bd1a9804f99197bb3989ad9781a45f5e7f.jpeg)
