How can I fasten the "histc" Matlab function - matlab

I need to fasten this part of my Matlab code :
double(sum(histc(windows, 0:1:255),2)')
It is applied on every pixel of a large image, it is for calculating the local histogram (within 'windows') so it is very quite consuming.
Do you have any suggestion to fasten the computing ?
Thanks a lot.

You can exploit the overlap between adjacent pixels. Lets say you us a window of size 3x3 and have calculated the histogram for a pixel I(x,y), then the histogram for pixel I(x+1,y) will contain 6 of the same pixels. So you need only subtract 3 values and add 3.
Your code looks wrong. histc returns bin counts and then you sum the counts which should always add up to the size of your window. Do you want to calculate the sum of pixel intensities within the window? Then you should just use the sum function directly.

Related

adaptive sliding window filter

I want to create an adaptive sliding window filter that operates on a sparse matrix (Image). I want to calculate an average of all pixels with non-zero values within a 9x9 window for each objective pixel with non zero value. I tried to do it using the following code
fun = #(x) mean(x(x~=0));
B = nlfilter(A,[9 9],fun);
A is the sparse image to be filtered. The code runs but returns a non zero value for elements that have a zero pixel value in the unfiltered sparse image. I also want to make sure that to calculate the average for an objective pixel, a minimum of 5 non-zero samples are present within the window. If this is not possible, I want to keep expanding the sliding window until this is fulfilled.
Any suggestions are greatly appreciated.

How to get any two minima of histogram values?

I'm trying to transform my original gray image to mapped gray image using grey-scale mapping function. I have no idea how to get any two minima correspond to the grey-scale range [a,b] of the original histogram so that I can use these values for the equations below to get the mapped gray image.
f(x,y)=0 if [0,a),
f(x,y)=(255/(a-b))-a for [a,b],
f(x,y)=255 if (b,255]
Thank you!
So essentially you want to scale the histogram of your image to range from 0 - 255. All you need is the max and the min. The easiest way to find them is
a = min(I(:));
b = max(I(:));
Also I suspect you middle equation should actually be
f(x,y)=(255/(a-b))*(f(x,y)-a) for [a,b]
however that would eliminate the need for your first two equations. So it's possible that a and b are not the extrema in your case but that you are actually trying to accentuate some range of intensities that sit in the middle of your images histogram (and essentially discard all information outside of that range). In this case you have not given us enough information to suggest values for either a or b.

Explaining corr2 function in Matlab

Can someone explain to me the correlation function corr2 in MATLAB? I know that it is for 2D comparing similarities of objects, but in the equation I have doubts what it is A and B (probably matrices for comparison), and also Amn and Bmn.
I'm not sure how MATLAB executes this function, because I have found in several cases that the correlation is not executed for the entire image (matrix) but instead it divides the image into blocks and then compares blocks of one picture with blocks of another picture.
In MATLAB's documentation, the corr2 equation is not put as referral point to the way the equation itself is calculated, like in other functions in MATLAB's documentation, such as referring to what book it is taken from and where it is explained.
The correlation coefficient is a number representing the similarity between 2 images in relation with their respective pixel intensity.
As you pointed out this function is used to calculate this coefficient:
Here A and B are the images you are comparing, whereas the subscript indices m and n refer to the pixel location in the image. Basically what Matab does is to compute, for every pixel location in both images, the difference between the intensity value at that pixel and the mean intensity of the whole image, denoted as a letter with a straightline over it.
As Kostya pointed out, typing edit corr2 in the command window will show you the code used by Matlab to compute the correlation coefficient. The formula is basically this:
a = a - mean2(a);
b = b - mean2(b);
r = sum(sum(a.*b))/sqrt(sum(sum(a.*a))*sum(sum(b.*b)));
where:
a is the input image and b is the image you wish to compare to a.
If we break down the formula, we see that a - mean2(a) and b-mean2(b) are the elements in the numerator of the above equation. mean2(a) is equivalent to mean(mean(a)) or mean(a(:)), that is the mean intensity of the whole image. This is only calculated once.
The 3rd line of code calculates the coefficient. Here sum(sum(a.*b)) calculates the double-sum present in the formula element-wise, that is considering each pixel location separately. Be aware that using sum(a) calculates the sum in every column individually, hence in order to get a single value you need to apply sum twice.
That's pretty much the same happening in the denominator, however calculations are performed on a-mean2(a)^2 and b-mean2(b)^2. You can see this a some kind of normalization process in which you consider the pixel intensity difference among each individual image.
As for your last comment, you can break down an image into small blocks and calculate the correlation coefficient on them; that might save some time for very large images but since everything is vectorized the calculation is quite fast. It might be useful in distributed processing I guess. Of course the correlation coefficient between 2 blocks of images is not necessarily identical to that of the whole image.
For the sake of curiosity you can look at this paper which highlights some caveats in using the correlation coefficient for image comparison.
Hope that makes things a bit clearer!

How to plot a probability density distribution graph in MATLAB?

I have about 10000 floating point data, and have read them into a single row matrix.
Now I would like to plot them and show their distribution, would there be some simple functions to do that?
plot() actually plots value with respect to data number...which is not what I want
bar() is similar to what I want, but actually I would like to lower the sample rate and merge neighbor bars which are close enough (e.g. one bar for 0.50-0.55, and one bar for 0.55-0.60, etc) instead of having one single bar for every single data sample.
would there be a function to calculate this distribution by dividing the range into small steps, and outputting the prob density in each step?
Thank you!
hist() would be best. It plots a histogram, with a lot of options which you can see by doc hist, or by checking the Matlab website. Options include a specified number of bins, or a range of bins. This will plot a histogram of 1000 normally random points, with 50 bins.
hist(randn(1000,1),50)

Determine the position and value of peak

I have a graph with five major peaks. I'd like to find the position and value of the first peak (the one furthest to the right). I have more than 100 different plots of this and the peak grows and shrinks in size in the various plots, and will need to use a for loop. I'm just stuck on determining the x and y values to a large number of significant figures using Matlab code.
Here's one of the many plots:
If you know for sure you're always gonna have 5 peaks I think the FileExchange function extrema will be very helpful, see here.
This will return you the maxima (and minima if needed) in descending order, so the first elements of output zmax and imax are respectively the maximal value and its index, their second elements are the second maximum value and its index and so on.
In the case if the peak you need is always the smallest of the five you'll just need zmax(5) and imax(5) to determine the 5th biggest maximum.
If you have access to Signal Processing Toolbox, findpeaks is the function you are looking for. It can be invoked using different options including number of peaks, which can be helpful when that information is available.