四角形が画像内で領域を接続している場合、どのように検出できますか?高度な方形検出(接続された領域で)
私はそれがうまく機能しなかった OpenCV C++/Obj-C: Advanced square detection
に記載の方法をテストしました。
いいアイデアはありますか?
import cv2
import numpy as np
def angle_cos(p0, p1, p2):
d1, d2 = (p0-p1).astype('float'), (p2-p1).astype('float')
return abs(np.dot(d1, d2)/np.sqrt(np.dot(d1, d1)*np.dot(d2, d2)))
def find_squares(img):
squares = []
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cv2.imshow("gray", gray)
gaussian = cv2.GaussianBlur(gray, (5, 5), 0)
temp,bin = cv2.threshold(gaussian, 80, 255, cv2.THRESH_BINARY)
# cv2.imshow("bin", bin)
contours, hierarchy = cv2.findContours(bin, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(gray, contours, -1, (0, 255, 0), 3)
#cv2.imshow('contours', gray)
for cnt in contours:
cnt_len = cv2.arcLength(cnt, True)
cnt = cv2.approxPolyDP(cnt, 0.02*cnt_len, True)
if len(cnt) == 4 and cv2.contourArea(cnt) > 1000 and cv2.isContourConvex(cnt):
cnt = cnt.reshape(-1, 2)
max_cos = np.max([angle_cos(cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4]) for i in xrange(4)])
if max_cos < 0.1:
squares.append(cnt)
return squares
if __name__ == '__main__':
img = cv2.imread('123.bmp')
#cv2.imshow("origin", img)
squares = find_squares(img)
print "Find %d squres" % len(squares)
cv2.drawContours(img, squares, -1, (0, 255, 0), 3)
cv2.imshow('squares', img)
cv2.waitKey()
私はOpenCVの例では、いくつかの方法を使用しますが、結果は良くありません。
+1 - 素敵な仕事。 –
うん、本当にいいアプローチ、+1。画像フォーマットを正しいフォーマットにするのは恐ろしいことですが、ここで示した同じzip展開方法を使用していましたが、最近は移調やコピーよりも遅くなることがわかりました(重要です)。残念ながら、 (少なくとも私にとっては)opencvの例外を避けるためにコピーが必要なようです。 – fraxel
違いはnumpyはデフォルトで '(y、x)'座標で動作し、OpenCVは '(x、y)'です。 @fraxel私はパフォーマンスを測定しませんでしたが、更新されたコードがその特定の点で優れている可能性があります。 – mmgp