From e10d4a731712b22cae56353ae5215b63d11c8e96 Mon Sep 17 00:00:00 2001
From: Elian Dib <elian.dib@inria.fr>
Date: Sat, 3 Aug 2019 11:38:58 +0200
Subject: [PATCH] Simplified rgb<--->ycbcr conversions

---
 rgb2ycbcr.m | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 ycbcr2rgb.m | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/rgb2ycbcr.m b/rgb2ycbcr.m
index 1c5a925..71c1bfe 100644
--- a/rgb2ycbcr.m
+++ b/rgb2ycbcr.m
@@ -1 +1,46 @@
-% Author :  Hadi Amirpour 
% email  :  hadi.amirpour@gmail.com
% Copyright(c) EmergIMG,
%              Universidade da Beira Interior

% script for RGB 444 to YCbCr 444 color space conversion in n bits
% Input: 
        % 1-rgb   ---> RGB image in double format
        % 2-n     ---> number of the bits, this number should be either 8 or 10

% Output: 
        % 1-ycbcr ---> YCbCr image in n bits
% Modified by Elian Dib (elian.dib@inria.fr) on October, 18th 2018

function [ycbcr] = rgb2ycbcr(rgb,n,fullRange,conv2int)

%  Recommendation ITU-R BT.709-6
M = [ 0.212600   0.715200  0.072200 ;
     -0.114572  -0.385428  0.500000 ;
      0.500000  -0.454153 -0.045847];
  
if (nargin < 2)
    if isinteger(rgb)
    [~,n] = utils.precision(class(rgb));
    else
        n = 0;
    end
end

if (nargin < 3)
    fullRange = true;
end

if (nargin < 4)
    if isinteger(rgb)
        conv2int = true;
    else
        conv2int = false;
    end
end

rgb = double(rgb)./double(2^n-1);

if fullRange
    offsetY = 0;
    scaleY = 255;
    offsetC = 128;
    scaleC = 255;
else
    offsetY = 16;
    scaleY = 219;    
    offsetC = 128;
    scaleC = 224;
end

ycbcr        = reshape(double(rgb), [], 3) * M';
ycbcr(:,1)   = (scaleY*ycbcr(:,1)   + offsetY)*2^(n-8);
ycbcr(:,2:3) = (scaleC*ycbcr(:,2:3) + offsetC)*2^(n-8);
ycbcr        = reshape(ycbcr, size(rgb));

if conv2int
    if(n<=8)
        ycbcr = uint8(ycbcr);
    elseif (n<=16)
        ycbcr = uint16(ycbcr);
    elseif (n<=32)
        ycbcr = uint32(ycbcr);
    elseif (n<=64)
        ycbcr = uint64(ycbcr);
    else
        print('invalid bit depth')
    end
end
end
\ No newline at end of file
+function img = rgb2ycbcr(img,n,fullRange,conv2int)
+%RGB2YCBCR Summary of this function goes here
+%   Detailed explanation goes here
+
+%  Recommendation ITU-R BT.709-6
+M = [ 0.212600   0.715200  0.072200 ;
+     -0.114572  -0.385428  0.500000 ;
+      0.500000  -0.454153 -0.045847];
+
+if (nargin < 2)
+    dr = diff(getrangefromclass(img));
+    n = log2(double(dr)+1);
+else
+    dr = double(2^n-1);
+end
+
+if (nargin < 3); fullRange = true; end
+if (nargin < 4); conv2int = isinteger(img); end
+
+if fullRange
+    scaleY = 255; offsetY = 0 ; scaleC = 255; offsetC = 128;
+else
+    scaleY = 219; offsetY = 16; scaleC = 224; offsetC = 128;
+end
+
+img        = double(img);
+img        = reshape( reshape( img,[],3 )*M' ,size(img));
+img(:,:,1) = (scaleY*img(:,:,1) + dr*offsetY)/255;
+img(:,:,2) = (scaleC*img(:,:,2) + dr*offsetC)/255;
+img(:,:,3) = (scaleC*img(:,:,3) + dr*offsetC)/255;
+
+if conv2int
+    if(n<=8)
+        img = uint8(img);
+    elseif (n<=16)
+        img = uint16(img);
+    elseif (n<=32)
+        img = uint32(img);
+    elseif (n<=64)
+        img = uint64(img);
+    else
+        print('invalid bit depth')
+    end
+end
+
+end
\ No newline at end of file
diff --git a/ycbcr2rgb.m b/ycbcr2rgb.m
index 6e08ab6..8e22c4b 100644
--- a/ycbcr2rgb.m
+++ b/ycbcr2rgb.m
@@ -1 +1,46 @@
-% Created by Elian Dib (elian.dib@inria.fr) on October, 18th 2018
function [rgb] = ycbcr2rgb(ycbcr,n,fullRange,conv2int)

%  Recommendation ITU-R BT.709-6
M = [ 1.000000   0.000000  1.574800 ;
      1.000000  -0.187350 -0.468130 ;
      1.000000   1.855630  0.000000];

if (nargin < 2)
    if isinteger(ycbcr)
    [~,n] = utils.precision(class(ycbcr));
    else
        n = 0;
    end
end

if (nargin < 3)
    fullRange = true;
end

if (nargin < 4)
    if isinteger(ycbcr)
        conv2int = true;
    else
        conv2int = false;
    end
end

if fullRange
    offsetY = 0;
    scaleY = 255;
    offsetC = 128;
    scaleC = 255;
else
    offsetY = 16;
    scaleY = 219;    
    offsetC = 128;
    scaleC = 224;
end

sz           = size(ycbcr);
ycbcr        = double(ycbcr);
ycbcr        = reshape(ycbcr, [], 3);
ycbcr(:,1)   = (ycbcr(:,1)  -offsetY*2^(n-8))/(scaleY*2^(n-8));
ycbcr(:,2:3) = (ycbcr(:,2:3)-offsetC*2^(n-8))/(scaleC*2^(n-8));
rgb          = ycbcr * M';
rgb          = reshape(rgb, sz);

if conv2int
    rgb = (2^n-1)*rgb;
    if(n<=8)
        rgb = uint8(rgb);
    elseif (n<=16)
        rgb = uint16(rgb);
    elseif (n<=32)
        rgb = uint32(rgb);
    elseif (n<=64)
        rgb = uint64(rgb);
    else
        print('invalid bit depth')
    end
end
end
\ No newline at end of file
+function img = ycbcr2rgb(img,n,fullRange,conv2int)
+%YCBCR2RGB Summary of this function goes here
+%   Detailed explanation goes here
+
+%  Recommendation ITU-R BT.709-6
+M = [ 1.000000   0.000000  1.574800 ;
+      1.000000  -0.187350 -0.468130 ;
+      1.000000   1.855630  0.000000];
+
+if (nargin < 2)
+    dr = diff(getrangefromclass(img));
+    n = log2(double(dr)+1);
+else
+    dr = double(2^n-1);
+end
+
+if (nargin < 3); fullRange = true; end
+if (nargin < 4); conv2int = isinteger(img); end
+
+if fullRange
+    scaleY = 255; offsetY = 0 ; scaleC = 255; offsetC = 128;
+else
+    scaleY = 219; offsetY = 16; scaleC = 224; offsetC = 128;
+end
+
+img        = double(img);
+img(:,:,1) = (255*img(:,:,1)-dr*offsetY)/scaleY;
+img(:,:,2) = (255*img(:,:,2)-dr*offsetC)/scaleC;
+img(:,:,3) = (255*img(:,:,3)-dr*offsetC)/scaleC;
+img          = reshape(reshape( img,[],3 )* M' ,size(img));
+
+if conv2int
+    if(n<=8)
+        img = uint8(img);
+    elseif (n<=16)
+        img = uint16(img);
+    elseif (n<=32)
+        img = uint32(img);
+    elseif (n<=64)
+        img = uint64(img);
+    else
+        print('invalid bit depth')
+    end
+end
+
+end
\ No newline at end of file
-- 
GitLab