I am trying to detect circles in my images. I have written the following code in C# using EmguCV. Most of the times it works, but there are some cases that it detects smaller or larger circles that are slightly shifted to a side.
Here is my code:
Thread.Sleep(1000);
imgCrp.Save(DateTime.Now.ToString("yyMMddHHmmss") + ".jpg");
imgCrpLab = imgCrp.Convert<Lab, Byte>();
imgIsolatedCathNTipBW = new Image<Gray, Byte>(imgCrp.Size);
CvInvoke.cvInRangeS(imgCrpLab.Split()[2], new MCvScalar(0), new MCvScalar(100), imgIsolatedCathNTipBW);
imgCrpNoBgrnd = imgCrp.Copy(imgIsolatedCathNTipBW.Not());
imgCrpNoBgrndGray = imgCrpNoBgrnd.Convert<Gray, Byte>().PyrUp().PyrDown();
Thread.Sleep(1000);
imgCrpNoBgrndGray.Save(DateTime.Now.ToString("yyMMddHHmmss") + ".jpg");
Gray cannyThreshold = new Gray(150);
Gray cannyThresholdLinking = new Gray(85);
Gray circleAccumulatorThreshold = new Gray(15);
imgCrpNoBgrndGrayCanny = imgCrpNoBgrndGray.Canny(cannyThreshold.Intensity, cannyThresholdLinking.Intensity);
Thread.Sleep(1000);
imgCrpNoBgrndGrayCanny.Save(DateTime.Now.ToString("yyMMddHHmmss") + ".jpg");
circarrTip = imgCrpNoBgrndGrayCanny.HoughCircles(
cannyThreshold,
circleAccumulatorThreshold,
1, //Resolution of the accumulator used to detect centers of the circles
500, //min distance
15, //min radius
42 //max radius
)[0]; //Get the circles from the first channel
imgCathNoTip = imgIsolatedCathNTipBW.Copy().Not();
foreach (CircleF circle in circarrTip)
{
circLarger2RemTip = circle;
circLarger2RemTip.Radius = circle.Radius;
imgCathNoTip.Draw(circLarger2RemTip, new Gray(140), 1); // -1 IS TO FILL THE CIRCLE
}
Thread.Sleep(1000);
imgCathNoTip.Save(DateTime.Now.ToString("yyMMddHHmmss") + ".jpg");
Sleep commands are just to make sure that the filenames will be different and will be removed later. I have also attached the images that have been save by this code during the process. The last image shows the detected circle which is larger and also shifted to the right.
Can anyone kindly check my code and let me know how I can improve it to detect circles more accurately?
Thanks in advance.
analogue to my answers in Detect semi-circle in opencv I see a problem: Don't extract canny edge detection before hough circle detection, since openCV houghCircle itself computes Gradient AND canny. So what you are trying to do is to extract canny from and edge image and detect circles in that, leading to (in the best case) 2 new edges around each edge => wrong way!
As it is done in the openCV tutorial, you can compute HoughCircles directly on your grayscale image, giving this result for me:
input:
parameters:
code:
result:
using my RANSAC method I posted in Detect semi-circle in opencv (my 2nd answer but slightly changed to search the most complete circle) (input: canny edges)
code:
I achieved this result instead:
Have no C# code, sorry.