JeVois  1.3
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
ColorConversion.c
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
19 
20 #define CLAMP(value) if (value < 0) value = 0; else if (value > 255) value = 255;
21 
22 // ####################################################################################################
23 void convertYUYVtoRGB24(unsigned int w, unsigned int h, unsigned char const * srcptr, unsigned char * dstptr)
24 {
25  // FIXME This code does not work if w is odd
26  const int K1 = (int)(1.402f * (1 << 16));
27  const int K2 = (int)(0.714f * (1 << 16));
28  const int K3 = (int)(0.334f * (1 << 16));
29  const int K4 = (int)(1.772f * (1 << 16));
30  const unsigned int pitch = w * 2; // 2 bytes per one YU-YV pixel
31  unsigned int x, y;
32  unsigned char Y1, Y2;
33  int uf, vf, R, G, B;
34 
35  for (y = 0; y < h; ++y)
36  {
37  for (x = 0; x < pitch; x += 4) // Y1 U Y2 V
38  {
39  Y1 = *srcptr++; uf = *srcptr++ - 128; Y2 = *srcptr++; vf = *srcptr++ - 128;
40 
41  R = Y1 + (K1 * vf >> 16);
42  G = Y1 - (K2 * vf >> 16) - (K3 * uf >> 16);
43  B = Y1 + (K4 * uf >> 16);
44  CLAMP(R); CLAMP(G); CLAMP(B);
45  *dstptr++ = (unsigned char)(R); *dstptr++ = (unsigned char)(G); *dstptr++ = (unsigned char)(B);
46 
47  R = Y2 + (K1 * vf >> 16);
48  G = Y2 - (K2 * vf >> 16) - (K3 * uf >> 16);
49  B = Y2 + (K4 * uf >> 16);
50  CLAMP(R); CLAMP(G); CLAMP(B);
51  *dstptr++ = (unsigned char)(R); *dstptr++ = (unsigned char)(G); *dstptr++ = (unsigned char)(B);
52  }
53  }
54 }
55 
56 // ####################################################################################################
57 inline void convertYUYVtoRGBYLinternal(int R, int G, int B, int * dstrg, int * dstby, int * dstlum,
58  int thresh, int lshift, int lumlshift)
59 {
60  CLAMP(R); CLAMP(G); CLAMP(B);
61 
62  int L = R + G + B;
63  *dstlum = (L / 3) << lumlshift;
64 
65  if (L < thresh)
66  {
67  *dstrg = 0;
68  *dstby = 0;
69  }
70  else
71  {
72  int red = (2 * R - G - B);
73  int green = (2 * G - R - B);
74  int blue = (2 * B - R - G);
75  int rg = R - G; if (rg < 0) rg = -rg;
76  int yellow = -2 * blue - 4 * rg;
77 
78  if (red < 0) red = 0;
79  if (green < 0) green = 0;
80  if (blue < 0) blue = 0;
81  if (yellow < 0) yellow = 0;
82 
83  *dstrg = (3 * (red - green) << lshift) / L;
84  *dstby = (3 * (blue - yellow) << lshift) / L;
85  }
86 }
87 
88 // ####################################################################################################
89 void convertYUYVtoRGBYL(unsigned int w, unsigned int h, unsigned char const * srcptr, int * dstrg,
90  int * dstby, int * dstlum, int thresh, int inputbits)
91 {
92  // FIXME This code does not work if w is odd
93  const int K1 = (int)(1.402f * (1 << 16));
94  const int K2 = (int)(0.714f * (1 << 16));
95  const int K3 = (int)(0.334f * (1 << 16));
96  const int K4 = (int)(1.772f * (1 << 16));
97  const unsigned int pitch = w * 2; // 2 bytes per one YU-YV pixel
98  const int lshift = inputbits - 3; // FIXME assumes inputbits > 3
99  const int lumlshift = inputbits - 8; // FIXME assumes inputbits > 8; why two different shifts?
100 
101  unsigned int x, y;
102  unsigned char Y1, Y2;
103  int uf, vf, R, G, B;
104 
105  for (y = 0; y < h; ++y)
106  {
107  for (x = 0; x < pitch; x += 4) // Y1 U Y2 V
108  {
109  Y1 = *srcptr++; uf = *srcptr++ - 128; Y2 = *srcptr++; vf = *srcptr++ - 128;
110 
111  R = Y1 + (K1 * vf >> 16);
112  G = Y1 - (K2 * vf >> 16) - (K3 * uf >> 16);
113  B = Y1 + (K4 * uf >> 16);
114 
115  convertYUYVtoRGBYLinternal(R, G, B, dstrg, dstby, dstlum, thresh, lshift, lumlshift);
116 
117  ++dstrg; ++dstby; ++dstlum;
118 
119  R = Y2 + (K1 * vf >> 16);
120  G = Y2 - (K2 * vf >> 16) - (K3 * uf >> 16);
121  B = Y2 + (K4 * uf >> 16);
122 
123  convertYUYVtoRGBYLinternal(R, G, B, dstrg, dstby, dstlum, thresh, lshift, lumlshift);
124 
125  ++dstrg; ++dstby; ++dstlum;
126  }
127  }
128 }
void convertYUYVtoRGBYLinternal(int R, int G, int B, int *dstrg, int *dstby, int *dstlum, int thresh, int lshift, int lumlshift)
#define CLAMP(value)
void convertYUYVtoRGB24(unsigned int w, unsigned int h, unsigned char const *srcptr, unsigned char *dstptr)
Convert from YUYV to RGB, mostly intended for internal use. Use RawImage functions instead in most ca...
void convertYUYVtoRGBYL(unsigned int w, unsigned int h, unsigned char const *srcptr, int *dstrg, int *dstby, int *dstlum, int thresh, int inputbits)
Convert from YUYV to RG, BY, and luminance for use by Saliency module in jevoisbase. For internal use.