Find centroid points on circle

Hi,

I am trying to find centroid points on circles/blobs using OpenCV.JS on the Observablehq. Here is my notebook https://observablehq.com/d/efc0f36193ef7067

My goal is to display centroid points on each circle/blob and save the coordinated points as a CSV file.

I found a few references, but I am unable to implement them in the Observablehq. Your help will be highly appreciable.

References:

  1. how to find the centre of multiple objects in a image - OpenCV Q&A Forum

I cannot open the notebook link. Is your notebook still private?

@mootari Now you should be able to open the link. I published it now.

Note that you can also publish a notebook as “unlisted”. That way it will be accessible to anyone who has the link, but won’t be listed publicly on your profile or in the global list of recently published notebooks.
Very handy if you’re still working on a notebook but want to show it someone else. :slight_smile:

And instead of forking the OpenCV notebook, I recommend just importing cv into your own notebook:

import {cv} from "@mootari/opencv-js"

You can read more about imports here:

1 Like

Would the Watershed method work for you, as described in this OpenCV.js tutorial?
https://docs.opencv.org/4.5.4/d7/d1c/tutorial_js_watershed.html

Also, are you required to use OpenCV? As far as I’m aware there should be more specialized JS libraries out there, that are likely easier to use.

@mootari I need to find centroid coordinate points for all the circles. I think the Watershed link you shared is not computing centroid coordinate points. I’m much familiar with Python OpenCV. So, I decided to use OpenCV.JS. It will be fine for me if you want to use any other libraries.

@joyaircel2016 I’ve added an example for centroids here:

2 Likes

@mootari It worked! You’re awesome! Thank you so so much!

1 Like

@mootari Could you please tell me how can I define center as a global variable? Also is it possible to get X and Y coordinates separately? Something like below
const {centerX, CenterY} = new cv.Point(m10 / m00, m01 / m00);

These kinds of questions are best answered by the OpenCV API docs. E.g., if you look at the reference for cv::Point, you’ll see x and y listed under public attributes.

Be sure to name your cell, then collect the x/y values into an array that you return:

centers = {
  // ... Skipping over getting the image data and contours. ...

  const coordinates = [];
  for(let i = 0; i < contours.size(); i++) {
    const {m00, m01, m10} = cv.moments(contours.get(i));
    if(m00 === 0) continue;
    const {x, y} = new cv.Point(m10 / m00, m01 / m00);
    coordinates.push({x, y});
    // Or, if you prefer an array of arrays:
    //coordinates.push([x, y]);
  };

  // ... remember to call .delete() on any cv objects before returning, to avoid memory leaks. ...
  
  return coordinates;
}
2 Likes

Thanks! Issue solved.