2017-07-02 113 views
1

我是新来的python和我试图编写一个代码,从图像中提取轮廓和排序他们轮廓列表中元素长度的升序。当我使用sort()或list.sort()时,出现错误:操作数不能与形状一起广播(1776,1,2)(3896,1,2) 我该如何解决这个问题? 这是我正在使用的image错误:操作数无法与形状一起广播(1776,1,2)(3896,1,2)

我得到的错误信息是:

Traceback (most recent call last): 

File "/home/dehaoliu/opencv_test/Engineering drawings/example.py", line 19, in <module> 
    contours.sort() 
ValueError: operands could not be broadcast together with shapes (1776,1,2) (3896,1,2) 

下面是缩短代码产生错误:

import cv2 
    import numpy as np 
    from math import sqrt 

name='20_right_5-1' 
img = cv2.imread(name+'.JPG') 
im = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
cv2.imwrite(name+"_dilation.jpg", closing) 
im = cv2.imread(name+'_dilation.jpg') 
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) 
#ret,thresh = cv2.threshold(imgray,127,255,cv2.THRESH_BINARY_INV) 
blur = cv2.GaussianBlur(imgray,(5,5),0) 
ret,thresh = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 
im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE) 
cv2.drawContours(im, contours, -1, (0,255,0), 3) 

cv2.namedWindow("Contours") 
cv2.imshow("Contours", im) 

cv2.waitKey(0) 
cv2.destroyAllWindows() 

cv2.imwrite(name+"_contour.jpg", im) 
print "this is contours" 
print contours 
print type(contours) 
contours.sort() 
+0

这很容易_make错误走开,确保结果是你想要的结果并不容易。你是否了解这些维度在错误中的含义,以及预期结果的大小应该是多少? –

+0

我相信它们是列表中第一个和第二个元素的尺寸 – Alizay

+0

对不起如果这是一个愚蠢的问题。我以前没有使用python的经验,现在我一直试图弄清楚这一点。 – Alizay

回答

0

注意,你原来的问题,你的缩短版都包含了一些错误,这使得再现你的问题有点困难。此外,你似乎正在做很多不必要的事情(例如不使用它们导入数学,图像,matplotlib,scipy等,或者只保存图像以另一个名称读取它们)。

无论如何,你的问题的核心可以很容易地回答。您contours,从cv2.findContours返回是这个样子:

>>> type(contours) 
list 
>>> len(contours) 
15 
>>> type(contours[0]) 
numpy.ndarray 
>>> print(contours[0].shape) 
(3888, 1, 2) 

即你的15个轮廓中的每一个都是一个形状为(N,1,2)的3d numpy阵列。除了单独维外,您在矩阵中基本上有N*2个点:N个整数对,即N对跟踪图像上给定轮廓的图像坐标。

现在,当你试图理清这个列表的阵列,蟒蛇试图比较两个元素,如

contours[0] < contours[1] 

但numpy的阵列相比的elementwise,与所谓的广播当数组在某些地方具有单例尺寸时使用。这意味着以下行为:

>>> np.random.rand(2,3) < np.random.rand(1,3) 
array([[ True, True, False], 
     [False, True, False]], dtype=bool) 
>>> np.random.rand(2,3) < np.random.rand(4,3) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: operands could not be broadcast together with shapes (2,3) (4,3) 

即,兼容形状的阵列(如(2,3)(1,3))被有效地沿单尺寸扩大和比较是由元素来完成元件。如果两种形状不匹配(例如(1776,1,2)(3896,1,2)),则会出现错误。但是,这不是你想要做的!

你想要做的是清楚地表达你的问题:根据长度按升序排列轮廓。大!我们仍然可以使用contours.sort(或sorted()如果我们想要一个副本),但我们需要告诉sort什么排序。在我们的情况下,它需要按轮廓长度排序。轮廓的长度是多少?对于每个轮廓contour,它是其第一维度的大小,即contour.shape[0]

底线是,你需要通过一键功能.sort,可让您通过等高线长度进行排序,从而导致整数(而不是数组)的比较:

>>> [contour.shape[0] for contour in contours] 
[3888, 1775, 1044, 1508, 255, 95, 233, 330, 310, 177, 155, 592, 506, 1044, 663] 
>>> contours.sort(key=lambda contour: contour.shape[0]) 
>>> [contour.shape[0] for contour in contours] 
[95, 155, 177, 233, 255, 310, 330, 506, 592, 663, 1044, 1044, 1508, 1775, 3888] 
+0

非常感谢!它现在非常有意义。我想我无法理解这个错误是由于我不熟悉python以及相应的代码行为,但是感谢你帮助我更好地理解它。 – Alizay

+0

@Alizay我很高兴能够提供帮助。如果你有时间,如果你想使用构建在顶层的框架,学习本地python本身可以帮助_lot_。无论如何,如果上述确实解决了您的问题,请考虑[将我的答案标记为已接受](https://stackoverflow.com/help/accepted-answer)。 –

相关问题