Python 在Numpy中逐像素迭代两个图像(使用随机条件) 随机导入 def sp_噪声(图像,prob): ''' 在图像中添加椒盐噪声 问题:噪音的概率 ''' 输出=np.零(图像.形状,np.uint8) thres=1-概率 对于范围内的i(image.shape[0]): 对于范围内的j(image.shape[1]): rdn=random.random() 如果rdnthres: 输出[i][j]=255 其他: 输出[i][j]=图像[i][j] 返回输出

Python 在Numpy中逐像素迭代两个图像(使用随机条件) 随机导入 def sp_噪声(图像,prob): ''' 在图像中添加椒盐噪声 问题:噪音的概率 ''' 输出=np.零(图像.形状,np.uint8) thres=1-概率 对于范围内的i(image.shape[0]): 对于范围内的j(image.shape[1]): rdn=random.random() 如果rdnthres: 输出[i][j]=255 其他: 输出[i][j]=图像[i][j] 返回输出,python,numpy,image-processing,vectorization,Python,Numpy,Image Processing,Vectorization,这就是我想要实现的。我知道这个函数不使用矢量化,但我不知道在这种情况下如何摆脱循环。如果有像素值的条件,那将是微不足道的。但在这种情况下,索引或像素值没有条件,我只需要保留像素值,或者根据随机变量的值,将其设置为0或1 如何将其矢量化 您可以使用附加的size参数调用,以获得整个随机浮点数组。然后,使用和访问与其中一个条件匹配的所有像素 这就是我的解决方案,包括图像加载和显示以及一些简单的性能分析: 导入cv2 将numpy作为np导入 导入时间 def sp_噪声(图像,prob): 输出=n

这就是我想要实现的。我知道这个函数不使用矢量化,但我不知道在这种情况下如何摆脱循环。如果有像素值的条件,那将是微不足道的。但在这种情况下,索引或像素值没有条件,我只需要保留像素值,或者根据随机变量的值,将其设置为0或1

如何将其矢量化

您可以使用附加的
size
参数调用,以获得整个随机浮点数组。然后,使用和访问与其中一个条件匹配的所有像素

这就是我的解决方案,包括图像加载和显示以及一些简单的性能分析:

导入cv2
将numpy作为np导入
导入时间
def sp_噪声(图像,prob):
输出=np.0(image.shape,np.uint8)
thres=1-概率
对于范围内的i(image.shape[0]):
对于范围内的j(image.shape[1]):
rdn=np.random.random()
如果rdnthres:
输出[i][j]=255
其他:
输出[i][j]=图像[i][j]
返回输出
def sp_noise_vec(图像,prob):
输出=image.copy()
thres=1-概率
rdn=np.random.random(image.shape[:2])
输出[np.其中(rdnthres)]=255
返回输出
img=cv2.imread('path/to/your/image.png'))
tic=时间。性能计数器()
输出=sp_噪声(img,0.1)
toc=时间。性能计数器()
打印('持续时间循环:',toc-tic)
tic=时间。性能计数器()
out_vec=sp_噪声_vec(img,0.1)
toc=时间。性能计数器()
打印('持续时间矢量化:',toc-tic)
cv2.imshow(“img”,img)
cv2.imshow('out',out)
cv2.imshow(“输出向量”,输出向量)
cv2.等待键(0)
cv2.destroyAllWindows()
图像输出具有可比性。对于一些
400x400
RGB图像,我得到以下时间:

持续时间循环:0.210990941000004
向量化持续时间:0.004011090000106
希望有帮助

----------------------------------------
系统信息
----------------------------------------
平台:Windows-10-10.0.16299-SP0
Python:3.8.1
NumPy:1.18.1
OpenCV:4.1.2
----------------------------------------

不确定这是否会产生完全相同的结果-因为有一种可能性(非常小),你可以用盐击中一个像素,然后再用胡椒再次击中同一个像素-但我尝试了不同的方法。它还能产生半盐半胡椒,其他溶液只有在对大量样本进行平均时才会产生。也许节省的速度和内存值得不精确性—YMMV:-)

首先确定有多少像素将受到噪声的影响,称之为
N
。然后生成N/2对[x,y]坐标并将输出图像中的对应像素设置为黑色,然后生成另一N/2对[x,y]坐标并将其设置为白色

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
使用
p=0.1
p=0.01
,我得到:

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)


请不要使用numpy数组进行迭代。@WillemVanOnsem,我知道这是灾难性的。我只是不知道如何避免在这里迭代。试试“numpy.ndenumerate”。例如:通常情况下,你只需要在相对较少的像素上添加盐和胡椒粉,这样你就可以计算出你想要影响多少像素(用宽度乘以高度的概率),并反复多次为每个像素生成一个随机[x,y]位置,然后在该位置向原始图像添加盐或胡椒粉,具体取决于另一个随机数是否大于或小于0.5。谢谢您的回答。不应该
image[np.random.randint(0,h,int(N/2)),np.random.randint(0,w,int(N/2))]=255
be
image[np.random.random.randint(0,w,int(N/2)),np.random.random.randint(0,h,int(N/2))=255
。在Numpy中首先给出垂直轴。通过制作20x800图像进行检查,如果它们的方式不正确,它将很快出错并堆死:-)它不适用于我的形状图像(3721412),因此我得出结论,应该颠倒顺序。你能在一张有形状的图片上测试一下吗,比如说,(100400)?哦!对不起,你是对的,应该是
h,w=image.shape[:2]
我已经更正了我的答案。
%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)