Creating your own contour in opencv using python
Asked Answered
P

4

25

I have a set of boundary points of an object.

I want to draw it using opencv as contour.

I have no idea that how to convert my points to contour representation.

To the same contour representation which is obtained by following call

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

Any ideas?

Thanks

Pastoralize answered 4/1, 2013 at 16:52 Comment(0)
D
33

By looking at the format of the contours I would think something like this should be sufficient:

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

This small program gives an running example:

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)
Darcydarda answered 4/1, 2013 at 17:18 Comment(1)
Creating a contour this way works for cv2.drawContours but doesn't seem to work when using cv2.pointPolygonTest. Is there a way of actually returning a contour object ?Disability
D
25

To create your own contour from a python list of points L

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

Create a numpy array ctr from L, reshape it and force its type

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

ctr is our new countour, let's draw it on an existing image

cv2.drawContours(image,[ctr],0,(255,255,255),1)
Denadenae answered 12/6, 2014 at 0:50 Comment(1)
great answer, respecting all of opencv's constraintsAlthough
H
13

A contour is simply a curve joining all continuous points so to create your own contour, you can create a np.array() with your (x,y) points in clockwise order

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

That's it!


There are two methods to draw the contour onto an image depending on what you need:

Contour outline

If you only need the contour outline, use cv2.drawContours()

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

Filled contour

To get a filled contour, you can either use cv2.fillPoly() or cv2.drawContours() with thickness=-1

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

Full example code for completeness

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()
Harwell answered 5/10, 2019 at 1:32 Comment(1)
A contour has a more complicated shape than a list of points, sadlyAlthough
G
1

To add to Cherif KAOUA's answer, I found I had to convert to list and zip my numpy array. Reading in an array of points from a text file:

  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))
Grani answered 8/12, 2016 at 21:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.