Don*_*per 2 python numpy image-processing vectorization
import random
def sp_noise(image,prob):
'''
Add salt and pepper noise to image
prob: Probability of the noise
'''
output = np.zeros(image.shape,np.uint8)
thres = 1 - prob
for i in range(image.shape[0]):
for j in range(image.shape[1]):
rdn = random.random()
if rdn < prob:
output[i][j] = 0
elif rdn > thres:
output[i][j] = 255
else:
output[i][j] = image[i][j]
return output
Run Code Online (Sandbox Code Playgroud)
这就是我想要达到的目标。我知道此函数不使用矢量化,但我不知道在这种情况下如何摆脱循环。如果有像素值的条件,那将是微不足道的。但在这种情况下,索引或像素值没有条件,我只需要保留像素值,或者根据随机变量的值将其设置为 0 或 1。
我如何矢量化?
您可以np.random.random使用附加size参数调用以获取整个随机浮点数组。然后,使用np.where和布尔数组索引访问的所有的像素的匹配条件之一。
那将是我的解决方案,包括用于图像加载和显示的OpenCV以及一些简单的性能分析:
import cv2
import numpy as np
import time
def sp_noise(image, prob):
output = np.zeros(image.shape, np.uint8)
thres = 1 - prob
for i in range(image.shape[0]):
for j in range(image.shape[1]):
rdn = np.random.random()
if rdn < prob:
output[i][j] = 0
elif rdn > thres:
output[i][j] = 255
else:
output[i][j] = image[i][j]
return output
def sp_noise_vec(image, prob):
output = image.copy()
thres = 1 - prob
rdn = np.random.random(image.shape[:2])
output[np.where(rdn < prob)] = 0
output[np.where(rdn > thres)] = 255
return output
img = cv2.imread('path/to/your/image.png')
tic = time.perf_counter()
out = sp_noise(img, 0.1)
toc = time.perf_counter()
print('Duration loop: ', toc - tic)
tic = time.perf_counter()
out_vec = sp_noise_vec(img, 0.1)
toc = time.perf_counter()
print('Duration vectorized: ', toc - tic)
cv2.imshow('img', img)
cv2.imshow('out', out)
cv2.imshow('out_vec', out_vec)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)
图像输出具有可比性。对于一些400 x 400RGB 图像,我得到以下时间:
Duration loop: 0.21099094100000004
Duration vectorized: 0.004011090000000106
Run Code Online (Sandbox Code Playgroud)
希望有帮助!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
NumPy: 1.18.1
OpenCV: 4.1.2
----------------------------------------
Run Code Online (Sandbox Code Playgroud)