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:
image