Reputation: 37
This code (almost) does what I want but I don't understand how it can be that simple. So can someone, please, explain me how this code works?
FIY, weather1618 is a 384x384 array with a range from -76 to -30. And maxv has a value of -30.
mapped_array = uint8((double(weather1618) ./ maxv) .* 50);
image(mapped_array);
And why does .*50 .*100 give different images but .*100 .*500 .*1000 are identical?
If I was to do directly,
image(weather1618);
I would only get a blue image.
Upvotes: 0
Views: 94
Reputation: 2565
This code (almost) does what I want but I don't understand how it can be that simple. So can someone, please, explain me how this code works?
Please note that this kind of questions are generally not the best fit for Stack Overflow. However, since you have narrowed down the line of code that you don't understand, I will explain it to you.
You mentioned that:
FIY,
weather1618
is a 384x384 array with a range from -76 to -30. Andmaxv
has a value of -30.
The first line of code:
mapped_array = uint8((double(weather1618) ./ maxv) .* 50);
Invokes the following functions/operators:
double
(function) - Convert to double precision./
(operator) - Element-wise division.*
(operator) - Element-wise multiplicationunit8
(function) - Convert to 8-bit unsigned integerWhat's going on:
double(weather1618)
converts the weather1618
matrix to double-precision floating-point format, so the values of the matrix are now decimal numbers. In MATLAB, a double can represent numbers ranging from -1.79769e+308 to -2.22507e-308 for negative values and from 2.22507e-308 to 1.79769e+308 for positive values (source). The probable reason for doing this conversion is to avoid an integer division in step 2 (explained next)../ maxv
divides every element of the matrix by -30. This will flip the sign of every element of the matrix and will scale the data by a factor of 1/30. Since the matrix was converted to double in the previous step, the array obtained after the division will also be of type double, and it will contain decimal numbers..* 50
multiplies every element of the matrix by 50. This will scale the data by a factor of 50. The array obtained after the multiplication will continue to be of type double, as before.uint8(...)
converts the matrix from type double to type uint8 (unsigned integer), so the values of the matrix will now range from 0 to 255.The second line of code:
image(mapped_array);
Calls the image
function to display an image of the array obtained in step 4.
If I was to do directly,
image(weather1618);
I would only get a blue image.
Good discovery! The reason why you only see a blue image is because the image
function by default does not use the full range of colors in the colormap
, so even though the information is there in the image, it is not possible to distinguish it, because it is not being displayed using the full range of colors. On the other hand, the imagesc
function uses the full range of colors by default.
Have a look at this example I made:
img = rand(50); % Random image with values from 0 to 1.
subplot(1, 2, 1); % Left plot.
image(img); % Display image from array.
colorbar; % Colorbar showing color scale.
subplot(1, 2, 2); % Right plot.
imagesc(img); % Display image with scaled colors.
colorbar; % Colorbar showing color scale.
They are both the same image, but the color scaling is different (look at the colorbars).
And why does
.*50
and.*100
give different images but.*100
,.*500
and.*1000
are identical?
Because the maximum value that uint8
can store is 255, so any value greater than 255 will be truncated to 255. That's why multiplying by 100, 500 and 1000 makes no difference at all, as the values obtained all exceed 255.
Upvotes: 3