python opencv TypeError: Layout of the output array incompatible with cv::Mat
Solution 1
The solution was to convert found
first to a numpy array, and then to recovert it into a list:
found = np.array(found)
boxes = cv2.groupRectangles(found.tolist(), 1, 2)
Solution 2
My own solution was simply to ask a copy of original array...(god & gary bradski knows why...)
im = dbimg[i]
bb = boxes[i]
m = im.transpose((1, 2, 0)).astype(np.uint8).copy()
pt1 = (bb[0],bb[1])
pt2 = (bb[0]+bb[2],bb[1]+bb[3])
cv2.rectangle(m,pt1,pt2,(0,255,0),2)
Solution 3
Another reason may be that the array is not contiguous. Making it contiguous would also solve the issue
image = np.ascontiguousarray(image, dtype=np.uint8)
Solution 4
Opencv appears to have issues drawing to numpy arrays that have the data type np.int64
, which is the default data type returned by methods such as np.array
and np.full
:
>>> canvas = np.full((256, 256, 3), 255)
>>> canvas
array([[255, 255, 255],
[255, 255, 255],
[255, 255, 255]])
>>> canvas.dtype
dtype('int64')
>>> cv2.rectangle(canvas, (0, 0), (2, 2), (0, 0, 0))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
The solution is to convert the array to np.int32
first:
>>> cv2.rectangle(canvas.astype(np.int32), (0, 0), (2, 2), (0, 0, 0))
array([[ 0, 0, 0],
[ 0, 255, 0],
[ 0, 0, 0]], dtype=int32)
user961627
Updated on May 13, 2020Comments
-
user961627 almost 4 years
I'm using the selective search here: http://koen.me/research/selectivesearch/ This gives possible regions of interest where an object might be. I want to do some processing and retain only some of the regions, and then remove duplicate bounding boxes to have a final neat collection of bounding boxes. To discard unwanted/duplicated bounding boxes regions, I'm using the
grouprectangles
function of opencv for pruning.Once I get the interesting regions from Matlab from the "selective search algorithm" in the link above, I save the results in a
.mat
file and then retrieve them in a python program, like this:import scipy.io as sio inboxes = sio.loadmat('C:\\PATH_TO_MATFILE.mat') candidates = np.array(inboxes['boxes']) # candidates is 4 x N array with each row describing a bounding box like this: # [rowBegin colBegin rowEnd colEnd] # Now I will process the candidates and retain only those regions that are interesting found = [] # This is the list in which I will retain what's interesting for win in candidates: # doing some processing here, and if some condition is met, then retain it: found.append(win) # Now I want to store only the interesting regions, stored in 'found', # and prune unnecessary bounding boxes boxes = cv2.groupRectangles(found, 1, 2) # But I get an error here
The error is:
boxes = cv2.groupRectangles(found, 1, 2) TypeError: Layout of the output array rectList is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
What's wrong? I did something very similar in another piece of code which gave no errors. This was the error-free code:
inboxes = sio.loadmat('C:\\PATH_TO_MY_FILE\\boxes.mat') boxes = np.array(inboxes['boxes']) pruned_boxes = cv2.groupRectangles(boxes.tolist(), 100, 300)
The only difference I can see is that
boxes
was a numpy array which I then converted to a list. But in my problematic code,found
is already a list. -
nair.ashvin over 8 yearssimply copying the array worked for me for a similar error as well.
-
Pwnna over 8 yearsCan confirm this as well, there seems to be no visible difference, tho.
-
DanGoodrick almost 8 yearsThis solution worked for a similar error produced by the cv2.ellipse() function
-
DarkCygnus over 6 yearsSame with cv2.line ... although it seems that the issue was solved by changing it to a np array rather than "just" making a copy of it (that is, it should be a np array copy of your list)
-
CMCDragonkai about 6 yearsI had the same problem, and I noticed if I just use
astype(np.uint8)
it also just works. But then I read thatastype
automatically copies the array. -
Nic almost 6 yearsWorks. Can anyone explain why this is necessary for the cv2.rectangle() function?
-
TimZaman over 5 yearsit's
ascontiguousarray
-> docs.scipy.org/doc/numpy/reference/generated/… -
user3731622 over 5 years@Nic worked for me too. I'd like to hear why this is necessary too.
-
plhn over 5 yearsDeniz Beker’s solution(
ascontiguousarray
) explains why. -
Gabriel123 almost 4 yearsthanks! I had identical problem with
cv2.HoughLinesP
ANDcv2.line
methods, and a conversion to int through.astype(np.uint8)
solved both issues and saved my hair! -
Eric Cousineau over 3 yearsThe error message more-or-less describes it, but yeah, it uses some specialized terms. If you want to dig more, here's the cv2 code: github.com/opencv/opencv/blob/3.4.0/modules/python/src2/… Basically,
cv::Mat
can only express a certain type of stride (or "step"), and you need a writeable view, so you can't copy (as that defeats the purpose of an output arg entirely), hence the fail-fast. For more details: docs.opencv.org/3.4.0/d3/d63/classcv_1_1Mat.html#details -
Can H. Tartanoglu over 2 yearsLike some other people in this comment area, I also got here because of issues with
cv2.rectange()
. My problem was with the color type, my color wasnp.ndarray
, converting it totuple
solved my problem.