web-dev-qa-db-ja.com

OpenCV-cv2.approxPolyDP()を正しく使用する

cv2.approxPolyDP()を使用して、画像の輪郭の近似を抽出しようとしています。私が使用している画像は次のとおりです。

map of UK

私のコードは、本島を分離し、輪郭近似と輪郭ハルを定義してプロットしようとします。緑色の輪郭、赤色の近似をプロットしました。

_import numpy as np
import cv2

# load image and shrink - it's massive
img = cv2.imread('../data/UK.png')
img = cv2.resize(img, None,fx=0.25, fy=0.25, interpolation = cv2.INTER_CUBIC)

# get a blank canvas for drawing contour on and convert img to grayscale
canvas = np.zeros(img.shape, np.uint8)
img2gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# filter out small lines between counties
kernel = np.ones((5,5),np.float32)/25
img2gray = cv2.filter2D(img2gray,-1,kernel)

# threshold the image and extract contours
ret,thresh = cv2.threshold(img2gray,250,255,cv2.THRESH_BINARY_INV)
im2,contours,hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)


# find the main island (biggest area)
cnt = contours[0]
max_area = cv2.contourArea(cnt)

for cont in contours:
    if cv2.contourArea(cont) > max_area:
        cnt = cont
        max_area = cv2.contourArea(cont)

# define main island contour approx. and hull
perimeter = cv2.arcLength(cnt,True)
epsilon = 0.01*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)

hull = cv2.convexHull(cnt)

# cv2.isContourConvex(cnt)

cv2.drawContours(canvas, cnt, -1, (0, 255, 0), 3)
cv2.drawContours(canvas, approx, -1, (0, 0, 255), 3)
## cv2.drawContours(canvas, hull, -1, (0, 0, 255), 3) # only displays a few points as well.

cv2.imshow("Contour", canvas)
k = cv2.waitKey(0)

if k == 27:         # wait for ESC key to exit
    cv2.destroyAllWindows()
_

結果の画像は次のとおりです。

enter image description here

最初の画像は、輪郭を緑色でプロットします。 2番目は赤で近似をプロットします-この近似を連続閉曲線としてプロットするにはどうすればよいですか?

ドキュメント はそれほど明確ではなく、どちらも チュートリアル ではありませんが、私の理解では、cv2.approxPolyDP()は連続した閉じた曲線を定義する必要があります。 cv2.drawContours()でプロットできます。あれは正しいですか?もしそうなら、私は何を間違っていますか?

13
Aidenhjj

問題は視覚化のみです:drawContoursは、1つのnumpy配列(approxPolyDPから返される)ではなく、輪郭の配列(Pythonの場合はリスト)を予期します。

解決策は次のとおりです。交換

cv2.drawContours(canvas, approx, -1, (0, 0, 255), 3)

cv2.drawContours(canvas, [approx], -1, (0, 0, 255), 3)
23
avtomaton