Создание собственного контура в opencv с использованием python

У меня есть набор граничных точек объекта.

Я хочу нарисовать его, используя opencv в качестве контура.

Я понятия не имею, как преобразовать мои точки в контурное представление.

К тому же представлению контура, которое получается следующим вызовом

  contours,_ = cv2.findContours(image,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

Есть идеи?

Спасибо


person Shan    schedule 04.01.2013    source источник


Ответы (4)


Глядя на формат контуров, я думаю, что что-то вроде этого должно быть достаточно:

contours = [numpy.array([[1,1],[10,50],[50,50]], dtype=numpy.int32) , numpy.array([[99,99],[99,60],[60,99]], dtype=numpy.int32)]

Эта небольшая программа дает работающий пример:

import numpy
import cv2

contours = [numpy.array([[1,1],[10,50],[50,50]], dtype=numpy.int32) , numpy.array([[99,99],[99,60],[60,99]], dtype=numpy.int32)]

drawing = numpy.zeros([100, 100],numpy.uint8)
for cnt in contours:
    cv2.drawContours(drawing,[cnt],0,(255,255,255),2)

cv2.imshow('output',drawing)
cv2.waitKey(0)
person sietschie    schedule 04.01.2013
comment
Создание контура таким образом работает для cv2.drawContours, но не работает при использовании cv2.pointPolygonTest. Есть ли способ вернуть объект контура? - person Eric F; 03.11.2020

Чтобы создать свой собственный контур из списка точек Python L

L=[[x1,y1],[x2,y2],[x3,y3],[x4,y4],[x5,y5],[x6,y6],[x7,y7],[x8,y8],[x9,y9],...[xn,yn]]

Создайте пустой массив ctr из L, измените его форму и принудительно введите его тип.

ctr = numpy.array(L).reshape((-1,1,2)).astype(numpy.int32)

ctr — это наш новый счетчик, давайте нарисуем его на существующем изображении.

cv2.drawContours(image,[ctr],0,(255,255,255),1)
person Cherif KAOUA    schedule 12.06.2014
comment
отличный ответ, соблюдая все ограничения opencv - person Anderas; 24.12.2020

Контур — это просто кривая, соединяющая все непрерывные точки, поэтому для создания собственного контура вы можете создать np.array() с вашими (x,y) баллами в по часовой стрелке

points = np.array([[25,25], [70,10], [150,50], [250,250], [100,350]])

Вот и все!


Существует два метода рисования контура на изображении в зависимости от того, что вам нужно:

Контурный контур

Если вам нужен только контур контура, используйте контуры" rel="noreferrer">cv2.drawContours()

cv2.drawContours(image,[points],0,(0,0,0),2)

Заполненный контур

Чтобы получить заполненный контур, вы можете использовать cv2.fillPoly() или cv2.drawContours() с thickness=-1

cv2.fillPoly(image, [points], [0,0,0]) # OR
# cv2.drawContours(image,[points],0,(0,0,0),-1)

Полный пример кода для полноты

import cv2
import numpy as np

# Create blank white image
image = np.ones((400,400), dtype=np.uint8) * 255

# List of (x,y) points in clockwise order
points = np.array([[25,25], [70,10], [150,50], [250,250], [100,350]])

# Draw points onto image
cv2.drawContours(image,[points],0,(0,0,0),2)

# Fill points onto image
# cv2.fillPoly(image, [points], [0,0,0])

cv2.imshow('image', image)
cv2.waitKey()
person nathancy    schedule 05.10.2019
comment
Контур имеет более сложную форму, чем список точек, к сожалению - person Anderas; 24.12.2020

Чтобы добавить к ответу Cherif KAOUA, я обнаружил, что мне нужно преобразовать в список и заархивировать мой массив numpy. Чтение массива точек из текстового файла:

  contour = []
  with open(array_of_points,'r') as f:
      next(f) // line one of my file gives the number of points
      for l in f:
          row = l.split()
          numbers = [int(n) for n in row]
          contour.append(numbers)

  ctr = np.array(contour).reshape((-1,1,2)).astype(np.int32)
  ctr = ctr.tolist()
  ctr = zip(*[iter(ctr)]*len(contour))
person ladlibertine    schedule 08.12.2016