Python 如何使用numpy有效地生成脉冲噪声图像?
我一直在尝试使用以下代码创建有噪声的图像:Python 如何使用numpy有效地生成脉冲噪声图像?,python,numpy,opencv,image-processing,Python,Numpy,Opencv,Image Processing,我一直在尝试使用以下代码创建有噪声的图像: def toImpulse(img, coef=1.2): # img - > 3dim numpy array, returns impulse image bmp = np.zeros(shape=(img.shape[0], img.shape[1], 1), dtype=np.float) for i in range(img.shape[0]): for j in range(img.shape[1]):
def toImpulse(img, coef=1.2): # img - > 3dim numpy array, returns impulse image
bmp = np.zeros(shape=(img.shape[0], img.shape[1], 1), dtype=np.float)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
bmp[i][j] = sum(img[i][j]) / 3
这里我对RGB通道求和,使图像为单通道?我想它可以写成numpy.sum()
但它在实时视频处理中显得非常缓慢。如何使用NumPy使其更高效?下面是函数工作的示例
您的第二个for循环可以替换为数组的总和中的
np。searchsorted
def toImpulse2(img, coef=1.2): # img - > 3dim numpy array, returns impulse image
bmp = img.sum(axis=2)
max_ = bmp.max() * coef
cumsum = np.cumsum(bmp)
repeats = int(cumsum[-1] / max_)
final = np.zeros((img.shape[0] * img.shape[1], img.shape[2]))
final[np.searchsorted(cumsum, np.arange(1, repeats + 1) * max_)] = 1
return final.reshape(img.shape)
我使用
img.sum()
而不是img.mean()
将所有计算保持为整数类型以提高精度。对于大图像,此代码和您的代码之间几乎没有什么区别,因为它是以浮点类型操作的。您的代码在我的机器上需要539ms的时间。如果我使用Numpy计算3个颜色通道的平均值,并避免将零写入输出图像,因为它已初始化为零,如下所示:
def metoImpulse(img, coef=1.2):
# Get mean of the 3 colour channels
bmp = np.mean(img, axis=-1, dtype=np.float32)
sum_ = 0
max_ = np.amax(bmp)
final = np.zeros_like(img[...,0])
for i in range(img.shape[0]):
for j in range(img.shape[1]):
sum_ += bmp[i][j]
if sum_ >= coef * max_:
final[i][j] = 1
sum_ -= coef * max_
return final
时间从539ms下降到257ms。如果我随后通过在函数前添加装饰器来使用Numba:
@jit(parallel=True)
def metoImpulse(img, coef=1.2):
# Get mean of the 3 colour channels
bmp = np.mean(img, axis=-1, dtype=np.float32)
sum_ = 0
max_ = np.amax(bmp)
final = np.zeros_like(img[...,0])
for i in range(img.shape[0]):
for j in range(img.shape[1]):
sum_ += bmp[i][j]
if sum_ >= coef * max_:
final[i][j] = 1
sum_ -= coef * max_
return final
时间从257ms下降到1.11ms
输入图像:
输出图像:
第一个函数可以简单地编写为,并且应该比for循环更有效:
返回np.sum(axis=2)/3
。对于代码的第二部分,我想不出更好的方法,因为您似乎正在进行条件累积和。一般来说,为了高效的代码,您应该避免使用显式for循环,而使用numpy的函数。当然np.mean(axis=2)
可能会尝试numba
第二部分。您可以尝试使用带有一个计数器的平面img(img.flat())数组。并使用变量k=coef*max_uuout FOR。您还可以删除else final[i][j]=0
,因为它是用零初始化的。该代码不会生成任何形式的噪声,甚至不会生成随机数。看起来更像是一种抖动?
@jit(parallel=True)
def metoImpulse(img, coef=1.2):
# Get mean of the 3 colour channels
bmp = np.mean(img, axis=-1, dtype=np.float32)
sum_ = 0
max_ = np.amax(bmp)
final = np.zeros_like(img[...,0])
for i in range(img.shape[0]):
for j in range(img.shape[1]):
sum_ += bmp[i][j]
if sum_ >= coef * max_:
final[i][j] = 1
sum_ -= coef * max_
return final