48
votes

I'm trying to draw an arbitrary quadrilateral over an image using the polylines function in opencv. When I do I get the following error

OpenCV Error: Assertion failed (p.checkVector(2, CV_32S) >= 0) in polylines, file /tmp/buildd/ros-fuerte-opencv2-2.4.2-1precise-20130312-1306/modules/core/src/d rawing.cpp, line 2065

I call the function as like so,

cv2.polylines(img, points, 1, (255,255,255))

Where points is as numpy array as shown below (The image size is 1280x960):

[[910 641]
 [206 632]
 [696 488]
 [458 485]]

and img is just a normal image that I'm able to imshow. Currently I'm just drawing lines between these points myself, but I'm looking for a more elegant solution.

How should I correct this error?

7
cv2.polylines(img, np.reshape(p, (1, *p), 1, (255,255,255))Epsi95

7 Answers

65
votes

The problem in my case was that numpy.array created int64-bit numbers by default. So I had to explicitly convert it to int32:

points = np.array([[910, 641], [206, 632], [696, 488], [458, 485]])
# points.dtype => 'int64'
cv2.polylines(img, np.int32([points]), 1, (255,255,255))

(Looks like a bug in cv2 python binding, it should've verified dtype)

42
votes

This function is not enough well documented and the error are also not very useful. In any case, cv2.polylines expects a list of points, just change your line to this:

import cv2
import numpy as np

img = np.zeros((768, 1024, 3), dtype='uint8')

points = np.array([[910, 641], [206, 632], [696, 488], [458, 485]])
cv2.polylines(img, [points], 1, (255,255,255))

winname = 'example'
cv2.namedWindow(winname)
cv2.imshow(winname, img)
cv2.waitKey()
cv2.destroyWindow(winname)

The example above will print the following image (rescaled):

enter image description here

11
votes

the error says your array should be of dimension 2. So reshape the array as follows:

points = points.reshape(-1,1,2)

Then it works fine.

Also, answer provided by jabaldonedo also works fine for me.

1
votes

Replace cv2.fillPoly( im, np.int32(points)) with cv2.fillPoly( im, np.int32([points])). It will work.

1
votes

I also faced the same problem The solution is to make a array of 1 row, 2 columns and - 1 depth, - 1 means unknown dimensions so numpy will assign convenient depth to the array. If you make array of more than 1 row and 2 columns it will show error.

Also this error can come when the array you created is not of type int32

Vertices = np.array([[36,86] ,[73,73], [87,87]], dtype=np.int32)
0
votes
pts = np.array([[40,300],[54,378],[60,420],[30,333]],np.int32) 
pts = pts.reshape((-1,1,2))
img = cv2.polylines(img,pts,True,(125,215,145),1)

The official documentation to provide explanation,need reshape

0
votes
import cv2
import numpy as np

sz, sh, of = 1000, 500, 100

# Create an Empty image with white background
im = 255 * np.ones(shape=[sz, sz, 3], dtype=np.uint8)

# Draw shapes
im = cv2.polylines(
    img=im,
    pts=[np.int32([
        [of, of], 
        [sh, of + of], 
        [sz - of, of],
        [sz-of-of,sh],
        [sz-of,sz-of],
        [sh,sz-of-of],
        [of,sz-of],
        [of+of,sh]])],
    isClosed=True,
    color=(128, 0, 200),
    thickness=30,
    lineType=cv2.LINE_AA,  # Anti-Aliased
)

cv2.imwrite("polylines.jpg", im)

enter image description here