2 回答

TA貢獻1809條經驗 獲得超8個贊
您可以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()
圖像輸出具有可比性。對于一些400 x 400RGB 圖像,我得到以下時間:
Duration loop: 0.21099094100000004
Duration vectorized: 0.004011090000000106
希望有幫助!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
NumPy: 1.18.1
OpenCV: 4.1.2
----------------------------------------

TA貢獻1876條經驗 獲得超5個贊
不確定這是否會給出完全相同的結果——因為有可能(非常?。┠憧梢杂名}擊中一個像素,然后再用胡椒再次擊中相同的像素——但我嘗試了一種不同的方法。它還準確地生成一半鹽和一半胡椒,而其他解決方案往往只有在對大量樣本進行平均時才會這樣做。也許速度和內存節省值得不準確 - YMMV :-)
首先確定有多少像素會受到噪聲的影響,稱之為N。然后生成 N/2 對 [x,y] 坐標并將輸出圖像中的相應像素設置為黑色,然后生成另外 N/2 對 [x,y] 坐標并將它們設置為白色。
import numpy as np
def me(image,prob):
h, w = image.shape[:2]
# Number of noise affected pixels
N = int(w * h * prob)
# Half salt
image[np.random.randint(0,h,int(N/2)), np.random.randint(0,w,int(N/2))] = 255
# Half pepper
image[np.random.randint(0,h,int(N/2)), np.random.randint(0,w,int(N/2))] = 0
return image
# Make solid grey start image
image = np.full((400,400), 128, dtype=np.uint8)
和p=0.1,p=0.01我得到:
%timeit me(image,0.1)
296 μs ± 2.48 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit me(image,0.01)
42.2 μs ± 933 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
添加回答
舉報