2017-07-02 56 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)。 –

相關問題