web-dev-qa-db-ja.com

python opencv TypeError:cv :: Matと互換性のない出力配列のレイアウト

ここでは選択検索を使用しています。 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はすでにリストです。

11
user961627

解決策は、最初にfoundをnumpy配列に変換し、次にそれをリストに復元することでした:

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

私自身の解決策は、元の配列のコピーを尋ねることでした...(神とゲイリー・ブラッドスキーは理由を知っています...)

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)  
51
Etienne Perot

別の理由として、配列が隣接していないことが考えられます。隣接させることも問題を解決します

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

18
Deniz Beker

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
MattLBeck