could numpy.random.poisson be used to add poisson noise to images? - image

For every pixle of one image,I have its x(int),y(int) and pixel value(float number).
Now I need to add noise to the image.Is numpy.random.poisson appropriate?
I am worried about it because it is not like new pixle value=original value+noise,but like
new pixle value=numpy.random.poisson(original value,1) .And the new values are all integers.
My question is as the title.
My purpose is to get a photometry measurement error for a star.But I have only one iamge.So I do a simulation via adding poisson noise.
Please check the figure got from the ccd image below.The source is the red feature.

This is an old thread, but I know the answer to this, so here goes.
The answer is yes.
imageplusshotnoise = numpy.random.poisson(lam=<noiseless_simulated_image>, size=None)
This will produce a sample image from a Poisson distribution for each pixel of the original image. Poisson distributions have a special property where the mean and the variance are equal. This means that if the mean is say 100 counts that the variance will be 100; hence, the shot noise will have a standard deviation of 10 (variance is equal to the standard deviation squared).
Create a numpy image array with all the values equal to 100
>>> myimage = 100 * np.ones((100,100))
>>> np.mean(myimage)
100.0
>>> np.std(myimage)
0.0
Note that the mean is 100 and the standard deviation is 0 as expected
Now using this image as the lambda of a Poisson distribution will produce a sample from that distribution with the same size
>>> imageplusnoise = np.random.poisson(lam=myimage, size=None)
>>> imageplusnoise.shape
(100, 100)
The mean of the sample will have the same mean as the lambda, but the standard deviation will be equal to the sqrt of the variance, which in a Poisson distribution is equal to the mean.
>>> np.mean(imageplusnoise)
100.0474
>>> np.std(imageplusnoise)
10.015934965843179
To obtain only the shot noise, simple subtract lambda from it and now the mean will be close to zero (if the mean is small, the mean noise will start skewing further from zero), but it will always have the same standard deviation.
>>> noiseonlyimage = imageplusnoise - myimage
>>> np.mean(noiseonlyimage)
0.047399999999999998
>>> np.std(noiseonlyimage)
10.015934965843179
It should be pointed out here that the lam argument is the expectation value of the Poisson distribution and is noiseless. Your starting image looks like it already has noise, so I would start out by modeling the star response through your aperture to obtain the noiseless image say using some point spread function like an airy disk, sinc function or similar as the input to the numpy.random.poisson function.

Related

How to ignore certain values in A histogram? without using NaN in Matlab?

Say I have an grey scale image S and I'm looking to ignore all values above 250, how do I do it with out using NaN? the reason I don't want to use NaN is because Im looking to take statistical information from the resultant image such as average etc.
You can collect all image pixel intensities that are less than 250. That's effectively performing the same thing. If your image was stored in A, you can simply do:
pix = A(A < 250);
pix will be a single vector of all image pixels in A that have intensity of 249 or less. From there, you can perform whatever operations you want, such as the average, standard deviation, calculating the histogram of the above, etc.
Going with your post title, we can calculate the histogram of an image very easily using imhist that's part of the image processing toolbox, and so:
out = imhist(pix);
This will give you a 256 element vector where each value denotes the intensity count for a particular intensity. If we did this properly, you should only see bin counts up to intensity 249 (location 250 in the vector) and you should. If you don't have the image processing toolbox, you can repeat the same thing using histc and manually specifying the bin cutoffs to go from 0 up to 249:
out = histc(pix, 0:249);
The difference here is that we will get a histogram of exactly 250 bins whereas imhist will give you 256 bins by default. However, histc is soon to be deprecated and histcounts is what is recommended to use. Still the same syntax:
out = histcounts(pix, 0:249);
You can use logical indexing to build a histogram only using values in your specified range. For example you might do something like:
histogram(imgData(imgData < 250))

Calculate SNR in single image in MATLAB

I have this image:
I want to calculate SNR in it. For this i used code:
img=imread('noicy.JPG');
img=double(img(:));
ima=max(img(:));
imi=min(img(:));
ims=std(img(:));
snr=20*log10((ima-imi)./ims)
Is that correct code to calculate SNR?
The definition of SNR can be found here or here:
Both the standard and the industry definition can be used (10log(x) and 20log(x)). check this
now, the signal is equal to the mean of the pixel values (mean(img(:))) and the noise is the standard deviation or error value of the pixel values (std(img(:))).
You may use either the ratio or the SNR=10*log10(signal/noise) to express the result in decibel.

What is the base of the logarithm in Log Transformation in image processing?

I am reading gonzales image processing book and as you know the log transformation has been defined like the following in the book:
s = c*log(1+r)
Now I have one question:
Is the logarithm based on 10 or it is a natural logarithm which is based on napier number?
The log transform is used for dark pixels enhancement. The dark pixels in an image are expanded as compare to the higher pixel values. So the base can be any number depending on the visualization effect of image.
I think log10 is often used because it is related to the decibel scale in signal processing, such as what is used in signal to noise definition.
If this is log() from math.h, then it's the natural logarithm.
That is, it's base is e, which is approximately 2.71828.

Maximum frequency present in an image in MATLAB

I guess there are various forms of this question peresnt here in stackoverflow. But I was unable to understand how I can solve my problem.
I have an image and I want to find the frequency content of the image.
img = imread('test.tif');
img = rgb2gray(img);
[N M] = size(img);
%% Compute power spectrum
imgf = fftshift(fft2(img));
imgfp = (abs(imgf)/(N*M)).^2;
I know I have to use the fft for this purpose. But I was wondering if I can find the maximum frequency in the images in terms of a particular value, say 'x cycles/mm' or 'x cycles/inch'.
What would be the best way to do this?
Thank you.
The FFT returns data in an array, where each array element is somewhat related to cycles per total data width (or height, etc.). So you could divide each FFT bin number by the image size in some dimensional unit (say "inches") to get cycles per unit dimension (say cycles per inch).
Note that except for some very specific narrowly specified types of images (say, constant amplitude exactly aperture periodic sinusoidal gradients), any image content will get spattered across the entire frequency spectrum and range of the FFT result. So you will likely have to set some non-zero threshold for frequency content before you can limit your "maximum" frequency finding.

How to measure Peak signal to noise ratio of images?

I have the following images :
Corrupted with 30% salt and pepper noise
After denoising
I have denoised images with various techniques
How do i compare which method is the best in terms of denoising
function PSNR = PeakSignaltoNoiseRatio(origImg, distImg)
origImg = double(origImg);
distImg = double(distImg);
[M N] = size(origImg);
error = origImg - distImg;
MSE = sum(sum(error .* error)) / (M * N);
if(MSE > 0)
PSNR = 10*log(255*255/MSE) / log(10);
else
PSNR = 99;
end
which two images should i take to calculate the PSNR?
Did you check the Wikipedia article on PSNR? For one, it gives a cleaner formula that would fix up your code (for example, why are you checking whether MSE > 0? If you defined MSE right, it has to be greater than 0. Also, this looks to be Matlab code, so use the log10() function to save some confusing base conversions. Lastly, be sure that the input to this function is actually a quantized image on the 0-255 scale, and not a double-valued image between 0 and 1).
Your question is unclear. If you want to use PSNR as a metric for performance, then you should compute the PSNR of each denoised method against the original and report those numbers. That probably won't give a very good summary of which methods are doing better, but it's a start. Another method could be to hand-select smaller sub-regions of the original image that you think correspond to different qualitative phenomena, such as a window on the background, a window on the foreground, and a window spanning the two. Then compute the PSNR for only those windows, again repeated for each denoised result vs. the original. In the end, you want a table showing PSNR of each different method as compared to the original, possibly with this sub-window breakdown.
You may want to look into more sophisticated methods depending on what application this is for. The chapter on total variation image denoising in Tony Chan's book is very helpful ( link ).
Here is Jython/Python example using DataMelt program.
Put these lines into a file "test.py" and run inside the DataMelt.
It will print PSNR value for 2 downloaded images. Replace the files names if you have different images.
from Catalano.Imaging.Tools import ObjectiveFidelity
from Catalano.Imaging import FastBitmap
from jhplot import *
print Web.get("http://jwork.org/dmelt/examples/data/logo_jhepwork.png")
print Web.get("http://jwork.org/dmelt/examples/data/logo_jhepwork_noisy.png")
original=FastBitmap("logo_jhepwork.png")
original.toGrayscale()
reconstructed=FastBitmap("logo_jhepwork_noisy.png")
reconstructed.toGrayscale()
img=ObjectiveFidelity(original,reconstructed)
print "Peak signal-to-noise ratio (PSNR)=",img.getPSNR()

Resources