とりあえず,質問に提示された画像から,その〇の位置を探すとしたら,
下記に示すような,あきれるほど単純な処理でも十分であろうと思います.
(下記コードはOpenCVを使用しており,C#でOpenCVを使ったことが無いのでC++で書いていますが)
C++
1int main()
2{
3 //(ここは画像の読み込み処理です)
4 cv::Mat Img = cv::imread( "Check.png", cv::IMREAD_GRAYSCALE );
5 if( Img.empty() )return 0;
6
7 //円の半径[pixel](太いので2種類)
8 const int r1 = 30;
9 const int r2 = 33;
10 //↑の2乗値
11 const int Sq_r1 = r1*r1;
12 const int Sq_r2 = r2*r2;
13
14 //画像内を走査し,
15 //各着目画素位置(cx,cy)において,(cx,cy)からの距離が r1~r2 である画素の色を調べて,
16 //黒い画素の個数をカウントする.
17 //最もカウント数が多い箇所を〇の中心だと判定する.
18 int BestCx = -1;
19 int BestCy = -1;
20 int BestScore = 0;
21
22 for( int cy=r2; cy+r2<Img.rows; ++cy )
23 {
24 for( int cx=r2; cx+r2<Img.cols; ++cx )
25 {
26 int score = 0; //黒い画素個数カウンタ
27 for( int dy=-r2; dy<=r2; ++dy )
28 {
29 const int Sq_dy = dy*dy;
30 const int y = cy + dy;
31 const unsigned char *pI = Img.ptr<unsigned char>( y );
32 for( int dx=-r2; dx<=r2; ++dx )
33 {
34 const int Sq_dx = dx*dx;
35 const int Sq_r = Sq_dx + Sq_dy;
36 if( Sq_r < Sq_r1 || Sq_r2 < Sq_r )continue;
37
38 if( pI[ cx+dx ]<128 ){ ++score; } //画素(x,y)が黒いかどうか
39 }
40 }
41
42 if( score > BestScore )
43 {
44 BestScore = score;
45 BestCx = cx;
46 BestCy = cy;
47 }
48 }
49 }
50
51 {//結果表示:赤〇を描画して示す
52 cv::Mat ShowImg( Img.size(), CV_8UC3 );
53 cv::cvtColor( Img, ShowImg, CV_GRAY2BGR );
54
55 cv::circle( ShowImg, cv::Point(BestCx,BestCy), (r1+r2)/2, cv::Scalar(0,0,255), 2 );
56 cv::imshow( "Result", ShowImg );
57 if( cv::waitKey() == 's' )
58 { cv::imwrite( "Result.png", ShowImg ); }
59 }
60
61 return 0;
62}
結果: