以下に示すような画像から矩形を特定し抽出する方法を教えてください。openCVで不完全な矩形を特定する方法
私の四角形は不完全であり、いくつかの辺が欠落しており、いくつかの辺は部分的な線であるかもしれないことに注意してください。
ありがとうございます!
以下に示すような画像から矩形を特定し抽出する方法を教えてください。openCVで不完全な矩形を特定する方法
私の四角形は不完全であり、いくつかの辺が欠落しており、いくつかの辺は部分的な線であるかもしれないことに注意してください。
ありがとうございます!
これは、eroding and dilatingなどの操作を使用して解決できます。この2つの操作は閉じた四角形の作成に役立ちます。 その後、pageのチュートリアルを使用して、長方形などの単純な図形を検出することができます。
私はあなたが提供したイメージのために働いたクイックデモを実装しました。
main.py:
は侵食が私たちが侵食後に拡張する必要があり、通常の幅に戻って取得するために、すべての行を厚く。私は、エロードがどのように機能し、その逆があるかを見るために、拡張操作を一度コメントすることをお勧めします。 この操作はこのように画像を変換します
私が使用した検出アルゴリズムでは、黒い背景に白線が表示されます。 なぜ画像を反転する必要があるのですか?
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
結果:
@Jeru Luke質問は「どのように矩形を識別して抽出するのか...」と書かれていますが、私の四角形は不完全であるかもしれないことに注意してください[...]。 –
Iは有意表される空間を識別し、このような各対をループ次に、正確に90度だけ異なるハフ空間に大きな質量と角度の対を同定次に、関心の角度を特定するためにハフ変換を取ることをお勧めしますそのような正則線候補からの可能性のある矩形を識別するために、そのような「垂直」および「水平」線候補のすべてのオフセットとそこからのヒューリスティックを使用します。
例えば、与えられた角度の対の線のセットを特定した後、評価する線の数が比較的少ない可能性が高いので、対で無差別なO(N^2)検索のようなことができます関連するコーナー(片側が「空」、両側が「密」と定義されている)を検索し、コーナーを一致させて長方形のリストを作成します。
これは、「ゲシュタルト心理学」と呼ばれる心理学研究の一部です。ウィキペディアによると、あなたは "閉鎖の法則"を探しています。最初のGoogleヒットの1つは、http://users.acin.tuwien.ac.at/arichtsfeld/files/2012-ICPR-Richtsfeldです。pdfしかし多分あなたはそれらのキーワードを使用していくつかの研究の後でより多くを見つけることができます。 – Micka
Phew。私の理解の範囲を超えた方法。しかし、私は簡単な解決策を得ることができない場合、私はそれをチェックします!ありがとう – lucidxistence
私は一般的にそれは簡単な仕事ではないと言うでしょう!しかし、あなたのアプリケーションに十分な単純なヒューリスティックがあるかもしれません。 – Micka