2017-07-02 9 views
1

Imはpythonには新しく、画像から輪郭を抽出して輪郭のリスト内の要素の長さの昇順。 sort()またはlist.sort()を使用すると、オペランドをシェイプ(1776,1,2)(3896,1,2)と一緒にブロードキャストできないというエラーが発生します。 どうすればこの問題を解決できますか? これは私が使用しているimageです。私が得たエラー:オペランドをシェイプ(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

私は彼らがリストの最初と2番目の要素の次元であると信じています – Alizay

+0

申し訳ありませんこれはばかな質問です。私は以前のパイソンの経験はありません。私は今、これをしばらく理解しようとしています。 – Alizay

答えて

0

注:

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

してエラーが発生した短縮コードですあなたの問題を少し難しくする。さらに、たくさんの不要なことをしているようです(数学、画像、matplotlib、scipyなどを使用せずに読み込む、画像を保存し直して別の名前に戻すなど)。

とにかく、あなたの質問の中核は簡単に答えることができます。あなたのcontourscv2.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の整数のペア、すなわちN対のx,yのイメージ座標をイメージの座標とするマトリックス内のポイントがN*2になります。今

、あなたは、Pythonは二つの要素を比較しようとすると、リスト・オブ・アレイのこのような

contours[0] < contours[1] 

をソートするためにしようとしている。しかしnumpyの配列は、いわゆる放送で、要素ごとを比較すると配列が特定の場所で単一次元を持つ場合に使用されます。これは、次の動作を意味し、(例えば(2,3)(1,3)など)互換形状のアレイを効果的にシングルトン次元に沿って展開され、比較は要素ごとに行われ、ある

>>> 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つの図形が一致しない場合(例えば、(1776,1,2)(3896,1,2)の場合)、エラーが発生します。しかし、これはあなたが最初にやりたいことではありません!

あなたのやりたいことは、あなたの質問で明確に表現されています:長さに従って輪郭を昇順で並べ替えます。すばらしいです! contours.sort(またはコピーが必要な場合はsorted())を使用することもできますが、で並べ替えるものをsortに伝える必要があります。私たちの場合は、の長さでソートするとになる必要があります。等高線の長さは何ですか?各輪郭contourについては、第1次元のサイズ、すなわち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)を検討してください。 –

関連する問題