Calculate Expectation and Variance of Histogram in matlab - matlab

I want to compute the standard deviation and expected value of the given histogram.
Which matlab function will help me to do that?
My code:
I = imread('download.bmp');
imshow(I);title('Input Image');
imhist(I(:));title('Histogram of input image');

Not quite sure, whether I am getting your question properly.
By expected value of the histogram, do you mean the mean intensity value of the image, so basically which intensity you are most likely to draw if you draw a random pixel?
This you could simply get by doing
m_wholeImage = mean(I(:));
s_wholeImage = std(double(I(:)));
s_wholeImage then gives you the standard deviation of all pixel values.

I would suggest this reference :
Gonzalez., R., Eddins., S. and Woods, R. (2009). Digital image processing using MATLAB. 2nd ed. Gatesmark Publishing, pp.644-654.
It mentions code for quantifying texture in an image, and that involves finding mean and standard deviation of the image histogram.
I found the code online :
http://fourier.eng.hmc.edu/e161/dipum/statxture.m
http://fourier.eng.hmc.edu/e161/dipum/statmoments.m

Related

Lognormal curve fitting equation

I have run into a very peculiar problem. It might seem silly to a lot of you. But I am in dire need of a way out. I am analyzing sets of high-speed images with MATLAB. The image of interest (https://www.dropbox.com/s/h4h26y3mvpao8m6/sample.png?dl=0) is an average of 3000 images (background subtracted). As shown in the picture, I am reading the pixel intensities/values along columns. As this is a laser beam, the shape or beam profile away from the wall has the shape of a Gaussian distribution. As I approach to the wall (the brightest part at the right of the image) because of some effect the shape is turning into one like a log-normal distribution. In this spreadsheet (https://www.dropbox.com/s/yeim06a5cq3iqg8/sample.xlsx?dl=0) I have pasted the raw intensities as I read thru from point A to point B. The column D has the raw intensities and the column E has the values achieved with a 'sgolay' fit of the column D values. If I plot these it pretty much has the shape of a lognormal distribution. I can get the mu and sigma with the 'lognfit' or 'fitdist' functions. Now the question is what is the equation [expressed as a function of pixel location (x) or the pixel intensity (y)] of the fitted 'lognormal curve' that could be used to recreate the fitted curve? Your help is highly appreciated.
The lognfit extracts the mu and the sigma of the lognormal distribution. The mu is the mean of logarithmic values and sigma the standard deviation of logarithmic values. You can refer to https://en.wikipedia.org/wiki/Log-normal_distribution for the shape of the function given mu and sigma.
With logrnd(mu,sigma) you can generate samples from the same distribution:
https://it.mathworks.com/help/stats/lognrnd.html?searchHighlight=lognrnd&s_tid=srchtitle_lognrnd_1

How to calculate image histogram without normalizing data in Matlab

I have an image I which pixel intensities fall within the range of 0-1. I can calculate the image histogram by normalizing it but I found the curves is not exactly the same as the histogram of raw data. This will cause some issue for the later peaks finding process(See attached two images).
My question is in Matlab, is there any way I can plot the image histogram without normalization the data so that I can keep the curve shape unchanged? This will benefit for those raw images when their pixel intensities are not within 0-1 ranges. Currently, I cannot calculate their histogram if I don't normalize the data.
The Matlab code for normalization and histogram calculation is attached. Any suggestion will be appreciated!
h = imhist(mat2gray(I));
Documentation of imhist tells us that the function checks the data type of the input and scale the values accordingly. Therefore, without testing with your attached data, this may work:
h = imhist(uint8(I));
An alternatively you may scale the integer-representation to floating-representation, by either using argument of mat2gray
h = imhist(mat2gray(I, [0,255]));
or just divide it.
h = imhist(I/255);
The imhist answer in this thread describing normalizing or casting is completely correctly. Alternatively, you could use the histogram function in MATLAB which will work with unnormalized floating point data:
A = 255*rand(500,500);
histogram(A);

Implement slightly different kernel smoothing density in matlab

I've been trying to implement this equation into matlab:
http://www.mathworks.com/matlabcentral/answers/uploaded_files/46747/Capture.PNG
Omega is some known region of the image u1.
and p1,i is:
http://www.mathworks.com/matlabcentral/answers/uploaded_files/46748/Capture1.PNG
Pay attention: u1 is an image (column ordered), an p1,i is supposed to be calculated in each pixel of this image.
Now, I've calculated p1,i in this way:
[f1,xi1] = ksdensity(u1(:),1:255);
p1_u1 = reshape(f1(floor(u1(:))+1),M,N);
Now my problem is to calculate the former equation.
I've tried with for loop but its taking forever..
Any other suggestions? Maybe there's a way using ksdensity and change the value inside the integral?
Thanks!

adjust the gray level of an image according to its statistical distribution [duplicate]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Please explain as to what happens to an image when we use histeq function in MATLAB? A mathematical explanation would be really helpful.
Histogram equalization seeks to flatten your image histogram. Basically, it models the image as a probability density function (or in simpler terms, a histogram where you normalize each entry by the total number of pixels in the image) and tries to ensure that the probability for a pixel to take on a particular intensity is equiprobable (with equal probability).
The premise behind histogram equalization is for images that have poor contrast. Images that look like they're too dark, or if they're too washed out, or if they're too bright are good candidates for you to apply histogram equalization. If you plot the histogram, the spread of the pixels is limited to a very narrow range. By doing histogram equalization, the histogram will thus flatten and give you a better contrast image. The effect of this with the histogram is that it stretches the dynamic range of your histogram.
In terms of the mathematical definition, I won't bore you with the details and I would love to have some LaTeX to do it here, but it isn't supported. As such, I defer you to this link that explains it in more detail: http://www.math.uci.edu/icamp/courses/math77c/demos/hist_eq.pdf
However, the final equation that you get for performing histogram equalization is essentially a 1-to-1 mapping. For each pixel in your image, you extract its intensity, then run it through this function. It then gives you an output intensity to be placed in your output image.
Supposing that p_i is the probability that you would encounter a pixel with intensity i in your image (take the histogram bin count for pixel intensity i and divide by the total number of pixels in your image). Given that you have L intensities in your image, the output intensity at this location given the intensity of i is dictated as:
g_i = floor( (L-1) * sum_{n=0}^{i} p_i )
You add up all of the probabilities from pixel intensity 0, then 1, then 2, all the way up to intensity i. This is familiarly known as the Cumulative Distribution Function.
MATLAB essentially performs histogram equalization using this approach. However, if you want to implement this yourself, it's actually pretty simple. Assume that you have an input image im that is of an unsigned 8-bit integer type.
function [out] = hist_eq(im, L)
if (~exist(L, 'var'))
L = 256;
end
h = imhist(im) / numel(im);
cdf = cumsum(h);
out = (L-1)*cdf(double(im)+1);
out = uint8(out);
This function takes in an image that is assumed to be unsigned 8-bit integer. You can optionally specify the number of levels for the output. Usually, L = 256 for an 8-bit image and so if you omit the second parameter, L would be assumed as such. The first line computes the probabilities. The next line computes the Cumulative Distribution Function (CDF). The next two lines after compute input/output using histogram equalization, and then convert back to unsigned 8-bit integer. Note that the uint8 casting implicitly performs the floor operation for us. You'll need to take note that we have to add an offset of 1 when accessing the CDF. The reason why is because MATLAB starts indexing at 1, while the intensities in your image start at 0.
The MATLAB command histeq pretty much does the same thing, except that if you call histeq(im), it assumes that you have 32 intensities in your image. Therefore, you can override the histeq function by specifying an additional parameter that specifies how many intensity values are seen in the image just like what we did above. As such, you would do histeq(im, 256);. Calling this in MATLAB, and using the function I wrote above should give you identical results.
As a bit of an exercise, let's use an image that is part of the MATLAB distribution called pout.tif. Let's also show its histogram.
im = imread('pout.tif');
figure;
subplot(2,1,1);
imshow(im);
subplot(2,1,2);
imhist(im);
As you can see, the image has poor contrast because most of the intensity values fit in a narrow range. Histogram equalization will flatten the image and thus increase the contrast of the image. As such, try doing this:
out = histeq(im, 256); %//or you can use my function: out = hist_eq(im);
figure;
subplot(2,1,1);
imshow(out);
subplot(2,1,2);
imhist(out);
This is what we get:
As you can see the contrast is better. Darker pixels tend to move towards the darker end, while lighter pixels get pushed towards the lighter end. Successful result I think! Bear in mind that not all images will give you a good result when you try and do histogram equalization. Image processing is mostly a trial and error thing, and so you put a mishmash of different techniques together until you get a good result.
This should hopefully get you started. Good luck!

how to find standard deviation of noise in an image using matlab?

As a part of my project, initially find low resolution of the input image. Then as a second step i need find the noise in the low-resolution image. How to find noise in an image and its standard deviation using matlab?
You can use the std matlab function which returns the standard deviation of a matrix.
std_deviation = std(image);
This will give you the standard deviation of the whole image. However you cannot calculate the noise std since you don't have the original filtered image.
Possible solution: (Not accurate) : This suppose thaht your noise is gaussian
Well, you can render several Noise matrices and test them:
(choose your mean_vector and std_vector)
for i = 1 : length(mean_vector) % or length(std_vector)
Noise(:,:,i) = mean_vector(i) + std_vector(i).*randn(size(your_image))
% extracting the possibly filtered image
filtered_img(:,:,i) = your_image - Noise(:,:,i);
end
Then display every filtered_img and choose the one that looks the less noisy.
You can denoise the image, compute the difference between the raw image and the denoised version, and then compute the standard deviation of the difference.
For instance:
a=imread('input');
a=double(a);
b=imsharpen(a); %you may need to tune the parameters
diff=b-a;
noise=std2(diff);
You can find the variance of noise in the image assuming that you know the distribution. You will know this if you have read some of the great works in image denoising field by Donoho & John.
To find the noise std. dev. of noise in an image with Gaussian contamination (additive), you can use the Median Absolute Deviation (MAD) estimator on the derivative of the image using the following kernel:
I am writing the python code for this, you can easily write it in Matlab:
def find_stddevs(img):
k = np.asmatrix([[-1.0/9, -1.0/9 ,-1.0/9],
[-1.0/9, 8.0/9 , -1.0/9],
[-1.0/9, -1.0/9 ,-1.0/9]])
filtered = convolve(img,k,mode='reflect')
median_a = np.median(filtered)
stddev = np.median(np.absolute(filtered - median_a))/0.67449 #Gaussian noise assumption
return stddev
You can see the derivation and the logic Here on Wikipedia.
Again, most people think it can be done. This is true iff you do not have any prior about the type of contamination in the image.