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

时间:2014-05-23 13:31:35

标签: python arrays matlab opencv numpy

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

一旦我从上面链接中的“选择性搜索算法”中获取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

错误是:

    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)

怎么了? 我在另一段代码中做了非常类似的事情,没有给出任何错误。这是无错误的代码:

inboxes = sio.loadmat('C:\\PATH_TO_MY_FILE\\boxes.mat')
boxes = np.array(inboxes['boxes'])
pruned_boxes = cv2.groupRectangles(boxes.tolist(), 100, 300)

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

5 个答案:

答案 0 :(得分:46)

我自己的解决方案只是问一个原始数组的副本......(上帝和加里布拉兹基知道为什么......)

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)  

答案 1 :(得分:12)

另一个原因可能是阵列不连续。使其连续也将解决问题

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:3)

Opencv似乎有问题绘制到数据类型为np.int64的numpy数组,这是np.arraynp.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)

解决方案是首先将数组转换为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)

答案 4 :(得分:0)

仅出于完整性考虑,似乎我们许多人都使用了上面的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)

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

绘制数据