Apply an operation on a sliding window in Matlab - matlab

I have an big image and I have to :
First, apply a function to every possible patch of the image, like a sliding window. This is actually very similar to convolution, which is supported in Matlab, but instead I need to calculate a "key value" (real) on each image patch (let's consider it a black box function). As suggested by the comments, perharps I can use the "blockproc" function
Then, I need to find n smallest key values and their respective positions, but the catch is that I have several overlapping windows with similarly low key values then sorting will preserve all of them in the list, which is undesirable. Instead I want to detect those overlapping windows and keep only the one with the lowest key value. You can say that I want to find not the n smallest key values but only the n local minima (not sure if this analogy is correct though) . I can't give the code because it is too long and complicated (face recognition using eigenfaces with +5 functions)

Step 1: apply nlfilter to the original image:
keyimg = nlfilter(img, windowsize, keyfun);
Step 2: apply im2col to keyimg and sort key values:
colimg = im2col(keyimg, windowsize, 'sliding');
minimg = sort(colimg, 1); % perhaps take only the first `k` rows

Related

Find minimum and maximum of a two variable function on fixed interval in Matlab, and plotting those points in the same graph with the function

I have this function below and I need to calculate the minimum and maximum of this function U, and also plotting the maximum and minimum value in 3D graph together with the function.
How can I write the code?
[x,y]=meshgrid(0:0.1:pi,0:0.1:2*pi);% x-theta,y-phi
a=90.7;b=36.2;c=12.9;
E=1.44;
U=-E.^2*(a.*sin(x).^2.*cos(y).^2+b.*sin(x).^2.*sin(y).^2+c.*cos(x).^2);
meshc(x,y,U)
xlabel('\theta')
ylabel('\Phi ')
zlabel('U')
I tired this way to find max but I don't know if i did it correct
max(U,[],1) %max row-wise
max(U,[],2) %max column-wise
and for the minimum it didn't work the same idea, also I didn't get the exact value of the maximum
As stated above, to simply find the maximum/minimum of your sampled function, use m = min(U(:)); M = max(U(:)). To be able to plot them, what you are missing are the coordinates that give you those values. For this, you will need the second output of the min/max functions, which gives you the index where the extreme happens.
A possible implementation (possibly not the best one) would be (might not work perfectly, I don't have matlab at hand):
[Ms,I] = max(U,[],1); %row-wise maximum and their indexes
[M,j] = max(Ms); %maximum among all rows and its index
Now i = I(j) is the location of the maximum. You can finally do plot3(x(i,j),y(i,j),U(i,j),'ro') to plot a big red circle in the maximums location, or whatever you like.
Note: I might have it backwards and it might be x(j,i), and so on. Just check. Of course you can do the same thing for min().
EDIT: I just remembered the ind2sub function , which solves all your problems. Following the syntax used above:
[M,ind] = max(U(:));
[i,j] = ind2sub(size(U),ind)
The rest holds the unchanged.
You can simply use something like
max(max(U))
this will find the maximum for your 2D matrix.
For the minimum you just have to replace max with min.

Find the connected component in matlab

Given a BW image that contains some connected components.
Then, given a single pixel P in the image. How to find which component that contains the pixel P? It is guaranteed that the pixel P is always on the white area in one of the connected components.
Currently, I use CC = bwconncomp(BW) than I iterate each component using 'for' loop. In the each component, I iterate the index pixel. For each pixels, I check whether the value equal to the (index of) pixel P or not. If I find it, I record the number of connected component.
However, it seems it is not efficient for this simple task. Any suggestion for improvement? Thank you very much in advance.
MATLAB provides multiple functions that implement connected-component in different ways.
In your example, I would suggest bwlabel.
http://www.mathworks.com/help/images/ref/bwlabel.html
[L, num] = bwlabel(imgBW) This will perform a full-image connected-component labeling on a black-and-white image.
After calling this function, the label value that pixel P belongs to can be read off the result matrix L, as in label_to_find = L(row, col) index. Simple as that.
To extract a mask image for that label, use logical(L == label_to_find).
If you use different software packages such as OpenCV you will be able to get better performance (efficiency in terms of cutting unnecessary or redundant computation), but in MATLAB the emphasis is on convenience and prototyping speed.

Detect signal jumps relative to local activity

In Matlab, is it possible to measure local variation of a signal across an entire signal without using for loops? I.e., can I implement the following:
window_length = <something>
for n = 1:(length_of_signal - window_length/2)
global_variance(n) = var(my_signal(1:window_length))
end
in a vectorized format?
If you have the image processing toolbox, you can use STDFILT:
global_std = stdfilt(my_signal(:),ones(window_length,1));
% square to get the variance
global_variance = global_std.^2;
You could create a 2D array where each row is shifted one w.r.t. to the row above, and with the number of rows equal to the window width; then computing the variance is trivial. This doesn't require any toolboxes. Not sure if it's much faster than the for loop though:
longSignal = repmat(mySignal(:), [1 window_length+1]);
longSignal = reshape(longSignal(1:((length_of_signal+1)*window_length)), [length_of_signal+1, window_length])';
global_variance = sum(longSignal.*longSignal, 2);
global_variance = global_variance(1:length_of_signal-window_length));
Note that the second column is shifted down by one relative to the one above - this means that when we have the blocks of data on which we want to operate in rows, so I take the transpose. After that, the sum operator will sum over the first dimension, which gives you a row vector with the results you want. However, there is a bit of wrapping of data going on, so we have to limit to the number of "good" values.
I don't have matlab handy right now (I'm at home), so I was unable to test the above - but I think the general idea should work. It's vectorized - I can't guarantee it's fast...
Check the "moving window standard deviation" function at Matlab Central. Your code would be:
movingstd(my_signal, window_length, 'forward').^2
There's also moving variance code, but it seems to be broken.
The idea is to use filter function.

Suppress kinks in a plot matlab

I have a csv file which contains data like below:[1st row is header]
Element,State,Time
Water,Solid,1
Water,Solid,2
Water,Solid,3
Water,Solid,4
Water,Solid,5
Water,Solid,2
Water,Solid,3
Water,Solid,4
Water,Solid,5
Water,Solid,6
Water,Solid,7
Water,Solid,8
Water,Solid,7
Water,Solid,6
Water,Solid,5
Water,Solid,4
Water,Solid,3
The similar pattern is repeated for State: "Solid" replaced with Liquid and Gas.
And moreover the Element "Water" can be replaced by some other element too.
Time as Integer's are in seconds (to simplify) but can be any real number.
Additionally there might by some comment line starting with # in between the file.
Problem Statement: I want to eliminate the first dip in Time values and smooth out using some quadratic or cubic or polynomial interpolation [please notice the first change from 5->2 --->8. I want to replace these numbers to intermediate values giving a gradual/smooth increase from 5--->8].
And I wish this to be done for all the combinations of Elements and States.
Is this possible through some sort of coding in Matlab etc ?
Any Pointers will be helpful !!
Thanks in advance :)
You can use the interp1 function for 1D-interpolation. The syntax is
yi = interp1(x,y,xi,method)
where x are your original coordinates, y are your original values, xi are the coordinates at which you want the values to be interpolated at and yi are the interpolated values. method can be 'spline' (cubic spline interpolation), 'pchip' (piece-wise Hermite), 'cubic' (cubic polynomial) and others (see the documentation for details).
You have alot of options here, it really depends on the nature of your data, but I would start of with a simple moving average (MA) filter (which replaces each data point with the average of the neighboring data points), and see were that takes me. It's easy to implement, and fine-tuning the MA-span a couple of times on some sample data is usually enough.
http://www.mathworks.se/help/curvefit/smoothing-data.html
I would not try to fit a polynomial to the entire data set unless I really needed to compress it, (but to do so you can use the polyfit function).

Difference between hist and imhist in matlab

What is the difference between hist and imhist functions in Matlab? I have a matrix of color levels values loaded from image with imread and need to count entropy value of the image using histogram.
When using imhist the resulting matrix contains zeros in all places except the last one (lower-right) which contains some high value number (few thousands or so).
Because that output seems to be wrong, I have tried to use hist instead of imhist and the resulting values are much better, the matrix is fulfilled with correct-looking values instead of zeros.
However, according to the docs, imhist should be better in this case and hist should give weird results..
Unfortunately I am not good at Matlab, so I can not provide you with better problem description. I can add some other information in the future, though.
So I will try to better explain my problem..I have an image, for which I should count entropy and few other values (how much bytes it will take to save that image,..). I wrote this function and it works pretty well
function [entropy, bytes_image, bytes_coding] = entropy_single_pixels(im)
im = double(im);
histg = hist(im);
histg(histg==0) = [];
nzhist = histg ./ numel(im);
entropy = -sum(nzhist.*log2(nzhist));
bytes_image = (entropy*(numel(im))/8);
bytes_coding = 2*numel(unique(im));
fprintf('ENTROPY_VALUE:%s\n',num2str(entropy));
fprintf('BYTES_IMAGE:%s\n',num2str(bytes_image));
fprintf('BYTES_CODING:%s\n',num2str(bytes_coding));
end
Then I have to count the same, but I have to make "pairs" from pixels which are below each other. So I have only half the rows and the same count of columns. I need to express every unique pixel pair as a different number, so I multiplied the first one by 1000 and added the second one to it... Subsequently I need to actually apply the same function as in the first example, but that is the time, when I am getting weird numbers from the imhist function. When using hist, it seems to be OK, but I really don't think that behavior is correct, so that must be my error somewhere. I actually understand pretty good, to what I want to do, or at least I hope so, but unfortunately Matlab makes all that kind of hard for me :)
hist- compute histogram(count number of occurance of each pixel) in color image.........
imhist- compute histogram in two dimensional image.
Use im2double instead of double if you want to use imhist. The imhist function expects double or single-precision data to be in the [0,1] data range, which is why you see everything in the last bin of the histogram.