Borrar filtros
Borrar filtros

How to calculate the dynamic range of an RGB image

7 visualizaciones (últimos 30 días)
Avi Patani
Avi Patani el 5 de Mzo. de 2020
Editada: DGM el 28 de Nov. de 2022
This is the code I am using to cal. the DR of an RGB image, I divide the n*m*3 image into R,G,B components and go from there. I understand that the min value could be zero and I can set it take all the values >=2 (or 2 in case of a lower value).
But the code is doing something unexpected and I am not sure where I am going wrong.
Thank you
Avi
% Cal. the luminance value of the frame
I4 = 0.2126*R(:,:)+ 0.7152*G(:,:)+ 0.0722*B(:,:);
% Find the max and min value
Max = max(I4,[],'all');
Min = min(I4,[],'all');
% Cal the log2() values
LogMax = log2(Max);
LogMin = log2(Min);
DR = LogMax - LogMin;

Respuestas (1)

DGM
DGM el 27 de Nov. de 2022
The error occurs because you're trying to do everything with integer data.
% read an image
inpict = imread('peppers.png');
inpict = im2double(inpict); % cast to a non-integer class
% split channels
[R G B] = imsplit(inpict);
% Cal. the BT709 luma value of the frame
Y = 0.2126*R + 0.7152*G + 0.0722*B;
% Find the max and min value
ymax = max(Y,[],'all');
ymin = min(Y,[],'all');
% Cal the log2() values
LogMax = log2(ymax);
LogMin = log2(ymin);
% dynamic range of luma
DRy = LogMax - LogMin
DRy = 5.1004
  3 comentarios
Walter Roberson
Walter Roberson el 27 de Nov. de 2022
Except when calculating with int64 or uint64, calculations with the integer classes and the same class, or integer classes and scalar doubles, are carried out "as if" the values were converted to double, then the calculation was performed, and then the result is converted to the integer class.
That does not mean that the calculations are carried out in double: the model is just "as-if" they were.
The main time you notice this in uint8 is division:
uint8(1)/uint8(2)
ans = uint8 1
How can 1/2 evaluate to 1 ? It is because it is as-if you calculated uint8( double(uint8(1)) / double(uint8(2))) which is uint8(1/2) which is uint8(0.5)... and casting a fraction to uint8 rounds.
You get the same rounding with uint8 times a fraction,
uint8(1) * (3/2)
ans = uint8 2
which is uint8(3/2) which rounds to 2. But that tends to surprise people less than the fact that you get rounding with uint8 division.
DGM
DGM el 28 de Nov. de 2022
Editada: DGM el 28 de Nov. de 2022
I should mention that I have no idea if the actual DR calculations are correct. I doubt it. I don't know why you'd calculate from luma. I just jumped at the obvious error.
EDIT: eh.

Iniciar sesión para comentar.

Categorías

Más información sobre Images en Help Center y File Exchange.

Productos


Versión

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by