You can easily detect the outer circle using Hough transform, from there you will get the centre.
- Find the THRESH_BINARY_INV of the src image('thr') with a threshold say 100.
- Create Mat of same size and and set all element to zero say 'add'.
- In a loop start drawing circle on 'add' from centre towards outer with a value say 255.
- On each step add=add+thr
5 Scan through each pixel of 'add' and check whether it's value is 255(means it touches whiter boarder)
6.If 255 exit loop and that will be the intermediate circle.
7.Else increase radius until you met the condition.
For intermediate circle
Same step as above but instead of adding image minus it.
radius=radius found out using hough transform- a constant
1. add=add-thr;
2. check if pixel value of add=155 if yes exit
3. else radius--
I am not sure does it work or not for other images but it is working fine for the image you provided with your question. Below is the code I just made to test the above algorithm.
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
/** @function main */
int main(int argc, char** argv)
{
Mat src, src_gray,thr,edge,add;
/// Read the image
src = imread( argv[1], 1 );
int t1=75;
int t2=100;
if( !src.data )
{ return -1; }
/// Convert it to gray
cvtColor( src, src_gray, CV_BGR2GRAY );
/// Reduce the noise so we avoid false circle detection
GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );
threshold( src_gray, thr, t1, t2, THRESH_BINARY_INV );
threshold( src_gray, add, 0, 0, THRESH_BINARY_INV ); //Instaed of this step you can create an image of the same size and set all element to zero
imshow( "thr", thr );
Point cent; // centre for inner circle
int rad=55; //radius for inner circle
int radius; // centre for Hough circle
vector<Vec3f> circles;
/// Apply the Hough Transform to find the circles
HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows/8, t1, t2, 0, 0 );
/// Draw the circles detected
for( size_t i = 0; i < circles.size(); i++ )
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
radius = cvRound(circles[i][2]);
cent.x=center.x;
cent.y=center.y;
// circle center
circle( src, center, 3, Scalar(0,255,0), 5, 8, 0 );
// circle outline
circle( src, center, radius, Scalar(0,255,0), 1, 8, 0 );
}
/************ This block will findout the inner circle******************/
int flag=0;
while(flag==0){
threshold( src_gray, add, 0, 0, THRESH_BINARY_INV ); // instead of this can you can set all elemet to zero
circle( add, cent, rad, Scalar(155), 1, 8, 0 );
add=thr+add;
imshow( "add", add );
waitKey(33);
rad++;
//Scan whole mat and check whether the circle hit the white pixel
for(int i = 0; i < add.rows; i++)
{
for(int j = 0; j < add.cols; j++)
{
Vec3b bgrPixel = add.at<Vec3b>(i, j);
int p=bgrPixel.val[0];
if(p==255){ //Check whether the radius reaches white region from centre.
flag=1 ...
(more)