2015-09-05 5 views
5

私は屋外シーンの動く物体を分析するために背景減算を使用しています。太陽が出てきたら私は影に問題があります。私は輪郭を使ってオブジェクトを分離しています。現時点では、影が通常は下半分にあるので、輪郭の上半分を単純に分析します。PythonのOpenCV輪郭最小次元位置

ゴムドックの輪郭を想像してみよう。私がしたいのは、アヒルの首のy位置、つまり輪郭が最小水平寸法にある位置を見つけることです。 誰かが "アヒルの首"を見つける方法の正しい方向に私を指摘してもらえますか?コードで

enter image description here

binaryは、移動物体の閾値画像であり、HIGHTWIDTHは画像の高さと幅であり、labは、LAB色空間内の同じ画像です。

half = int(h/2)行を「ダックネック」をオフにする水平線のy位置を見つける関数に置き換えたいとします。

_,contours,_ = cv2.findContours(binary.copy(), cv2.RETR_EXTERNAL, 
          cv2.CHAIN_APPROX_SIMPLE) 

# loop over the contours 
for i, cnt in enumerate(contours): 

    # compute the bounding box for the contour 
    (x, y, w, h) = cv2.boundingRect(cnt) 

    # reject contours outside size range 
    if w > 250 or w < 30 or h > 250 or h < 30 : 
      continue 

    # make sure the box is inside the frame 
    if x <= 0 or y <= 0 or x+w >= (WIDTH -1) or y+h >= (HIGHT -1): 
      continue 

    # isolate feature 
    half = int(h/2) 
    roi = lab[y:y+half, x:x+w] 
    mask = binary[y:y+half, x:x+w] 

    # calculate the mean of the colour 
    mean = cv2.mean(roi, mask = mask) 
    # note: mean is L a b 
    L = int(mean[0]) 
    a = int(mean[1]) 
    b = int(mean[2]) 
    print L,a,b 

私はOpenCVの3とPython 2.7

P.S.を使用しています私はシャドウを識別するバックグラウンド減算器MOG2を試しましたが、それは私の使用のために騒々しい方法であり、実行可能ではありません。

+3

あなたの質問に追加して、実際の結果と期待される結果を示します。タグの下にある編集リンクをクリックします。画像を追加するには十分な評判はありませんが、imgurなどから公開リンクを投稿することができます – Miki

+0

こんにちは、私はスケッチを追加しました。私は3つの解決策を考えました.1)何とかモーメントを使用する、2)輪郭リストを繰り返して転換点を見つける、3)行を横に並べてプロファイルを取得して、プロファイルの転換点を見つけます。最初の2つは、モーメントを使用する方法や、輪郭リストにアクセスして解釈する方法についての助けが大いに役立つとは考えていません。または他の提案は非常に高く評価されるだろう。 – Johno

+0

尋ねられたように苦しんでいると申し訳ありませんが、できる限りDropbox /その他の一時的なリンクは避けてください。これらの質問は何年も人々を助け、今後Dropboxファイルを削除するとこの質問はあまり価値がありません。すべての画像がその周りにあることを確認するためにimgurと手配してください。私はこの例であなたのためにそれをしました。あなたがあなたの答えを見つけることを願っています! – Basic

答えて

0

画像をぼかすためのマスクを定義することで、谷から上と下のブロブを壊すことができます。これをコードに適用すると、次のようになります。

# loop over the contours 
for i, cnt in enumerate(contours): 

    # compute the bounding box for the contour 
    (x, y, w, h) = cv2.boundingRect(cnt) 

    # reject contours outside size range 
    if w > 250 or w < 30 or h > 250 or h < 30 : 
      continue 

    # make sure the box is inside the frame 
    if x <= 0 or y <= 0 or x+w >= (WIDTH -1) or y+h >= (HIGHT -1): 
      continue 

    # --------------- 
    # create a mask for erosion, you can play with the mask size/shape 
    mask = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) 
    # erode the original image 
    eroded_img = cv2.erode(binary,mask,iterations = 1) 
    cv2.imshow("Eroded image",eroded_img) 
    # find the middle of the two new contours 
    _,new_contours,_ = cv2.findContours(eroded_img, cv2.RETR_EXTERNAL, 
         cv2.CHAIN_APPROX_SIMPLE) 
    (_, y_t, _, h_t) = cv2.boundingRect(new_contours[0]) 
    (_, y_b, _, h_b) = cv2.boundingRect(new_contours[1]) 
    bottom_top_y = max(y_t, y_b) # highest y of bottom part 
    top_bottom_y = min(y_t+h_t, y_b+h_b) # lowest y of top part 
    half = top_bottom_y + (bottom_top_y - top_bottom_y)/2 
    # ------------ 

    # isolate feature 
    roi = lab[y:y+half, x:x+w] 
    mask = binary[y:y+half, x:x+w] 

    # calculate the mean of the colour 
    mean = cv2.mean(roi, mask = mask) 
    # note: mean is L a b 
    L = int(mean[0]) 
    a = int(mean[1]) 
    b = int(mean[2]) 
    print L,a,b 

希望すると助かります!バイナリイメージの形態的操作の例については、hereを参照してください。

+0

Ike、ありがとうございました。これは間違いなくそれを行う一つの方法です。私はすでにオブジェクトの非常に端が私の認識計算に含まれないようにマスクサイズを減らすためにerodeを使用します。たぶん、輪郭が2つになるまでループ状に腐食し、上部の輪郭を元のサイズに戻します。乾杯:-) – Johno