Image Normalization, image Range and image Scaling for different still images

I am so confused with image normalization, as well as image range and image scaling. I use the algorithm (I loaded the algorithm in my Previous question ), and after applying the algorithm, I use this formula from wikipedia to normalize the images:

enter image description here

using getrangefromclass(filtImag1{i}) from MATLAB, the matrix range before applying the algorithm is [0 255], and after applying the algorithm the range is [0 1].

The problem is that I need to find the link to find out if the normalization of the formula is correct or not? I also have 5 stacks of images, each of which contains 600 images. I applied an algorithm for each stack, and since the result of the algorithm is 10 images for each stack, I get 50 images that I need to analyze and compare them with each other. I find max and min from 50 images, and then pass each image to a formula to normalize the image.

although the image range is [0 1], but the maximum image size: max = 3.6714e + 004

why? shouldn't be 1? Is this the right way to normalize? How can I apply scaling? do i need to do this?

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 changed the code based on the suggested answers, but the result was a black image

% find 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}); color bar colormap jet end

+6
source share
3 answers

The Wikipedia snippet you provide is correct and can be used to normalize the 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 occupy only a small range of possible values. If your values โ€‹โ€‹can range from 0 to 1, then black will be 0 and white will be 1. However, if your darkest spot in the image is 0.5 and your brightest is 7, then it may look blurry for your processing or user when is rendered (note that MATLAB imagesc automatically normalizes the image before displaying for this very reason).

If you look at the histogram of the image using hist (myImg (:)), you can determine how the valid values โ€‹โ€‹that the image actually uses should be. In a normalized image, the smallest value will be 0, and the largest will be 1 (or any other range that you use).

A common mistake in implementing this equation is the incorrect placement of brackets, rather than subtracting the minimum image before scaling or adding back to "newMin".

You can see everything together in the following code and image. Please note that the original image (1) uses only a small part of the space (2), so it looks blurry when we do not allow the images to autoscale the clearance parameter. However, as soon as we normalize (3), the image has both very dark and very light values, and the histogram extends from 0 to 1 (4). Although it is not entirely clear what your code does or does not do, comparing it with 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 

enter image description here

EDIT:

In addition, there are some important points for taking notes on how getrangefromclass (...) will work on your problem. This function returns the "default display range of the image based on its class", that is, returns what, according to MATLAB, is a reasonable range of values โ€‹โ€‹for this data type to represent the image. For uint8 data, this is [0, 255]. For int16, this is [-32768, 32767]. For your case, double, the range [0, 1] is not because the minimum and maximum values, but because it is a regular and double data type, have a special representation that makes this range quite reasonable. Note that the range has nothing to do with your data. If you have data small or large than min and max, it will not be at all what MATLAB thinks, it is good for photographs. In the case of a double or single value, the value can be much larger. To normalize the values โ€‹โ€‹between [0, 1], we can use the code that we discussed.

In this case, we create a random image with large positive and negative values, but we will scale them all between zero and one. That is, we make the darkest color 0 and the lighted color 1 --- whereas the smallest were negative thousands, and the largest were positive thousands. However, pay attention to how the shape of the histogram remains unchanged, and the values โ€‹โ€‹along the x axis change by 0.1. This should demonstrate why the MATLAB range is [0,1], but your min / max is different - that's 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 

enter image description here

+7
source

Answering your previous question, I think I understand your confusion.

First of all, the input images were of the uint8 type (thus, the range [0.255]), and since we needed to perform signal processing (Butterworth filtering), it was necessary to convert to double data to avoid truncating the values.

Now, at the end of processing, the resulting โ€œimagesโ€ were of type double , but had arbitrary ranges (they represented the average energy in the signals). Now, if we want to display these images or even perform image processing on them (you tried to use medfilt2 in your source code), MATLAB expects double images to be in the range [0,1].

The formula that I used in the code and the one you just provided are compatible, I just normalize to the range [0,1], so newMax = 1 and newMin = 0 , and the equation ends just as I described it before:

  img = ( img - min(img(:)) ) ./ ( max(img(:)) - min(img(:)) ); 

Just remember that you must normalize each image yourself, that is, calculate min / max in the formula for the image itself, and not from the entire group of images. If you look back at the solution I proposed, the images were saved in an array of cells, and the calculation was performed using CELLFUN to get the min / max of each image separately:

 Tf = cellfun(@(x)reshape((x-min(x))./range(x),sz), Tf, 'Uniform',false); 

it is obvious that the signals were stored as linearized vectors (each in a cell), so we normalized each to the range [0,1], then we converted it to the correct image matrix.

Now, if you like to return to uint8 images after that, a simple call to im2uint8 .

I must add that the type of linear transformation that we performed above is called the min / max norm, but this, of course, is not the only one (see this answer for other examples). You can also look at other methods to increase contrast (think about equalizing the histogram and )

+3
source

I usually use mat2gray from image processing tools for this purpose: mat2gray . I use exactly the same linear interpolation you are talking about above. Inside, it calls imlincomb .

The problem you are talking about makes me believe that you somehow introduced the above equation.

+2
source

Source: https://habr.com/ru/post/918879/


All Articles