noise reduction - matlab

I have an image with uniform intensity everywhere with gray value = 100 then i added additive zero-mean independent Gaussian noise with standard deviation = 5
I = ones(100,100)*100;
I_n=I+(5*randn(100,100));
I think that the mean and standard deviation of the pixel intensity in the noisy image will be 100 and 5 respectively,
then i want to reduce the noise in the noisy image by 2x2 averaging mask.
what is the effect of the averaging mask on the mean and standard deviation of the pixel intensity in the image?
is it better to increase the size of the mask?

for a uniform original image, and uniform noise, averaging won't change the mean. it will reduce the variation between pixels, but also make the noise between adjacent pixels correlated.
if you calculated the standard deviation then you would find that the value is 2.5 (reduced by a factor of 2, 2 = sqrt(4), where you averaged 4 values).
using a larger mask will reduce the noise further, but correlate it over more pixels. it will also blur more any structure in the underlying image (not an issue in this case, because it is uniform).

Standard averaging techniques will not work well in these situations. Just use a Wiener Filter if you have the autocorrelation matrices, else use Gaussian Process Regression with a suitable kernel matrix.

Related

Detecting noise presense on medical images

Noise can be different and it requires different techniques to remove it:
gaussian noise
speckle noise
salt noise
pepper noise
I've faced with noise samples which look like smth mean between gaussian and speckle noise.
It more looks like uniform speckle noise which evenly fills all the space on the image.
What Image Processing Toolbox function or general algorithm can be used to only detect the noise (not remove)? So that it can be measured on the piece of image.
I guess that it would be smth like pixel brightness density (how many bright pixels are presented on the image area) or brightness rarefaction (how much is average distance between bright pixels on the image part). But I think there is more robust way.
An example below is non-noise representation in scale.
As a hacky thing to try. First erode/dilate your image. Then subtract this processed image from the original image. Then use a sliding window and calculate a distribution of of intensities. This distribution might be a good proxy for the noise

What is the effect of mean and variance in Gaussian noise?

I = imread('us-currency.png');
mean = 0.5;
variance = 0.5;
J = imnoise(I,'gaussian', mean, variance);
imshow(J);
What are the effects of mean and variance on that image?
Does mean increases the brightness?
Does variance increases the amount of noise?
Input
Output
The mean and variance set which distribution the random values will taken from.
Once you add those numbers to an image you change the image properties as well.
If the image mean value is imageMeanVal, assuming the image is large, then after the addition of the random noise its mean value will be `imageMeanVal + noiseMeanVal' since the image and the noise are independent.
If you define the brightness of an image as its mean value then you're right, the mean value changes (Increase or decrease) the image brightness.
The same logic holds for the Variance / Standard Deviation.
Yet it is hard to say what's Variance of an image is.
Sometimes one could say it is the power of data in the image and the variance of the noise is the power of noise.
Hence if you increase the power of the added noise, if one looks on the power ration of the image to the noise, you decrease it and makes the data in the image harder to notice.
This is basically the SNR of the noised image.

How to make "well" a ridge-shape from a given 2d line? (gaussian, matlab)

My goal is to make a ridge(mountain)-like shape from the given line. For that purpose, I applied the gaussian filter to the given line. In this example below, one line is vertical and one has some slope. (here, background values are 0, line pixel values are 1.)
Given line:
Ridge shape:
When I applied gaussian filter, the peak heights are different. I guess this results from the rasterization problem. The image matrix itself is discrete integer space. The gaussian filter is actually not exactly circular (s by s matrix). Two lines also suffer from rasterization.
How can I get two same-peak-height nice-looking ridges(mountains)?
Is there more appropriate way to apply the filter?
Should I make a larger canvas(image matrix) and then reduce the canvas by interpolation? Is it a good way?
Moreover, I appreciate if you can suggest a way to make ridges with a certain peak height. When using gaussian filter, what we can do is deciding the size and sigma of the filter. Based on those parameters, the peak height varies.
For information, image matrix size is 250x250 here.
You can give a try to distance transform. Your image is a binary image (having only two type of values, 0 and 1). Therefore, you can generate similar effects with distance transform.
%Create an image similar to yours
img=false(250,250);
img(sub2ind(size(img),180:220,linspace(20,100,41)))=1;
img(1:200,150)=1;
%Distance transform
distImg=bwdist(img);
distImg(distImg>5)=0; %5 is set manually to achieve similar results to yours
distImg=5-distImg; %Get high values for the pixels inside the tube as shown
%in your figure
distImg(distImg==5)=0; %Making background pixels zero
%Plotting
surf(1:size(img,2),1:size(img,1),double(distImg));
To get images with certain peak height, you can change the threshold of 5 to a different value. If you set it to 10, you can get peaks with height equal to the next largest value present in the distance transform matrix. In case of 5 and 10, I found it to be around 3.5 and 8.
Again, if you want to be exact 5 and 10, then you may multiply the distance transform matrix with the normalization factor as follows.
normalizationFactor=(newValue-minValue)/(maxValue-minValue) %self-explanatory
Only disadvantage I see is, I don't get a smooth graph as you have. I tried with Gaussian filter too, but did not get a smooth graph.
My result:

Decomposing an image into two frequency components using DCT?

I am a beginner in digital image processing field, recently I am working on a project where I have to decompose an image into two frequency components namely (low and high) using DCT. I searched a lot on web and I found that MATLAB has a built-in function for Discrete Cosine Transform which is used like this:
dct_img = dct2(img);
where img is input image and dct_img is resultant DCT of img.
Question
My question is, "How can I decompose the dct_img into two frequency components namely low and high frequency components".
As you've mentioned, dct2 and idct2 will do most of the job for you. The question that remains is then: What is high frequency and what is low frequency content? The coefficients after the 2 dimensional transform will actually represent two frequencies each (one in x- and one in y-direction). The following figure shows the bases for each coefficient in an 8x8 discrete cosine transform:
Therefore, that question of low vs. high can be answered in different ways. A common way, which is also used in the JPEG encoding, proceeds diagonally from zero-frequency downto the max as shown above. As we can see in the following example that is mostly motivated because natural images are largely located in the "top left" corner of "low" frequencies. It is certainly worth looking at the result of dct2 and play around with the actual choice of your regions for high and low.
In the following I'm dividing the spectrum diagonally and also plotting the DCT coefficients - in logarithmic scale because otherwise we would just see one big peak around (1,1). In the example I'm cutting far above half of the coefficients (adjustable with cutoff) we can see that the high-frequency part ("HF") still contains some relevant image information. If you set cutoff to 0 or below only noise of small amplitude will be left.
%// Load an image
Orig = double(imread('rice.png'));
%// Transform
Orig_T = dct2(Orig);
%// Split between high- and low-frequency in the spectrum (*)
cutoff = round(0.5 * 256);
High_T = fliplr(tril(fliplr(Orig_T), cutoff));
Low_T = Orig_T - High_T;
%// Transform back
High = idct2(High_T);
Low = idct2(Low_T);
%// Plot results
figure, colormap gray
subplot(3,2,1), imagesc(Orig), title('Original'), axis square, colorbar
subplot(3,2,2), imagesc(log(abs(Orig_T))), title('log(DCT(Original))'), axis square, colorbar
subplot(3,2,3), imagesc(log(abs(Low_T))), title('log(DCT(LF))'), axis square, colorbar
subplot(3,2,4), imagesc(log(abs(High_T))), title('log(DCT(HF))'), axis square, colorbar
subplot(3,2,5), imagesc(Low), title('LF'), axis square, colorbar
subplot(3,2,6), imagesc(High), title('HF'), axis square, colorbar
(*) Note on tril: The lower triangle-function operates with respect to the mathematical diagonal from top-left to bottom-right, since I want the other diagonal I'm flipping left-right before and afterwards.
Also note that this kind of operations are not usually applied to entire images, but rather to blocks of e.g. 8x8. Have a look at blockproc and this article.
An easy example:
I2 = dct_img;
I2(8:end,8:end) = 0;
I3 = idct2(I2);
imagesc(I3)
I3 can be seen as the image after low pass filter (the low frequency components), then idct2(dct_img - I2) can be viewed as high frequency.

Variance and Mean of Image

I am calculating mean and variance of my original and stego image to compare them
I am using grayscale BMP image for comaprison
image=imread("image name")
M = mean(image(:))
V = var((image(:)))
Is this is correct way fo calculating mean/var in MATLAB? My Variance is getting more than mean..
Any help appreciated..
These are indeed the correct way to calculate the mean and variance over all the pixels of your image.
It is not impossible that your variance is larger than the mean as both are defined in the following way:
mean = sum(x)/length(x)
variance = sum((x - mean(x)).^2)/(length(x) - 1);
For example, if you generate noise from a standard normal distribution with randn(N,1), you will get N samples, and if you calculate the mean and variance, you will get approximately 0 and 1. So there as well, your variance may well be larger than the mean.
Both have a totally different meaning: the mean gives you an idea where your pixels are (i.e. are they white, black, 50% gray, ...). The mean will give you an idea of what pixel color to choose to summarize the color of the complete image. The variance gives you an idea how the pixel values are spread: e.g. if your mean pixel value is 50% gray, are most of the other pixels also 50% gray (small variance) or do you have 50 black pixels and 50 white pixels (large variance)? So you could also view it as a way to get an idea how well the mean summarizes the image (i.e. with zero variance, most of the information is captured by the mean).
edit: For the RMS value (Root Mean Square) of a signal, just do what the definition says. In most cases you want to remove the DC component (i.e. the mean) before calculating the RMS value.
edit 2: What I forgot to mention was: it also makes little sense to compare the numerical value of the variance with the mean from a physical point of view. The mean has the same dimension as your data (in case of pixels, think of intensity), while the variance has the dimension of your data squared (so intensity^2). The standard deviation (std in MATLAB), which is the square root of the variance on the other hand has the same dimension as the data, so there you could make some comparisons (it is another question whether you should do such comparison).
If you are workign with RGB image (H x W x 3), you have to calculate mean and variance separately for each channel. In this case the mean pixel will also be 3-values vector.
for ch = 1:3
M(ch) = mean(reshape(img(:,:,ch),[],1));
V(ch) = var(reshape(img(:,:,ch),[],1));
end
MATLAB has function image. Avoid using it as a variable.