image Normalization, image Range and image Scaling for different stack of images
I am so confused with image Normalization, and image Range, and image Scaling. I am using an algorithm (I have upload the algorithm in my Previous Question), and after applying the algorithm I am using this formula from wikipedia to normalize the images:
using getrangefromclass(filtImag1{i})
from MATLAB, the range of matrices before applying the algorithm is [0 255] and after applying the algorithm the range is [0 1].
the problem is I need to find a reference to find out if the normalization formula is correct or not? also I have 5 stacks of images each containing 600 images. I have applied the algorithm for each stack, and because the result of algorithm is 10 images for each stack, I will end up with 50 images that I need to analysis and compare them together. I find the max and the min of the 50 images , and then pass each image into the formula to normalize the image.
although the range of the images is [0 1] but the max of the image is : max = 3.6714e+004
why? shouldn't it be 1? is this the right way of normalization? how can I apply scaling ? do I need to do it?
here is the normalization code :
%%%%%%%%%%%%%%Find Min and Max between the results%%%%%%%%%%%%%%%%%%%%%%%
pre_max = max(filtImag1{1}(:));
for i=1:10
new_max = max(filtImag1{i}(:));
if (pre_max<new_max)
pre_max=max(filtImag1{i}(:));
end
end
new_max = pre_max;
pre_min = min(filtImag1{1}(:));
for i=1:10
new_min = min(filtImag1{i}(:));
if (pre_min>new_min)
pre_min = min(filtImag1{i}(:));
end
end
new_min = pre_min;
%%%%%%%%%%%%%%normalization %%%%%%%%%%%%%%%%%%%%%%%
for i=1:10
temp_imag = filtImag1{i}(:,:);
x=isnan(temp_imag);
temp_imag(x)=0;
t_max = max(max(temp_imag));
t_min = min(min(temp_imag));
temp_imag = (double(temp_imag-t_min)).*((double(new_max)-double(new_min))/double(t_max-t_min))+(double(new_min));
imag_test2{i}(:,:) = temp_imag;
end
EDIT I have change the code based on suggested answers but the result is black image
%find the max and min between them pre_max = max(sTStack{1}(:)); for i=1:40 newMax = max(sTStack{i}(:)); if (pre_max
pre_min = min(sTStack{1}(:)); for i=1:40 newMin = min(sTStack{i}(:)); if (pre_min>newMin) pre_min = min(sTStack{i}(:)); end end t_min = pre_min;
%%%%%%%%%%%%%%%%%%%%%%% Normalize the Image:%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:40 NTstack{i} = (sTStack{i} - t_min)/(t_max-t_min); end
for i=10:10:40 figure,imshow(NTstack{i}); colorbar colormap jet end
The Wikipedia snippet you provide is correct and can be used to normalize an image using the following MATLAB code:
%% Create an Example Image:
rand('seed', 1982);
n = 16;
myImg= rand(n,n)*.2 + .5;
%% Normalize the Image:
myRange = getrangefromclass(myImg(1));
newMax = myRange(2);
newMin = myRange(1);
myImgNorm = (myImg - min(myImg(:)))*(newMax - newMin)/(max(myImg(:)) - min(myImg(:))) + newMin;
The problem with some images is that although they only occupy a small range of possible values. If your values can range between 0 and 1 then black would be 0 and white would be 1. However, if your darkest spot in the image is .5 and your brightest is .7 then it might look washed out to your processing or to the user when is is visualized (note that MATLAB's imagesc automatically normlizes the image before display for this very reason).
If you look at the histogram of the image using hist(myImg(:)) you can tell how must of the allowed values the image is actually using. In a normalized image, the smallest value will be 0 and the largest will be 1 (or whatever range you use).
A common error in implementing this equation is to not properly place your parenthesis, not subtract off the min of your image before scaling, or not adding back in "newMin".
You can see everything together in the following code and image. Note how the original image (1) uses only a small portion of the space (2), so it looks washed out when we don't let imagesc autoscale the clim parameter. Once we normalize (3), however, the image has both very dark and very light values and the histogram stretches all the way from 0 to 1 (4). While it's not exactly clear what your code is or isn't doing, comparing it to this example should solve your problem.
%% Create an Example Image:
rand('seed', 1982);
n = 16;
myImg= rand(n,n)*.2 + .5;
%% Normalize the Image:
myRange = getrangefromclass(myImg(1));
newMax = myRange(2);
newMin = myRange(1);
myImgNorm = (myImg - min(myImg(:)))*(newMax - newMin)/(max(myImg(:)) - min(myImg(:))) + newMin;
%% Display the Image:
figure(42);
clf;
% Display the original:
subplot(2,2,1);
imagesc(myImg);
set(gca, 'clim', [0,1]);;
title('(1) Original Image');
% Display the hist of the original:
subplot(2,2,3);
hist(myImg(:))
xlim([0,1]);
title('(2) Histogram Of Original Image');
% Display the normalized image:
subplot(2,2,2);
imagesc(myImgNorm);
title('(3) Normalized Image');
% Display the hist of the normalized image:
subplot(2,2,4);
hist(myImgNorm(:))
title('(4) Histogram of Normalized Image');
xlim([0,1]);
colormap gray
EDIT:
Additionally, there are some important points to notes to make on how getrangefromclass(...) will work on your problem. This function returns the "default display range of image based on its class"---that is, it returns what MATLAB believes is a reasonable range of values is for that data type to represent a picture. For uint8 data, this is [0, 255]. For int16 this is [-32768, 32767]. For your case, double, the range is [0, 1] not because that's the minimum and maximum value but because that is conventional and double data types have a special representation that make this range quite reasonable. Note that is range has nothing to do with what your data actually is. If you have data is small or larger than the min and max will be quite different than what MATLAB thinks is good for pictures. In the case of double or single your value could be much larger. To normalize the values to between [0, 1] we can use the code we have been discussing.
In this case we create a random image that has big positive and negative values, but we will scale them all to be between zero and one. That is, we make the darkest color 0 and the lighted color 1---whereas before the smallest was negative thousands and the largest was positive thousands. However, note how the histogram shape stays the same while the x-axis values change to 0,1. This should demonstrate why the MATLAB range is [0,1] but your min/max is different----that is fine and your normalization code will fix everything between zero and one.
randn('seed', 1982);
myImg = randn(n,n)*1000;
% Normalize the Image:
myRange = getrangefromclass(myImg(1));
newMax = myRange(2);
newMin = myRange(1);
myImgNorm = (myImg - min(myImg(:)))*(newMax - newMin)/(max(myImg(:)) - min(myImg(:))) + newMin;
% Display the Image:
figure(42);
clf;
% Display the original:
subplot(2,2,1);
imagesc(myImg);
% set(gca, 'clim', [0,1]);;
title('(1) Original Image');
colorbar
% Display the hist of the original:
subplot(2,2,3);
hist(myImg(:))
title('(2) Histogram Of Original Image');
axis tight;
% Display the normalized image:
subplot(2,2,2);
imagesc(myImgNorm);
title('(3) Normalized Image');
colorbar
% Display the hist of the normalized image:
subplot(2,2,4);
hist(myImgNorm(:))
title('(4) Histogram of Normalized Image');
axis tight;
colormap gray
Having answered your previous question, I think I understand your confusion.
First of all, the input images were of type uint8
(thus the range [0,255]), and since we needed to perform processing on the signals (Butterworth filtering), it was necessary to convert to double
data type to avoid having the values being truncated.
Now at the end of the processing, the resulting "images" were of type double
but have arbitrary ranges (they represented average energy in signals). Now if we want to display those images or even perform image-processing on them (you were attempting to apply medfilt2
in your original code), MATLAB expects images of type double
to be in the [0,1] range.
The formula I used in the code and the one you just provided are compatible, its just that I am normalizing to the range of [0,1], thus newMax = 1
and newMin = 0
and the equation end up simply as I described it before:
img = ( img - min(img(:)) ) ./ ( max(img(:)) - min(img(:)) );
Just remember that you should be normalizing each image on its own, ie compute the min/max in the formula for the image itself, not from the entire group of images. If you look back at the solution I proposed, the images were stored in a cell array, and the computation was done using CELLFUN to get min/max of each image separately:
Tf = cellfun(@(x)reshape((x-min(x))./range(x),sz), Tf, 'Uniform',false);
obviously the signals were stored as linearized vectors (each in a cell), thus we normalized each to [0,1] range, then we reshaped it into a proper image matrix.
Now if you like to go back to uint8
images after that, a simple call to im2uint8
would suffice.
I should add that the type of linear transformation we performed above is called min/max normalization, but it's certainly not the only kind (see this answer for other examples). One might also look into other contrast-enhancement techniques (think histogram equalization and the like)
I usually use mat2gray
from the image processing toolbox for these purposes: mat2gray. I applies exactly the same linear interpolation that you refer to above. Internally it calls imlincomb.
The problem you are refering to, makes me believe that you have somehow implemented the above equation wrongly.
链接地址: http://www.djcxy.com/p/79616.html上一篇: 迷宫解决约束