我正在尝试使用V4L2 API捕获图像并将图像放入opencv Mat中。问题是我的网络摄像头只能在YUYV(YUY2)中捕获所以我需要先转换为RGB24。这是我正在使用的完整V4L2 code。
我能够让图片中的物体被识别,但它全部是粉红色和绿色,并且水平拉伸并扭曲。我尝试了很多不同的转换公式,并且我有相同的基本粉红色/绿色扭曲图像。用于此图片的公式来自http://paulbourke.net/dataformats/yuv/。我在linux上使用shotwell照片查看器来查看.raw图像。我无法让gimp打开它。我不知道如何保存图像格式,但我认为必须有某种标题,但Shotwell照片查看器似乎工作。这可能是图像不正确的原因吗?
我不确定V4l2是否返回p所指向的有符号或无符号字节图像。但如果这是问题,我的形象不会只是变色吗?但似乎几何形状也是扭曲的。我相信我正确处理浮动点和浮点数。
有人可以帮助我理解
由于
static unsigned char *bgr_image;
static void process_image(void *p, int size)
{
frame_number++;
char filename[15];
sprintf(filename, "frame-%d.raw", frame_number);
FILE *fp=fopen(filename,"wb");
int i;
float y1, y2, u, v;
char * bgr_p = bgr_image;
unsigned char * p_tmp = (unsigned char *) p;
for (i=0; i < size; i+=4) {
y1 = p_tmp[i];
u = p_tmp[i+1];
y2 = p_tmp[i+2];
v = p_tmp[i+3];
bgr_p[0] = (y1 + 1.371*(u - 128.0));
bgr_p[1] = (y1 - 0.698*(u - 128.0) - 0.336*(v - 128.0));
bgr_p[2] = (y1 + 1.732*(v - 128.0));
bgr_p[3] = (y2 + 1.371*(v - 128.0));
bgr_p[4] = (y2 - 0.698*(v - 128.0) - 0.336*(u - 128.0));
bgr_p[5] = (y2 + 1.732*(u - 128.0));
bgr_p+=6;
}
fwrite(bgr_image, size, 1, fp);
fflush(fp);
fclose(fp);
}
答案 0 :(得分:2)
不要试图重新发明轮子。很多人都写过色彩空间转换器,很有可能你的实现(即使它有效)不是“最优”的(例如比必要的慢)。
处理任何色彩空间的V4L2设备的规范方法是使用libv4l - 库,它将透明地将相机原生色彩空间转换为BGR24
一次, RGB24
和YUV420
(如果您愿意,我认为这是真的)。
至于保存图像,再次使用已存在的图像。就个人而言,我会使用imagemagick以“适当”的格式保存一个框架,任何图像查看器都可以读取(png或tiff,如果质量很重要)
答案 1 :(得分:1)
首先,您必须了解您正在使用的YUV422的类型。
PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
尝试相应地替换y1,u,y2和v,但你可能根本没有处理YUV422,图片可能是平面的,而不是你期望的打包格式?
我认为最好下载IrfanViewer,它具有原始yuv文件打开功能,并尝试选择正确的值以获得正确解码的图像,以查找您正在使用的数据类型。