Opencv polylines function in python throws exception
Question:
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 1280×960):
[[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?
Answers:
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):
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.
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
)
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
Replace cv2.fillPoly( im, np.int32(points))
with cv2.fillPoly( im, np.int32([points]))
. It will work.
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)
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)
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 1280×960):
[[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?
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):
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.
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
)
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
Replace cv2.fillPoly( im, np.int32(points))
with cv2.fillPoly( im, np.int32([points]))
. It will work.
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)
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)