2016-04-16 75 views
1

輪郭内でピクセル値を取得しようとしています。私は似たような質問への答えに沿って続けたが、私の結果はオフである。CV2輪郭内のピクセル値を取得する

このコードブロックは、画像の輪郭線を見つけ、その輪郭線を反復して最大の領域を含む輪郭線を見つけます。私は昼間の場合にコードのRGB値を取得しようとする終了if文を追加しました。元の画像(ビデオフレーム)をI輪郭とともに、(grab_rgb)を書いた関数に渡され

thresh = cv2.dilate(thresh, None, iterations=2) 
    (_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 

    # look for motion 
    motion_found = False 
    biggest_area = 0 

    # examine the contours, looking for the largest one 
    for c in cnts: 
     (x, y, w, h) = cv2.boundingRect(c) 
     # get an approximate area of the contour 
     found_area = w * h 
     # find the largest bounding rectangle 
     if (found_area > MIN_AREA) and (found_area > biggest_area): 
      biggest_area = found_area 
      motion_found = True 

      if not is_nighttime(): 
       rgb = grab_rgb(image, c) 
      else: 
       rgb = 'nighttime' 

これは私が書いた関数である:

def grab_rgb(image, c): 
    pixels = [] 

    # TODO: Convert to real code 
    # Detect pixel values (RGB) 
    mask = np.zeros_like(image) 
    cv2.drawContours(mask, c, -1, color=255, thickness=-1) 

    points = np.where(mask == 255) 

    for point in points: 
     pixel = (image[point[1], point[0]]) 
     pixel = pixel.tolist() 
     pixels.append(pixel) 

    pixels = [tuple(l) for l in pixels] 
    car_color = (pixels[1]) 

    r = car_color[0] 
    g = car_color[1] 
    b = car_color[2] 

    pixel_string = '{0},{1},{2}'.format(r, g, b) 

    return pixel_string 

コードが実行さ、のみ返します3つのRGB値があり、2番目の値だけが意味のあるものを含みます(値0と2は[0,0,0]、[0,0,0]です)。輪郭内に3つ以上のピクセルがあるはずです。

編集:私はそれが役に立つかもしれないことに気付いた実際に変数に格納されているものを含めます。

マスク:

[[[ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0] 
    ..., 
    [ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0]] 

[[ 0 0 0] 
    [255 0 0] 
    [ 0 0 0] 
    ..., 
    [ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0]] 

[[ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0] 
    ..., 
    [ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0]] 

..., 
[[ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0] 
    ..., 
    [ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0]] 

[[ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0] 
    ..., 
    [ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0]] 

[[ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0] 
    ..., 
    [ 0 0 0] 
    [ 0 0 0] 
    [ 0 0 0]]] 

点:

(array([ 1, 1, 3, 5, 10, 11, 11, 12, 12, 13, 13, 14, 14], dtype=int32), array([ 1, 22, 22, 24, 24, 21, 23, 16, 20, 9, 15, 1, 8], dtype=int32), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)) 

ピクセル:

[0, 0, 0] [136, 89, 96] [0, 0, 0] 

ピクセル:

[(0, 0, 0), (136, 89, 96), (0, 0, 0)] 

car_colorは:

(136, 89, 96) 

答えて

2

それはあなたが渡されたすべての輪郭上の点の画素値のリストでちょうど第二の点のRGB値がされる(ここではいわゆる「ピクセル」)を返すようにコードを求めてきたもののように思えます

car_color =(画素[1])

r = car_color[0] 

g = car_color[1] 

b = car_color[2] 

と、grab_rgbすることがだから出力イメージを満たす少なくとも3検出された輪郭を有していることを意味すべきです輪郭のポイントリストの2番目のポイントのRGB値は、あなたが言及したもの([0,0,0]、[x、y、z]および[0,0,0])であることを示しています。

+0

元の投稿にさらに情報を追加しましたが、何らかの理由でnp.whereが3点しか返していません。私はそれを提供しているマスクに何か問題があると仮定しています。興味深いことに、最初と最後のピクセル値は0,0,0です。 私はピクセルから2番目のピクセル値を取り出しました。これは値が変更された唯一のものであったため、それが何とか私が望んでいたかどうかを確認しようとしていたからです。だから、なぜnp.whereが3つのポイントしか返さないのか分かりません。 –

+0

違いがあるとは思わないが、今はあなたのマスクが(幅×高さ×1)必要なときに(幅×高さ×1)の形状になっている。 zeros_likeを使わないでください。あなたのマスクに3つのチャンネルがあり、3つのチャンネルを必要としないあなたの '画像'の形を与えるからです。代わりに、ゼロを使用して0のマスクを初期化します(画像の幅と高さを指定します)。あなた自身。 また、あなたのポイント配列は11-12ポイントを持つように見えるので、どのようなnp.whereが返されたのでしょうか。 – gunshi

+0

マスクを修正し、このリンクをチェックして、np.whereの出力を反復処理する方法を確認してください。 http://stackoverflow.com/questions/21887138/iterate-over-the-output-of-np-where – gunshi