summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYongqin Liu <yongqin.liu@linaro.org>2017-09-05 09:47:03 +0800
committerYongqin Liu <yongqin.liu@linaro.org>2017-09-05 09:48:33 +0800
commitfd9043575e12b82c095e9b5e9466eac3ef91e910 (patch)
tree7afb495f37f23d2a278548af1d884aa63797a506
parent238806e34087ddb59915fa2a5c1450f1e99c7fb1 (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.c50
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;