python opencv TypeError:输出数组的布局与cv :: Mat不兼容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23830618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:29:06  来源:igfitidea点击:

python opencv TypeError: Layout of the output array incompatible with cv::Mat

pythonarraysmatlabopencvnumpy

提问by user961627

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 grouprectanglesfunction of opencv for pruning.

我在这里使用选择性搜索:http: //koen.me/research/selectivesearch/这给出了对象可能所在的可能感兴趣的区域。我想做一些处理并只保留一些区域,然后删除重复的边界框以获得最终整齐的边界框集合。为了丢弃不需要的/重复的边界框区域,我使用grouprectanglesopencv的功能进行修剪。

Once I get the interesting regions from Matlab from the "selective search algorithm" in the link above, I save the results in a .matfile and then retrieve them in a python program, like this:

一旦我从上面链接中的“选择性搜索算法”中获得了来自 Matlab 的有趣区域,我将结果保存在一个.mat文件中,然后在一个 python 程序中检索它们,如下所示:

 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 boxeswas a numpy array which I then converted to a list. But in my problematic code, foundis already a list.

我能看到的唯一区别是这boxes是一个 numpy 数组,然后我将其转换为列表。但在我有问题的代码中,found已经是一个列表。

采纳答案by user961627

The solution was to convert foundfirst to a numpy array, and then to recovert it into a list:

解决方案是首先转换found为 numpy 数组,然后将其恢复为列表:

found = np.array(found)
boxes = cv2.groupRectangles(found.tolist(), 1, 2)

回答by Etienne Perot

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)  

回答by MattLBeck

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.arrayand np.full:

Opencv 似乎在绘制具有数据类型的 numpy 数组时遇到问题np.int64,这是由np.array和等方法返回的默认数据类型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.int32first:

解决方案是np.int32先将数组转换为:

>>> 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)

回答by Deniz Beker

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)

image = np.ascontiguousarray(image, dtype=np.uint8)

回答by Gabriel123

Just for the sake of completeness, it seems that many of us have used the solution of Etienne Perot above, minus .copy(). Converting the array type to int is enough. For example, when using the Hough transform:

只是为了完整起见,似乎我们中的许多人都使用了上面 Etienne Perot 的解决方案,减去.copy()。将数组类型转换为 int 就足够了。例如,当使用霍夫变换时:

    # Define the Hough transform parameters
    rho,theta,threshold,min,max = 1, np.pi/180, 30, 40, 60  

    image = ima.astype(np.uint8) # assuming that ima is an image.

    # Run Hough on edge detected image
    lines = cv2.HoughLinesP(sob, rho, theta, threshold, np.array([]), min, max)

    # Iterate over the output "lines" and draw lines on the blank 
    line_image = np.array([[0 for col in range(x)] for row in range(y)]).astype(np.uint8)

    for line in lines: # lines are series of (x,y) coordinates
        for x1,y1,x2,y2 in line:
            cv2.line(line_image, (x1,y1), (x2,y2), (255,0,0), 10)

Only then could the data be plotted out using plt.imshow()

只有这样,数据才能使用 plt.imshow()