diff options
author | Yongqin Liu <yongqin.liu@linaro.org> | 2017-09-05 09:47:03 +0800 |
---|---|---|
committer | Yongqin Liu <yongqin.liu@linaro.org> | 2017-09-05 09:48:33 +0800 |
commit | fd9043575e12b82c095e9b5e9466eac3ef91e910 (patch) | |
tree | 7afb495f37f23d2a278548af1d884aa63797a506 | |
parent | 238806e34087ddb59915fa2a5c1450f1e99c7fb1 (diff) |
webcam-tools.c: update the yuyv to rgb algorithm
https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/1071301e-74a2-4de4-be72-81c34604cde9/program-to-translate-yuyv-to-rgbrgb?forum=windowsdirectshowdevelopment
Signed-off-by: Yongqin Liu <yongqin.liu@linaro.org>
-rw-r--r-- | libcamera/webcam-tools.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/libcamera/webcam-tools.c b/libcamera/webcam-tools.c index 6a01506..82a976d 100644 --- a/libcamera/webcam-tools.c +++ b/libcamera/webcam-tools.c @@ -2,7 +2,7 @@ * from: https://github.com/bellbind/node-v4l2camera * capturing from UVC cam * requires: libjpeg-dev - * build: gcc -std=c99 capture.c -ljpeg -o capture + * build: gcc -std=c99 webcam-tools.c -ljpeg -o capture */ #include <errno.h> @@ -727,31 +727,45 @@ static inline int minmax(int min, int v, int max) { return (v < min) ? min : (max < v) ? max : v; } static inline uint8_t yuv2r(int y, int u, int v) { - (void) u; return minmax(0, (y + 359 * v) >> 8, 255); + int c = y-16, d = u - 128, e = v - 128; + // https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/1071301e-74a2-4de4-be72-81c34604cde9/program-to-translate-yuyv-to-rgbrgb?forum=windowsdirectshowdevelopment + int r = (298 * c + 409 * e + 128) >> 8; + // linaro webcam + // int r = (1.164 * c + 1.596 * e ); + // int r = (y + 359 * v) >> 8; + return minmax(0, r, 255); } static inline uint8_t yuv2g(int y, int u, int v) { - return minmax(0, (y + 88 * v - 183 * u) >> 8, 255); + int c = y - 16, d = u - 128, e = v - 128; + int g = (298 * c - 100 * d - 208 * e + 128) >> 8; + // int g = (1.164 * c - 0.391 * d - 0.813 * e ) + // int g = (y + 88 * v - 183 * u) >> 8; + return minmax(0, g, 255); } static inline uint8_t yuv2b(int y, int u, int v) { - (void) v; return minmax(0, (y + 454 * u) >> 8, 255); + int c = y - 16, d = u - 128, e = v - 128; + int b = (298 * c + 516 * d + 128) >> 8; + //int b = (1.164 * c + 2.018 * d ); + //int b = (y + 454 * u) >> 8; + return minmax(0, b, 255); } -uint8_t* yuyv2rgb(const uint8_t* yuyv, uint32_t width, uint32_t height) { - uint8_t* rgb = calloc(width * height * 3, sizeof (uint8_t)); +unsigned char* yuyv2rgb(const unsigned char* yuyv, uint32_t width, uint32_t height) { + unsigned char* rgb = calloc(width * height * 3, sizeof (unsigned char)); for (size_t i = 0; i < height; i++) { for (size_t j = 0; j < width; j += 2) { - size_t index = i * width + j; - size_t index2 = index * 2, index3 = index * 3; - int y0 = yuyv[index2 + 0] << 8; - int u = yuyv[index2 + 1] - 128; - int y1 = yuyv[index2 + 2] << 8; - int v = yuyv[index2 + 3] - 128; - rgb[index3 + 0] = yuv2r(y0, u, v); - rgb[index3 + 1] = yuv2g(y0, u, v); - rgb[index3 + 2] = yuv2b(y0, u, v); - rgb[index3 + 3] = yuv2r(y1, u, v); - rgb[index3 + 4] = yuv2g(y1, u, v); - rgb[index3 + 5] = yuv2b(y1, u, v); + size_t indexPixel = i * width + j; + size_t indexYUYV = indexPixel * 2, indexRGB = indexPixel * 3; + unsigned char y0 = yuyv[indexYUYV + 0] ; + unsigned char u = yuyv[indexYUYV + 1]; + unsigned char y1 = yuyv[indexYUYV + 2]; + unsigned char v = yuyv[indexYUYV + 3]; + rgb[indexRGB + 0] = yuv2r(y0, u, v); + rgb[indexRGB + 1] = yuv2g(y0, u, v); + rgb[indexRGB + 2] = yuv2b(y0, u, v); + rgb[indexRGB + 3] = yuv2r(y1, u, v); + rgb[indexRGB + 4] = yuv2g(y1, u, v); + rgb[indexRGB + 5] = yuv2b(y1, u, v); } } return rgb; |