亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Numpy 中逐像素迭代兩個圖像(隨機條件)

在 Numpy 中逐像素迭代兩個圖像(隨機條件)

慕田峪4524236 2022-07-19 16:52:36
import randomdef 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這就是我想要達到的目標。我知道這個函數不使用矢量化,但我不知道在這種情況下如何擺脫循環。如果有像素值的條件,那將是微不足道的。但在這種情況下,索引或像素值沒有條件,我只需要保留像素值,或者根據隨機變量的值將其設置為 0 或 1。我如何矢量化它?
查看完整描述

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

----------------------------------------


查看完整回答
反對 回復 2022-07-19
?
慕運維8079593

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)

http://img1.sycdn.imooc.com//62d671060001479304040821.jpg

查看完整回答
反對 回復 2022-07-19
  • 2 回答
  • 0 關注
  • 75 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號