Best way to identify a circle

So, I’ve been playing around with trackers and ways to identify circles to get a bounding box to track them. I tried houges circle detection and it failed completely to ever locate a circle. Any tips?

you can try

1 Like

simple thresholding. your sunspot has good contrast, even if it’s blurry.

or throw the SimpleBlobDetector at it.

The radial Hough transform (a variant of the symmetry transform) is also a good solution.
Get the grandient vectors of the image, then draw a line in every pixel (with gradient amplitude larger than a given threshold) along this vector in an accumulator image. The maxima of the accumulator will give the centers of the circles.

Below is the C++ code, as it’s not in OpenCV. gxMat and gyMat are the gradient images (double), minval and maxval the gradient thresholds.

``````Mat result=Mat::zeros(gx.size(), CV_16U);
int x,y,i,H,W;
double tx,ty,gx,gy,ampl,max,angl;
H=gxMat.rows;W=gxMat.cols;
for(y = 0; y < H; y++)
for (x = 0; x < W; x++)
{
gx=gxMat.at<double>(y,x);
gy=gyMat.at<double>(y,x);
ampl=abs(gx)+abs(gy);
if((ampl>minval)&&(ampl<maxval)){
max=(abs(gx)>abs(gy)?abs(gx):abs(gy));
angl=fastAtan2(gy,gx)*0.017453293;
gx/=max;
gy/=max;
tx=x-ray*cos(angl);ty=y-ray*sin(angl);
if(tx<0||tx>W-1||ty<0||ty>H-1)continue; //outside the image
while(abs(tx-x)+abs(ty-y)>5)
{
tx+=gx;
ty+=gy;
result.at<ushort>((int)ty,(int)tx)++;
}
}
}``````
2 Likes

Hmmm okay, still need to tear this code apart a bit but what is “ray” here in your code? Also, I assume when you refer to gxMat, gyMat I would need to get my image and set it to gray scale. What would those thresholds be for minval and maxval as such?

`ray` is the radius of the circle - the length of the line to be drawn.
To get the gradients, you need to convert your image to grayscale.
You can consider `minval=1` and `maxval=255`, but you can modify these values according to your image.

Perhaps this helps you - I used K-means to quant your image down to 2 values and got this: