2012-02-18 19 views
4

私はthis paperのようなコンポーネントラベリングアルゴリズムをpythonとopencvを使って実装しています。入力画像をピクセル単位でチェックし、バイナリ画像のブロブにラベルを割り当てるために、いわゆる輪郭追跡サブルーチンを実行する必要があります。pythonとopencvでの高速コンポーネントラベリング

私はそれを稼働させることができますが、それは非常に遅いようです。コードをプロファイリングすると、ピクセルにアクセスするforループがボトルネックに見えることがわかります。 256px * 256pxの画像で約200msかかる。おおよそ次のようになります。

for i in image.height: 
    for j in image.width: 
     p = image[i, j] 
      pa = image[i - 1, j] 
      pb = image[i + 1, j] 
      # etc... 

ここで、「image」はバイナリのopencv画像です。

ビデオアプリケーションでも使用できるように、より速い方法があるのだろうかと思います。私は20〜25fpsを得るために同じ問題のサイズに対して40〜50msの実行時間を目標にしています。 10-15fpsもおそらく許容されます(66-100msの稼働時間)。

私ができることは、何かヒントやアイデアは大変ありがたいです。

+0

Pythonは正確には高性能言語ではありません... Java、C/C++などでもう一度やり直してください。 –

答えて

1

Python用の最新のOpenCVバインディングでは、numpyのデータ型が返されます。これは、あなたが自由に使いこなすことができます。 numpy(インデックス付き)で2D配列をループするのは、通常、ndenumerateで行われます。これは、少なくともN-D配列用に最適化された単一のループであるため、少なくともスピードアップが必要です。数字の小さいvectorizeを調べるとさらに高速化できますが、配列のインデックスが必要な場合は、ndenumerateが必要です。この向こう

、あなたの最善の策はC.

をボトルネックをライトすることができるアップデート

それが役立つだろうならば、私はscipy.ndimage.labelは、あなたがしようとしている正確に何をし信じる、とさえかもしれません同じアルゴリズムを使用してください。

1

多くの人がOpenCVラベルの欠如を嘆いていると思う投稿です。

@ malloc47は、scipy.ndimage.labelと同様に動作します。私はそれを使用しましたが、イメージ内で最大のブロブを探している間、私はそのパフォーマンスに満足していませんでした。私は、特にラベルを必要としなかったので、私は最大のものを分離するcv2.findContourscv2.contourAreaを使用して終了:

# The [0] is because I didn't care about the hierarchy, which is the second 
# return value of cv2.findContours. 
contours = cv2.findContours(numpy_array, 
          mode=cv2.RETR_EXTERNAL, 
          method=cv2.CHAIN_APPROX_SIMPLE 
          )[0] 

areas = [cv2.contourArea(ctr) for ctr in contours] 
max_contour = [contours[areas.index(max(areas))]] 

これは、はるかに高速私にとって非常に類似した結果についてscipy.ndimage.labelよりことになりました。私が言ったように、これはまさにラベルではありませんが、合理的に優れたラベルを付けるために、おそらく輪郭ファインダーを使うことができます。

関連する問題