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
python opencv TypeError: Layout of the output array incompatible with cv::Mat
提问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 grouprectangles
function of opencv for pruning.
我在这里使用选择性搜索:http: //koen.me/research/selectivesearch/这给出了对象可能所在的可能感兴趣的区域。我想做一些处理并只保留一些区域,然后删除重复的边界框以获得最终整齐的边界框集合。为了丢弃不需要的/重复的边界框区域,我使用grouprectangles
opencv的功能进行修剪。
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:
一旦我从上面链接中的“选择性搜索算法”中获得了来自 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 boxes
was a numpy array which I then converted to a list. But in my problematic code, found
is already a list.
我能看到的唯一区别是这boxes
是一个 numpy 数组,然后我将其转换为列表。但在我有问题的代码中,found
已经是一个列表。
采纳答案by user961627
The solution was to convert found
first 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.array
and 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.int32
first:
解决方案是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()