Search code examples
arraysimagematlabmatlab-figureuint8t

what is this : uint8((double(weather1618) ./ maxv) .* 50);?


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?

enter image description here

If I was to do directly,

 image(weather1618);

I would only get a blue image.

enter image description here


Solution

  • 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. And maxv 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 multiplication
    • unit8 (function) - Convert to 8-bit unsigned integer

    What's going on:

    1. 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).
    2. ./ 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.
    3. .* 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.
    4. 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.
    

    image vs imagesc

    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.