Vas*_*dis 2 python binary opencv numpy edges
我想制作一个实时应用程序,它涉及查找二进制掩码的边缘.如果可能的话,我需要一些快速的东西,没有GPU,每张图像低于0.0005秒,大小(1000,1000).我将使用以下二进制图像示例,大小(1000,1000).
(要复制的代码:)
import numpy as np
im=np.zeros((1000,1000),dtype=np.uint8)
im[400:600,400:600]=255
Run Code Online (Sandbox Code Playgroud)
快速做事的第一个合理方法是使用OpenCV库:
import cv2
timeit.timeit(lambda:cv2.Laplacian(im,cv2.CV_8U),number=100)/100
0.0011617112159729003
Run Code Online (Sandbox Code Playgroud)
正如预期的那样导致: 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
Run Code Online (Sandbox Code Playgroud)
这给出了与上述相同的结果.这样比较好,但仍然不如我想的那么好.我继续使用numpy,使用渐变近似laplacian,作为最后的手段,虽然我知道它会更糟:
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
Run Code Online (Sandbox Code Playgroud)
那么,有没有人可以进一步了解如何加速我的算法?我强调我希望这个算法用于二进制图像,所以我想必须有一个更好的实现.
我选择了速度最快的一个cv2.findContours.在其中,我们可以transpose用简单的方式替换那些昂贵的和转换为元组的部分slicing,就像这样 -
idx = cv2.findContours(im,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)[1][0]
out = np.zeros_like(im)
out[idx[:,0,0],idx[:,0,1]] = 255
Run Code Online (Sandbox Code Playgroud)
运行时测试 -
In [114]: # Inputs
...: im=np.zeros((1000,1000),dtype=np.uint8)
...: im[400:600,400:600]=255
...: idx = cv2.findContours(im,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)[1][0]
...:
In [115]: def original_app(im, idx):
...: points=np.transpose(idx)
...: tmp=np.zeros_like(im)
...: tmp[tuple(points)]=255
...: return tmp
...:
...: def proposed_app(im, idx):
...: out = np.zeros_like(im)
...: out[idx[:,0,0],idx[:,0,1]] = 255
...: return out
...:
In [120]: %timeit original_app(im, idx)
10000 loops, best of 3: 108 µs per loop
In [121]: %timeit proposed_app(im, idx)
10000 loops, best of 3: 101 µs per loop
In [122]: %timeit cv2.findContours(im,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
1000 loops, best of 3: 1.55 ms per loop
Run Code Online (Sandbox Code Playgroud)
因此,所提出的方法在那里有一些微小的改进,但与轮廓发现本身相比,这似乎可以忽略不计.
我查看了scikit-image's version并进行了快速测试,看起来它比OpenCV版本慢得多.
| 归档时间: |
|
| 查看次数: |
1797 次 |
| 最近记录: |