バイナリマスクのエッジを見つけることを含むリアルタイムアプリケーションを作成したい。可能であれば、GPUなしで何か速いものが必要です。画像あたり0.0005秒以下で、サイズ(1000,1000)でうまくいきます。サイズ(1000,1000)のバイナリイメージの次の例を使用します。Pythonのバイナリマスクから輪郭マスクを高速に検索する方法
(コードを複製するように:)
import numpy as np
im=np.zeros((1000,1000),dtype=np.uint8)
im[400:600,400:600]=255
を高速に物事を行うための最初の論理的な方法は、OpenCVのライブラリを使用していた。予想通り
import cv2
timeit.timeit(lambda:cv2.Laplacian(im,cv2.CV_8U),number=100)/100
0.0011617112159729003
がもたらしました: laplacian
私はこの方法が非常に時間がかかることがわかった。この後、私はfindContoursを試しました:
def usingcontours(im):
points=np.transpose(cv2.findContours(im,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)[1][0])
tmp=np.zeros_like(im)
tmp[tuple(points)]=255
return tmp
timeit.timeit(lambda:usingcontours(im),number=100)/100
0.0009052801132202148
これは上記と同じ結果をもたらしました。 これは優れていますが、それでも私が望むほど良くはありません。私はそれが悪いことを知っていたが、私は、最後の手段として、勾配を用いてラプラシアン近似する、numpyのの使用に移っ:
def usinggradient(im):
tmp=np.gradient(im)
return ((tmp[0]+tmp[1])>0).astype(np.uint8)
timeit.timeit(lambda:usinggradient(im),number=100)/100
0.018681130409240722
だから、誰に私は私のアルゴリズムを加速させることができる方法上の任意の更なるアイデアを持って?私はこのアルゴリズムをバイナリイメージに使用したいと考えているので、より良い実装が必要であると思います。
NumPyとScipyの形態的侵食とビット単位の操作NumPyでこれを行うことができます。 'scipy.ndimage.morphology.binary_dilation'と' np.logical_ * '関数を見てください。 – YXD
'1000 x 1000/0.0005s = 2 x 10^9 pixels/second' - それは1ピクセルあたり1-2クロック・サイクルであり、ベクトル化と並列化でもそれほど動かない。 –
@DanMašek2×10^9ピクセル/秒とは、ビット画像2×10^9ビット/秒を意味します。良いプログラムは、私が可能と信じているすべてのコアを使用していると仮定すると、8コアの2GHz CPUでは、各コアに4つのスレッドがあり、クロックサイクルあたり32ピクセル(ビット)を処理できるため、64 * 10^9ピクセル/秒= 1000×1000/0.00016秒。ですから、O(3 * n)よりも複雑な実装を求めています。バイナリイメージでは可能です。 –