0
votes

So what I need to do is to apply an operation like

(x(i,j)-min(x)) / max(x(i,j)-min(x))

which basically converts each pixel value such that the values range between 0 and 1.

First of all, I realised that Matlab saves our image(rows * col * colour) in a 3D matrix on using imread,

Image = imread('image.jpg')

So, a simple max operation on image doesn't give me the max value of pixel and I'm not quite sure what it returns(another multidimensional array?). So I tried using something like

max_pixel = max(max(max(Image)))

I thought it worked fine. Similarly I used min thrice. My logic was that I was getting the min pixel value across all 3 colour planes.

After performing the above scaling operation I got an image which seemed to have only 0 or 1 values and no value in between which doesn't seem right. Has it got something to do with integer/float rounding off?

image = imread('cat.jpg')
maxI = max(max(max(image)))
minI = min(min(min(image)))
new_image = ((I-minI)./max(I-minI))

This gives output of only 1s and 0s which doesn't seem correct.

The other approach I'm trying is working on all colour planes separately as done here. But is that the correct way to do it?

I could also loop through all pixels but I'm assuming that will be time taking. Very new to this, any help will be great.

2
It's unclear without an example, but seems like you want to use the dim argument to max/min, as described in the docs. Also I think the bottom of the fraction in your first equation should be (max(x)-min(x)), taking the max of (x-min(x)) will not normalise the data between 0 and 1. - Wolfie
@wolfie x(i,j)-min(x) will make the value of minimum pixel 0, and all others will have some value, say max of which is y, now dividing with max(x(i,j)-min(x)) means dividing with y so the max value of pixel becomes 1. Isn't it? And what kind of example should I provide? Do you mean the code? Thanks a lot. - momo
How is your image generated? If its RGB already, then its not a "data matrix", its a color representation of something. This means that its either 0-255, 0-1, or possibly wrongly generated. - Ander Biguri
@AnderBiguri so I read the image using imread..it gives output with values ranging from 0-255. also size(image) gives 375 500 3, which means it's RGB I think. When I use red = image(:,:,1) and then size(red) I get 375 500. - momo

2 Answers

2
votes

If you are not sure what a matlab functions returns or why, you should always do one of the following first:

Type help >functionName< or doc >functionName< in the command window, in your case: doc max. This will show you the essential must-know information of that specific function, such as what needs to be put in, and what will be output.

In the case of the max function, this yields the following results:

M = max(A) returns the maximum elements of an array.

If A is a vector, then max(A) returns the maximum of A.

If A is a matrix, then max(A) is a row vector containing the maximum value of each column.

If A is a multidimensional array, then max(A) operates along the first array dimension whose size does not equal 1, treating the elements as vectors. The size of this dimension becomes 1 while the sizes of all other dimensions remain the same. If A is an empty array whose first dimension has zero length, then max(A) returns an empty array with the same size as A

In other words, if you use max() on a matrix, it will output a vector that contains the maximum value of each column (the first non-singleton dimension). If you use max() on a matrix A of size m x n x 3, it will result in a matrix of maximum values of size 1 x n x 3. So this answers your question:

I'm not quite sure what it returns(another multidimensional array?)

Moving on:

I thought it worked fine. Similarly I used min thrice. My logic was that I was getting the min pixel value across all 3 colour planes.

This is correct. Alternatively, you can use max(A(:)) and min(A(:)), which is equivalent if you are just looking for the value.

And after performing the above operation I got an image which seemed to have only 0 or 1 values and no value in between which doesn't seem right. Has it got something to do with integer/float rounding off?

There is no way for us to know why this happens if you do not post a minimal, complete and verifiable example of your code. It could be that it is because your variables are of a certain type, or it could be because of an error in your calculations.

The other approach I'm trying is working on all colour planes separately as done here. But is that the correct way to do it?

This depends on what the intended end result is. Normalizing each colour (red, green, blue) seperately will result in a different result as compared to normalizing the values all at once (in 99% of cases, anyway).

1
votes

You have a uint8 RGB image.

Just convert it to a double image by

I=imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Cat_poster_1.jpg/1920px-Cat_poster_1.jpg')

I=double(I)./255;

alternatively

I=im2double(I); %does the scaling if needed

Read about image data types


What are you doing wrong?

If what you want todo is convert a RGB image to [0-1] range, you are approaching the problem badly, regardless of the correctness of your MATLAB code. Let me give you an example of why:

Say you have an image with 2 colors.

A dark red (20,0,0): enter image description here

A medium blue (0,0,128) enter image description here

Now you want this changed to [0-1]. How do you scale it? Your suggested approach is to make the value 128->1 and either 20->20/128 or 20->1 (not relevant). However when you do this, you are changing the color! you are making the medium blue to be intense blue (maximum B channel, enter image description here) and making R way way more intense (instead of 20/255, 20/128, double brightness! enter image description here). This is bad, as this is with simple colors, but with combined RGB values you may even change the color itsef, not only the intensity. Therefore, the only correct way to convert to [0-1] range is to assume your min and max are [0, 255].