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
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)++;
}
}
}
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: