简体   繁体   中英

Adding noise to an image psychopy

I am trying to add noise to images in psychopy. I was using imread but do not appear able to read images in the format needed to add noise to individual pixels throughout the image. I'm hoping someone may have ideas of how I might be able to do this.

Specifically, my task presents stimuli to participants at their own perceptual threshold. I am using an adaptive staircasing procedure (the quest handler) to titrate between trials the amount of noise added to an image to reach this threshold. ie, the participant identifies the image correctly, the next image has more noise; they identify an image incorrectly, the next trial has less noise. We do this over repeated trials to get the amount of noise needed for participants to answer a certain percentage of trials correctly.

I'm trying to add an amount of noise at each trial equal to the percent of noise passed from the quest handler by altering individual pixels to add gaussian noise. I do not wish to alter the original image. I envision this working by reading the image in as a matrix of pixels, copying it, adding noise to pixels in that matrix, and presenting that new stimulus for that trial. The imread function I was using to read in my images does not appear able to do this - does anyone have any suggestions?

I have demonstrated how one can read an image with cv2 and apply varying levels of noise to it. The noise addition does not modify the original image. As @Michael MacAskill wrote in his comments, you can apply noise to an image with a single vector operation. In my answer, I create a Gaussian with mean 1 and the same shape as the image, and I multiply it against the image. The level of noise can be increased by increasing the standard deviation of the Gaussian noise distribution.

import cv2
import matplotlib.pyplot as plt
import numpy as np


def apply_noise(image, scale):
    """Return image with noise.

    Parameters
    ----------
    image : ndarray, image to which noise is applied.
    scale : positive float, standard deviation of Gaussian 
        noise distribution.
    """
    image = np.asarray(image)
    # Create a Gaussian noise array.
    noise = np.random.normal(loc=1.0, scale=scale, size=image.shape)
    # Apply the noise array.
    noisy = image * noise
    # Tranform to integer type.
    noisy = noisy.astype(np.int32)
    # Clip the values to RGB bounds.
    noisy = noisy.clip(0, 255)
    return noisy

I downloaded a sample image using

wget -qO "astronaut.jpg" https://live.staticflickr.com/8674/16504233985_9f1060624e_q_d.jpg

and here are sample results. The original image:

img = cv2.imread("astronaut.jpg")
# Transform from BGR to RGB
img = img[..., ::-1]
plt.imshow(img)

宇航员

The image with some noise applied:

img_a = apply_noise(image=img, scale=0.1)
plt.imshow(img_a)
plt.title("Gaussian std. dev. = 0.1")

应用了一些噪音的宇航员

The image with more noise applied:

img_b = apply_noise(image=img, scale=0.5)
plt.imshow(img_b)
plt.title("Gaussian std. dev. = 0.5")

应用更多噪音的宇航员

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM