<p>您可以使用附加的<code>size</code>参数调用<a href="https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.random.html" rel="noreferrer">^{<cd1>}</a>,以获得整个随机浮点数组。然后,使用<a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html" rel="noreferrer">^{<cd3>}</a>和<a href="https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#boolean-array-indexing" rel="noreferrer">boolean array indexing</a>访问与其中一个条件匹配的所有像素</p>
<p>这就是我的解决方案,包括<a href="https://www.opencv.org" rel="noreferrer">OpenCV</a>图像加载和显示以及一些简单的性能分析:</p>
<pre class="lang-py prettyprint-override"><code>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()
</code></pre>
<p>图像输出具有可比性。对于某些<code>400 x 400</code>RGB图像,我得到以下时间:</p>
<pre class="lang-none prettyprint-override"><code>Duration loop: 0.21099094100000004
Duration vectorized: 0.004011090000000106
</code></pre>
<p>希望有帮助</p>
<pre class="lang-none prettyprint-override"><code>
System information
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
NumPy: 1.18.1
OpenCV: 4.1.2
</code></pre>