我试图使用V4L2 API来捕获图像并将图像放入opencv Mat中。问题是我的网络摄像头只在YUYV (YUY2)中捕获,所以我需要首先转换为RGB24。这里是完整的V4L2代码,我正在使用。
我能够让图片中的物体被识别出来,但它都是粉红色和绿色的,并且它是水平拉伸和扭曲的。我已经尝试了许多不同的转换公式,我有相同的基本粉红色/绿色失真图像。这张图的公式来自http://paulbourke.net/dataformats/yuv/。我正在使用linux上的shotwell照片查看器来查看.raw图像。我没法让瘸子打开。我不太了解如何保存图像格式,但我假设必须有某种标题,但shotwell照片查看器似乎工作。这可能是不正确的图像的原因吗?
我不确定V4l2是否返回由p指向的有符号或无符号字节图像。但如果这是问题,我的图像不会只是色差吗?但看起来几何形状也扭曲了。我相信我正确地处理了转换为浮点数和从浮点数转换的问题。
有人能帮我理解一下吗
- 如何找出包含在*void p变量 中的底层类型
- 从YUYV转换为RGB24的正确公式,包括使用哪种类型的解释
- 可以保存图像没有格式(头)和观看与Shotwell是问题吗?
- 是否有一种简单的方法来正确保存RGB24图像。
- 通用调试提示
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);
}
首先,您必须了解使用什么类型的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文件打开功能,并尝试选择正确的值有一个正确解码的图像,以找到你正在使用的数据类型。
不要尝试重新发明轮子。很多人都写过色彩空间转换器,而且很有可能你的实现(即使它有效)不是"最佳"的(例如比必要的慢)。
处理任何颜色空间的V4L2设备的规范方法是使用libv4l库,它将透明地将相机的本机颜色空间转换为BGR24
, RGB24
和YUV420
中的一次(如果你想要,我认为这是真的)。
至于保存图像,仍然使用已经存在的内容。就我个人而言,我会使用imagemagick将帧保存为任何imageviewer都可以读取的"适当"格式(png或tiff,如果质量重要)