2012-08-02 14 views
7

OpenCVでPythonでhereというアルゴリズムを実装しようとしています。私はOpenCVの初心者ですので、私と一緒にいらしてください。Python OpenCV Contourツリー階層

私は、無関係のエッジ境界を削除するアルゴリズムの一部を、内部の境界の数に基づいて実装しようとしています。

  • 現在のエッジ境界が二つ以上の内縁の境界を持っている場合は、現在のエッジ境界が正確に1または2つの内部のエッジの境界、内部境界が
  • を無視することができたならば、それは
を無視することができます

イメージから抽出した輪郭のツリー構造を決定する際に問題があります。

私の現在の源:

import cv2 

# Load the image 
img = cv2.imread('test.png') 
cv2.copyMakeBorder(img, 50,50,50,50,cv2.BORDER_CONSTANT, img, (255,255,255)) 

# Split out each channel 
blue = cv2.split(img)[0] 
green = cv2.split(img)[1] 
red = cv2.split(img)[2] 

# Run canny edge detection on each channel 
blue_edges = cv2.Canny(blue, 1, 255) 
green_edges = cv2.Canny(green, 1, 255) 
red_edges = cv2.Canny(red, 1, 255) 

# Join edges back into image 
edges = blue_edges | green_edges | red_edges 

# Find the contours 
contours,hierarchy = cv2.findContours(edges.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 

# For each contour, find the bounding rectangle and draw it 
for cnt in contours: 
    x,y,w,h = cv2.boundingRect(cnt) 
    cv2.rectangle(edges,(x,y),(x+w,y+h),(200,200,200),2) 

# Finally show the image 
cv2.imshow('img',edges) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

私はRETR_TREEを使用すると、私の輪郭の素敵なネストされた配列を与えるだろうが、それはケースのように思われないと仮定しました。輪郭のツリー構造を取得するにはどうすればよいですか?

+1

あなたはこの記事の階層についての詳細を見つけることができます。http://opencvpython.blogspot.com/2013/01/contours-5-hierarchy.html答えを –

答えて

9

ここでの主な混乱は、おそらく、返される階層が必要以上の次元を持つ数値的な配列であるということです。その上に、PythonのFindContours関数が輪郭のリストであるタプルと階層のNDARRAYを返すように見えます...

もっと階層的な情報が得られますC docsは階層[0]を取るだけです。それは、例えば、輪郭で圧縮するのに適した形状になります。以下

は、この画像に赤色、緑色で最も外側の長方形と最も内側の四角形を描画する例である。

enter image description here

出力:

enter image description here

注、によってところで、OpenCVの文書の言葉は少しあいまいですが、hierarchyDataOfAContour[2]はその輪郭の子を記述します(負であればそれは内側の輪郭です)。そしてhierarchyDataOfAContour[3]はその輪郭の親を記述する(負の場合はそれが外部輪郭である)。

また、OCRの論文で言及したアルゴリズムを実装してみましたが、FindContoursがほぼ同じ輪郭の繰り返しをたくさん提供していました。これは、論文が述べるように、「エッジボックス」の発見を複雑にする。これは、Cannyの閾値が低すぎるためです(私が論文で説明されているように遊んでいたことに注意してください)。しかし、その影響を減らす方法や、すべてのボックスや重複を排除...

import cv2 
import numpy 

# Load the image 
img = cv2.imread("/ContourTest.PNG") 

# Split out each channel 
blue, green, red = cv2.split(img) 

def medianCanny(img, thresh1, thresh2): 
    median = numpy.median(img) 
    img = cv2.Canny(img, int(thresh1 * median), int(thresh2 * median)) 
    return img 

# Run canny edge detection on each channel 
blue_edges = medianCanny(blue, 0.2, 0.3) 
green_edges = medianCanny(green, 0.2, 0.3) 
red_edges = medianCanny(red, 0.2, 0.3) 

# Join edges back into image 
edges = blue_edges | green_edges | red_edges 

# Find the contours 
contours,hierarchy = cv2.findContours(edges, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 

hierarchy = hierarchy[0] # get the actual inner list of hierarchy descriptions 

# For each contour, find the bounding rectangle and draw it 
for component in zip(contours, hierarchy): 
    currentContour = component[0] 
    currentHierarchy = component[1] 
    x,y,w,h = cv2.boundingRect(currentContour) 
    if currentHierarchy[2] < 0: 
     # these are the innermost child components 
     cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),3) 
    elif currentHierarchy[3] < 0: 
     # these are the outermost parent components 
     cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),3) 

# Finally show the image 
cv2.imshow('img',img) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 
+0

感謝。私は重複輪郭を得るのと同じ問題に遭遇した。私はOpenCVグループに投稿しましたが、何も聞いていません:http://tech.groups.yahoo.com/group/OpenCV/message/88940 – jasonlfunk

+0

私はどのように知っていただけでなくアルゴリズムを実装しました。それはかなりうまくいっているようだ。 https:// githubで確認してください。com/jasonlfunk/ocr-text-extracted – jasonlfunk

+0

よく見えます。あなたがチェックアウトしたいかもしれないもう一つの事は、「ストローク幅の変換」です。 Googleはそれを...最初のヒット(Epshteinによる論文)のリンクはすぐに "クイックビュー"でそれを見ることができますが壊れている – bellkev