I am using the skewness and kurtosis functions for image color Histogram in image retrieval system as a statistical color features then using these features to compare between two images to retrieve the similarity images....but I get 'NaN' value in some results which is causes an error in image retrieval process:
S=double(imread('im.jpg');
R=S(:,:,1)/64; R1=floor(R);
G=S(:,:,2)/64; G1=floor(G);
B=S(:,:,3)/64; B1=floor(B);
[rr cc c]=size(R1);
ImageHist = zeros(4,4,4);
for row = 1 :rr
for col = 1:cc
ImageHist(R1(row,col)+1, G1(row,col)+1,B1(row,col)+1 )= ImageHist(R1(row,col)+1, G1(row,col)+1,B1(row,col)+1)+1;
end
end
ImageHist = ImageHist/(rr*cc);
then I compute the Kurtosis as:
QKurColHis = kurtosis(ImageHist);
I make the same thing to second function (skewness)
It is suitable to use this function to the color histogram to extract color feature? then using it in image retrieval?
if it is OK, how can I correct this Error, how can I remove the NaN values from my mat.file?
I want to use these function as image features in matching between color images... any one please could help me to solve this problem?
I don't know how the builtin kurtosis function is working but it might be that you have to supply it a vector instead of 3D matrix as an input
kurtosis(ImageHist(:))
Apart from the NaN problem, kurtosis and skewness give you some info about statistical distribution of the data in ImageHist so they could be treated as some image features. But how good will they perform in image matching is hard to say.
Related
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);
function out = findWaldo(im, filter)
% convert image (and filter) to grayscale
im_input = im;
im = rgb2gray(im);
im = double(im);
filter = rgb2gray(filter);
filter = double(filter);
filter = filter/sqrt(sum(sum(filter.^2)));
out = normxcorr2(filter, im);
Question1: Why we first do rgb2gray on im and filter?
Question2: What does the last second line actually do? Namely,
filter = filter/sqrt(sum(sum(filter.^2)));
Question 1: Why apply rgb2gray first?
normxcorr2 standing for "Normalized 2-D cross-correlation" works on a 2D signal (see doc). A RGB image is a 3D signal: width x height x color (e.g. 1024 x 1024 x 3, 3 since it's three colors). That is why you flatten it first to one color channel. Applying the filter to the image on each color separately would be the alternative, but then you also need to process three correlations (average them or something...).
Question 2: What does filter = filter/sqrt(sum(sum(filter.^2)));do?
It squares the filter image, then sums over rows and columns (basically all squared gray values of the filters) to get a single number that the squareroot is applied to and then is used to divide all filter image values.
I'd say it is some sort of normalization to handle specific input signals, maybe an attempt to get values from 0 - 1. But since normalized cross correlation (normxcorr2) does normalization itself, this step is definitely not needed for it. Unless you don't do something other than cross correlation with the filter variable, I'd consider this an artifact that should be deleted.
General explanation of the function
This function receives two inputs: an image file and a template.
For example, the image file may be a large scene of findings Waldo game and the template can be a picture of Waldo himself.
The output is a matrix called 'out' with same size as the image file. s.t. each pixel holds a "matching results". The higher the value - the higher the chances that the patch centered around the pixel holds a similar pattern such as the template.
The maximal value should be on the pixel in which Waldo is.
Question 1
rgb2gray function receives an rgb image with 3 channels and transorm it into gray image.
It is done on im and on filter because normxcorr2 function only works with grayscale images.
Question 2
The last perform normalization of the pattern: it divides it by it's norm, thus changing it to 1. In fact, this line is not required and should be deleted. Normalization stage is already performed inside normxcorr2 function.
I want to get the first principal component for an image using the built-in function pca. How can I do that?
I have tried the following code:
[COEFF, SCORE] = pca(image);
SCORE(1:size(SCORE,1),:)=0;
reconstructed_image = SCORE / COEFF + repmat(mean(image,1),size(image,1), 1);
I=reshape(reconstructed_image,[256,256]);
figure
imshow(I,[0 255])
I only get the fist row of the image. Any idea how can I do that correctly?
You can't "PCA one image". What this did is not give you the first row, it used all rows as observations and your columns as parameters, like you'd usually set up your measurements. So it calculated the variance through all parameters, giving you a vector with the length being equal to your number of columns. You'd probably want more images to do this instead.
Please read the following answer of mine though before continuing, since I explain the main pitfalls of PCA in MATLAB there.
PCA in matlab selecting top n components
I couldn't find an answer for RGB image.
How can someone get a value of SD,mean and Entropy of RGB image using MATLAB?
From http://airccse.org/journal/ijdms/papers/4612ijdms05.pdf TABLE3, it seems he got one answer so did he get the average of the RGB values?
Really in need of any help.
After reading the paper, because you are dealing with colour images, you have three channels of information to access. This means that you could alter one of the channels for a colour image and it could still affect the information it's trying to portray. The author wasn't very clear on how they were obtaining just a single value to represent the overall mean and standard deviation. Quite frankly, because this paper was published in a no-name journal, I'm not surprised how they managed to get away with it. If this was attempted to be published in more well known journals (IEEE, ACM, etc.), this would probably be rejected outright due to that very ambiguity.
On how I interpret this procedure, averaging all three channels doesn't make sense because you want to capture the differences over all channels. Doing this averaging will smear that information and those differences get lost. Practically speaking, if you averaged all three channels, should one channel change its intensity by 1, and when you averaged the channels together, the reported average would be so small that it probably would not register as a meaningful difference.
In my opinion, what you should perhaps do is treat the entire RGB image as a 1D signal, then perform the mean, standard deviation and entropy of that image. As such, given an RGB image stored in image_rgb, you can unroll the entire image into a 1D array like so:
image_1D = double(image_rgb(:));
The double casting is important because you want to maintain floating point precision when calculating the mean and standard deviation. The images will probably be of an unsigned integer type, and so this casting must be done to maintain floating point precision. If you don't do this, you may have calculations that get saturated or clamped beyond the limits of that data type and you won't get the right answer. As such, you can calculate the mean, standard deviation and entropy like so:
m = mean(image_1D);
s = std(image_1D);
e = entropy(image_1D);
entropy is a function in MATLAB that calculates the entropy of images so you should be fine here. As noted by #CitizenInsane in his answer, entropy unrolls a grayscale image into a 1D vector and applies the Shannon definition of entropy on this 1D vector. In a similar token, you can do the same thing with a RGB image, but we have already unrolled the signal into a 1D vector anyway, and so the input into entropy will certainly be well suited for the unrolled RGB image.
I have no idea how the author actually did it. But what you could do, is to treat the image as a 1D-array of size WxHx3 and then simply calculate the mean and standard deviation.
Don't know if table 3 is obtain in the same way but at least looking at entropy routine in image toolbox of matlab, RGB values are vectorized to single vector:
I = imread('rgb'); % Read RGB values
I = I(:); % Vectorization of RGB values
p = imhist(I); % Histogram
p(p == 0) = []; % remove zero entries in p
p = p ./ numel(I); % normalize p so that sum(p) is one.
E = -sum(p.*log2(p));
I have successfully written the MATLAB code for finding the n-order hadamard matrix.
Then I found the transpose of that matrix.
Then I found the basis images,
e.g., A(1,3)th basis image = hadamard_matrix(:,1)*hadamard_matrix(:,2)'
But whenever I try to print it using imshow() function in matlab, it shows just a completely dark image for all the basis images.
So what is the correct approach to show such basis images in matlab ?
Thanks in advance!
The only reasonable explanation I can think of right now, is that your resulting matrix contains only of values smaller than, say, 0.05.
Instead of the default bounds 0 and 1, try other high/low values. For instance:
imshow(A,[min(min(A)) max(max(A))]);