2

以下に示すような画像から矩形を特定し抽出する方法を教えてください。openCVで不完全な矩形を特定する方法

私の四角形は不完全であり、いくつかの辺が欠落しており、いくつかの辺は部分的な線であるかもしれないことに注意してください。

ありがとうございます!

image sample

+1

これは、「ゲシュタルト心理学」と呼ばれる心理学研究の一部です。ウィキペディアによると、あなたは "閉鎖の法則"を探しています。最初のGoogleヒットの1つは、http://users.acin.tuwien.ac.at/arichtsfeld/files/2012-ICPR-Richtsfeldです。pdfしかし多分あなたはそれらのキーワードを使用していくつかの研究の後でより多くを見つけることができます。 – Micka

+1

Phew。私の理解の範囲を超えた方法。しかし、私は簡単な解決策を得ることができない場合、私はそれをチェックします!ありがとう – lucidxistence

+0

私は一般的にそれは簡単な仕事ではないと言うでしょう!しかし、あなたのアプリケーションに十分な単純なヒューリスティックがあるかもしれません。 – Micka

答えて

2

これは、eroding and dilatingなどの操作を使用して解決できます。この2つの操作は閉じた四角形の作成に役立ちます。 その後、pageのチュートリアルを使用して、長方形などの単純な図形を検出することができます。

私はあなたが提供したイメージのために働いたクイックデモを実装しました。


main.py:

​​

は侵食が私たちが侵食後に拡張する必要があり、通常の幅に戻って取得するために、すべての行を厚く。私は、エロードがどのように機能し、その逆があるかを見るために、拡張操作を一度コメントすることをお勧めします。 この操作はこのように画像を変換しますthis

私が使用した検出アルゴリズムでは、黒い背景に白線が表示されます。 なぜ画像を反転する必要があるのですか?

cv2.bitwise_not (dilate, dilate) 

その後、チュートリアルのコードを使用できます。

image = dilate 
resized = imutils.resize(image, width=300) 
ratio = image.shape[0]/float(resized.shape[0]) 

# convert the resized image to grayscale, blur it slightly, 
# and threshold it 
gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY) 
blurred = cv2.GaussianBlur(gray, (5, 5), 0) 
thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1] 
#thresh = dilate 
# find contours in the thresholded image and initialize the 
# shape detector 
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, 
    cv2.CHAIN_APPROX_SIMPLE) 
cnts = cnts[0] if imutils.is_cv2() else cnts[1] 
sd = ShapeDetector() 

# loop over the contours 
for c in cnts: 
    # compute the center of the contour, then detect the name of the 
    # shape using only the contour 
    M = cv2.moments(c) 
    cX = int((M["m10"]/M["m00"]) * ratio) 
    cY = int((M["m01"]/M["m00"]) * ratio) 
    shape = sd.detect(c) 

    # multiply the contour (x, y)-coordinates by the resize ratio, 
    # then draw the contours and the name of the shape on the image 
    c = c.astype("float") 
    c *= ratio 
    c = c.astype("int") 
    cv2.drawContours(image, [c], -1, (0, 255, 0), 2) 
    cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX, 
     0.5, (255, 255, 255), 2) 

    # show the output image 
    cv2.imshow("Image", image) 
    cv2.waitKey(0) 

shapeDetector.py:

# import the necessary packages 
import cv2 

class ShapeDetector: 
    def __init__(self): 
     pass 

    def detect(self, c): 
     # initialize the shape name and approximate the contour 
     shape = "unidentified" 
     peri = cv2.arcLength(c, True) 
     approx = cv2.approxPolyDP(c, 0.04 * peri, True) 
     # if the shape is a triangle, it will have 3 vertices 
     if len(approx) == 3: 
      shape = "triangle" 

     # if the shape has 4 vertices, it is either a square or 
     # a rectangle 
     elif len(approx) == 4: 
      # compute the bounding box of the contour and use the 
      # bounding box to compute the aspect ratio 
      (x, y, w, h) = cv2.boundingRect(approx) 
      ar = w/float(h) 

      # a square will have an aspect ratio that is approximately 
      # equal to one, otherwise, the shape is a rectangle 
      shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle" 

     # if the shape is a pentagon, it will have 5 vertices 
     elif len(approx) == 5: 
      shape = "pentagon" 

     # otherwise, we assume the shape is a circle 
     else: 
      shape = "circle" 

     # return the name of the shape 
     return shape 

結果:

enter image description here

+0

@Jeru Luke質問は「どのように矩形を識別して抽出するのか...」と書かれていますが、私の四角形は不完全であるかもしれないことに注意してください[...]。 –

0

Iは有意表される空間を識別し、このような各対をループ次に、正確に90度だけ異なるハフ空間に大きな質量と角度の対を同定次に、関心の角度を特定するためにハフ変換を取ることをお勧めしますそのような正則線候補からの可能性のある矩形を識別するために、そのような「垂直」および「水平」線候補のすべてのオフセットとそこからのヒューリスティックを使用します。

例えば、与えられた角度の対の線のセットを特定した後、評価する線の数が比較的少ない可能性が高いので、対で無差別なO(N^2)検索のようなことができます関連するコーナー(片側が「空」、両側が「密」と定義されている)を検索し、コーナーを一致させて長方形のリストを作成します。

関連する問題