

[![判定前の画像](https://i.stack.imgur.com/o0MCO.jpg)](https://i.stack.imgur.com/o0MCO.jpg)  
[![判定後の画像](https://i.stack.imgur.com/pJP63.jpg)](https://i.stack.imgur.com/pJP63.jpg)  
お世話になります。画像から赤、緑の色を抽出して色の点群を矩形で囲みたいのですが、HSVのどのパターンを試してもうまくいきません。今は青はうまくいっていますが一部ずれていたり、関係のないところにもかかっています。プログラムのような色の探し方が悪いのか、別な範囲を変えたらいいのかよくわからないでいます。どなたか解決法を教えてください。よろしくお願いいたします。

[code]

    col_img=cv2.imread("/home/pi/seisaku/2.jpg",cv2.IMREAD_COLOR)   
    col_img=cv2.resize(col_img,None,fx=3,fy=3)
    img=cv2.cvtColor(col_img,cv2.cv.CV_BGR2HSV)
    
    h=copy.copy(img[:,:,0])
    s=copy.copy(img[:,:,1])
    v=copy.copy(img[:,:,2])
    
    Blue=np.zeros(col_img.shape,dtype=np.uint8)
    Red=np.zeros(col_img.shape,dtype=np.uint8)
    Green=np.zeros(col_img.shape,dtype=np.uint8)
    Blue[((h > 200) | (h < 260)) & (s > 100)]=255
    Red[((h < 30) | (h > 280)) & (s > 128)]=255
    Green[((h > 80) | (h < 230)) & (s > 170)]=255
    
    for col in [Red,Blue,Green]:
        gray = cv2.cvtColor(col, cv2.COLOR_BGR2GRAY)
        retval, bw = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
        cv2.imwrite("bw.jpg",bw)
    
        contours,_= cv2.findContours(bw, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
    
        ##各輪郭に対する処理
        for i in range(0, len(contours)):
    
            # 輪郭の領域を計算
            area = cv2.contourArea(contours[i])
    
            # 外接矩形
            if( len(contours[i]) > 0 )&(100<area<400):
                rect = contours[i]
                x, y, w, h = cv2.boundingRect(rect)
                if abs(w-h)<5:
                    cv2.rectangle(col_img, (x, y), (x + w, y + h), (255,0 ,0), 2)
                #print(int(x+w/2),int(y+h/2))
    
                cv2.imwrite("aux.jpg",col_img)
                #cv2.waitKey(0)
    
[/code]


CC BY-SA 3.0
2017-09-16T05:49:44.947
37984
2017-10-26T01:47:19.273
2017-09-16T08:20:14.167
3060
19263
question
python opencv raspberry-pi
画像から特定の色を抽出したい


>
[code]

>     Blue[((h > 200) | (h < 260)) & (s > 100)]=255
>     Red[((h < 30) | (h > 280)) & (s > 128)]=255
>     Green[((h > 80) | (h < 230)) & (s > 170)]=255
>  
[/code]

色相(`h`)を角度[0,360)で判定したいという意図でしょうか？OpenCVによるHSV変換後の値域は0〜179となるため、この判定式はあなたの想定通りに機能しません。

* * *

質問ソースコードをベースに、マーカー判定基準を改良してみました。Python 3＋OpenCV 3前提としています。

[code]

    #!/usr/bin/env python3
    import cv2
    import numpy as np
    import math
    
    col_img = cv2.imread("q37984.jpg", cv2.IMREAD_COLOR)
    col_img = cv2.resize(col_img, None, fx=3, fy=3)
    
    # HSVチャネル別に分解
    img = cv2.cvtColor(col_img, cv2.COLOR_BGR2HSV)
    h = img[:, :, 0]
    s = img[:, :, 1]
    v = img[:, :, 2]
    
    shape = (img.shape[0], img.shape[1], 1)
    Red = np.zeros(shape, dtype=np.uint8)
    Green = np.zeros(shape, dtype=np.uint8)
    Blue = np.zeros(shape, dtype=np.uint8)
    # 色相(Hue)による色成分検出; +彩度(S)と明度(V)の閾値判定
    HF = 0.5
    Red[((h < 0*HF) | (h > 300*HF)) & (s > 16) & (v > 128)] = 255     # 330±30°
    Green[((h > 30*HF) & (h < 90*HF)) & (s > 16) & (v > 128)] = 255   # 60±30°
    Blue[((h > 180*HF) & (h < 240*HF)) & (s > 16) & (v > 128)] = 255  # 210±30°
    
    # 縮小処理によるノイズ除去(5x5円形カーネル)
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
    Red = cv2.morphologyEx(Red, cv2.MORPH_OPEN, kernel)
    Green = cv2.morphologyEx(Green, cv2.MORPH_OPEN, kernel)
    Blue = cv2.morphologyEx(Blue, cv2.MORPH_OPEN, kernel)
    
    ROUND_TH = 0.4  # 円判定閾値
    
    for target in [Red,Green,Blue]:
        _, contours, _ = cv2.findContours(target, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
        for cnt in contours:
            # 検出輪郭の外接円面積area1を計算
            (cx, cy), radius = cv2.minEnclosingCircle(cnt)
            area1 = (radius * radius) * math.pi
            # 検出輪郭の実面積area0を計算
            area0 = cv2.contourArea(cnt)
            # 面積比率から輪郭の"円形度"を推定
            if (1 - ROUND_TH) < area1 / area0 < (1 + ROUND_TH):
                cv2.circle(col_img, (int(cx), int(cy)), int(radius), (0,0,0), 2)
    
    cv2.imwrite("result.jpg", col_img)
    
[/code]

結果：  
[![検出結果](https://i.stack.imgur.com/20BEW.jpg)](https://i.stack.imgur.com/20BEW.jpg)


CC BY-SA 3.0
2017-09-16T18:51:59.643
37996
2017-09-23T02:18:17.477
2017-09-23T02:18:17.477
49
49
37984
answer