我的图像有一个粗线像素,下面有一行。我想
所以我使用了这个循环:
N = 1000
im = (np.random.random((N, N)) - 0.5)
xx,yy = np.where(im > 0)
for x,y in zip(xx,yy):
for i in range(xmin,xmax): # I played with the limits so they would fit my specific image
# if inner loop already broke
if im[x][y] == False:
break
for j in range(ymin,ymax): # here again
if im[x-i][y+j]:
im[x][y] = False
break
这非常适合(大约95%的不需要的像素被移除)但它非常慢......我每张图片花费大约1秒钟,其中像np.where, np.argmax
这样的操作需要< 0.01秒
如何使用numpy
(我猜numpy
最适合)来加快速度呢?
编辑: 使用@numba.jit
按照@jmd_dk的建议非常有用,但它似乎仍然比普通numpy
方法慢
为了澄清,我不仅要找到np.where(im > 0)
提供的正像素的位置,还要查找在其下方/上方有正像素的像素的位置...
所以,如果我有这个矩阵:
0 | 0 | 0 | 1 | 1 | 1 | 0
0 | 0 | 0 | 0 | 0 | 0 | 1
0 | 1 | 0 | 1 | 0 | 1 | 1
0 | 0 | 0 | 1 | 1 | 0 | 1
0 | 0 | 0 | 0 | 0 | 0 | 1
0 | 1 | 0 | 1 | 1 | 1 | 1
我想找到所有'1'
像素,其上方有'1'
并删除它们 - 获取此矩阵:
0 | 0 | 0 | 1 | 1 | 1 | 0
0 | 0 | 0 | 0 | 0 | 0 | 1
0 | 1 | 0 | * | 0 | * | *
0 | 0 | 0 | * | * | 0 | *
0 | 0 | 0 | 0 | 0 | 0 | *
0 | * | 0 | * | * | * | *
我将1
替换为*
所以它会突然出现......
答案 0 :(得分:1)
这是Numba真正闪耀的情况。没有任何实际工作,我立即获得~115x的加速(次数,而不是百分比!)。我没有你的整个代码,但请考虑这个例子:
import numpy as np
import numba
from time import time
@numba.jit
def fun():
# Added just to make the code run
t0 = time()
N = 1000
im = (np.random.random((N, N)) - 0.5)
xmin = ymin = 0
xmax = ymax = N
# Your code
xx,yy = np.where(im > 0)[0], np.where(im > 0)[1]
for x,y in zip(xx,yy):
for i in range(xmin,xmax):
if im[x][y] == False:
break
for j in range(ymin,ymax):
if im[x-i][y+j]:
im[x][y] = False
break
t1 = time()
print('took', t1 - t0, 's')
fun()
fun()
在我的机器上,我得到了
取0.18608522415161133 s
花了0.0416417121887207 s
现在删除numba.jit
装饰器,我得到
采取了4.783859491348267 s
采取了4.796429872512817 s
获取Numba包的最简单方法是使用Anaconda Python发行版。
然后,您应该为每个图像调用一次函数(此处为fun()
)。第一次调用该函数时,Numba会将其编译为快速代码,这就是为什么第一次调用比第二次调用慢得多(尽管仍然比普通的非Numba版本快得多)。