# Best way to identify a circle

**URL:** <https://forum.opencv.org/t/best-way-to-identify-a-circle/6480>\
**Category:** C++\
**Tags:** imgproc\
**Created:** [November 29, 2021, 10:42pm UTC](https://forum.opencv.org/t/best-way-to-identify-a-circle/6480 "2021-11-29T22:42:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![MechFall](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/mechfall/32/3810_2.png) [@MechFall](https://forum.opencv.org/u/MechFall)\
**Post date:** [November 29, 2021, 10:42pm UTC](https://forum.opencv.org/t/best-way-to-identify-a-circle/6480/1 "2021-11-29T22:42:58Z")

</div>

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?

 ![Screenshot_20211129-144222_Gallery](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/9/9357d90f713fd0286230539449c36609751fa764.jpeg)

---

<div class="post-metadata">

**Author:** ![sturkmen](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/sturkmen/32/13_2.png) [@sturkmen](https://forum.opencv.org/u/sturkmen)\
**Post date:** [November 30, 2021, 1:49am UTC](https://forum.opencv.org/t/best-way-to-identify-a-circle/6480/2 "2021-11-30T01:49:57Z")

</div>

you can try

> <https://github.com/opencv/opencv_contrib/blob/4.x/modules/ximgproc/samples/edge_drawing.py>

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [November 30, 2021, 7:43am UTC](https://forum.opencv.org/t/best-way-to-identify-a-circle/6480/3 "2021-11-30T07:43:28Z")

</div>

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

or throw the SimpleBlobDetector at it.

---

<div class="post-metadata">

**Author:** ![kbarni](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/kbarni/32/26_2.png) [@kbarni](https://forum.opencv.org/u/kbarni)\
**Post date:** [November 30, 2021, 8:19am UTC](https://forum.opencv.org/t/best-way-to-identify-a-circle/6480/4 "2021-11-30T08:19:32Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![MechFall](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/mechfall/32/3810_2.png) [@MechFall](https://forum.opencv.org/u/MechFall)\
**Post date:** [November 30, 2021, 6:42pm UTC](https://forum.opencv.org/t/best-way-to-identify-a-circle/6480/5 "2021-11-30T18:42:50Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![kbarni](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/kbarni/32/26_2.png) [@kbarni](https://forum.opencv.org/u/kbarni)\
**Post date:** [December 1, 2021, 7:55am UTC](https://forum.opencv.org/t/best-way-to-identify-a-circle/6480/6 "2021-12-01T07:55:23Z")

</div>

`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.

---

<div class="post-metadata">

**Author:** ![seabirdman](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/seabirdman/32/3934_2.png) [@seabirdman](https://forum.opencv.org/u/seabirdman)\
**Post date:** [December 4, 2021, 5:52pm UTC](https://forum.opencv.org/t/best-way-to-identify-a-circle/6480/7 "2021-12-04T17:52:05Z")

</div>

Perhaps this helps you - I used K-means to quant your image down to 2 values and got this:  
 ![image](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/b/b9542e348a55a107d049e7f8b25e41dfaee4d1fa.png)
