2017-01-26 2 views
4

Я пытаюсь извлечь аппроксимацию контура в изображении, используя cv2.approxPolyDP(). Вот изображение Я использую:OpenCV - правильно использовать 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

Первого изображение вычерчивает контур зеленого цвета. Второй график показывает приближение в красном - как я нарисую это приближение как непрерывную замкнутую кривую?

documentation не не очень ясно, и ни один не tutorial, но я понимаю, что cv2.approxPolyDP() следует определить непрерывную замкнутую кривую, которую я должен быть в состоянии построить с cv2.drawContours(). Это верно? Если да, то что я делаю неправильно?

+0

Что ваш вопрос? Чего вы хотите достичь? Ваш код не соответствует визуализации. 'cv2.approxPolyDP()' возвращает список точек, и да, вы можете нарисовать их как кривую, но я не уверен, как она связана с самопересечениями (которые существуют на вашей начальной кривой). – avtomaton

+0

@avtomaton - я обновил свой вопрос - как мне построить возвращенный список точек как непрерывную кривую, если не используя 'drawContours'? – Aidenhjj

+0

Я все еще не уверен, что вы рисуете. Вы правы, вы должны использовать 'drawContours' для рисования контуров, но в вашем коде вы рисуете их на одном холсте, и они показывают одно изображение, но ваши прикрепленные изображения разные! Не могли бы вы разместить соответствующий код? И я все еще полагаю, что это может быть связано с самопересечениями. Попробуйте нарисовать линии istead, чтобы понять это. – avtomaton

ответ

11

Проблема только в визуализации: drawContours ожидает массив (список в случае python) контуров, а не только один массив numpy (который возвращается с approxPolyDP).

Решение заключается в следующем: замена

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

в

cv2.drawContours(canvas, [approx], -1, (0, 0, 255), 3) 
Смежные вопросы