参考までに teratail でよく見る処理を提示画像に対してやってみた結果を示しておく.
(Python使えない人なのでC++ですが)
C++
1 int main ( )
2 {
3 //Load Image
4 cv :: Mat Src = cv :: imread ( "RedTgts.jpg" ) ;
5 if ( Src . empty ( ) ) return 0 ;
6 cv :: imshow ( "Src" , Src ) ;
7
8 //てきとーにinRangeで「赤い部分Mask」をつくる
9 cv :: Mat Mask ;
10 {
11 cv :: Mat HSV ;
12 cv :: cvtColor ( Src , HSV , cv :: COLOR_BGR2HSV ) ;
13
14 const unsigned char S_min = 128 ;
15 const unsigned char V_min = 64 ;
16 cv :: inRange ( HSV , cv :: Scalar ( 345 / 2 , S_min , V_min ) , cv :: Scalar ( 360 / 2 , 255 , 255 ) , Mask ) ;
17 cv :: Mat Mask2 ;
18 cv :: inRange ( HSV , cv :: Scalar ( 0 , S_min , V_min ) , cv :: Scalar ( 15 / 2 , 255 , 255 ) , Mask2 ) ;
19 cv :: bitwise_or ( Mask , Mask2 , Mask ) ;
20
21 cv :: imshow ( "Mask" , Mask ) ;
22 }
23 { //モルフォロジでゴミの除去
24 cv :: erode ( Mask , Mask , cv :: Mat ( ) ) ;
25 cv :: dilate ( Mask , Mask , cv :: Mat ( ) , cv :: Point ( - 1 , - 1 ) , 2 ) ;
26 cv :: erode ( Mask , Mask , cv :: Mat ( ) ) ;
27 cv :: imshow ( "Morph" , Mask ) ;
28 }
29 { //findContours
30 std :: vector < std :: vector < cv :: Point > > Conts ;
31 cv :: findContours ( Mask , Conts , cv :: RETR_EXTERNAL , cv :: CHAIN_APPROX_NONE ) ;
32
33 //ある程度の面積を持つcontourの個数を数える
34 Src *= 0.4 ; //※ここでは検出結果をSrcに描画することにする
35 int N = 0 ; //個数カウンタ
36 const double AreaThresh = 100 ; //面積閾値
37 for ( int i = 0 ; i < Conts . size ( ) ; ++ i )
38 {
39 if ( cv :: contourArea ( Conts [ i ] ) >= AreaThresh )
40 {
41 ++ N ;
42 cv :: drawContours ( Src , Conts , i , cv :: Scalar ( 0 , 0 , 255 ) , 2 ) ; //見つけたものを描画してみる
43 }
44 }
45 std :: cout << N << " Red Targets Found." << std :: endl ;
46 cv :: imshow ( "Result" , Src ) ;
47 }
48
49 //
50 if ( cv :: waitKey ( ) == 's' ) cv :: imwrite ( "Result.png" , Src ) ;
51 return 0 ;
52 }
各種閾値等をこの画像に特化して調整して良いならば,こんな感じの結果が作れるね(検出個数=6).