你好!
我们正在尝试将使用libuvc(USB摄像头)捕获的YUV帧转换为RGB,但我们无法获得正确的颜色。
libuvc 提供的帧格式是 YUV422(根据标题):
enum uvc_frame_format {
....
UVC_FRAME_FORMAT_COMPRESSED,
/** YUYV/YUV2/YUV422: YUV encoding with one luminance value per pixel and
* one UV (chrominance) pair for every two pixels.
*/尺寸为 1920x1024,跨度为 3840(1920*2)
我们用来转换颜色的代码是
cv::Mat ConvertFrame(uvc_frame_t *frame, int inputFormat=G2D_YUYV){
void *G2D_Handler=NULL;
if (g2d_open(&G2D_Handler)!=0){
puts("G2D_Start: Error opening g2d device");
};
int size = frame->data_bytes;
struct g2d_buf *srcM = g2d_alloc (size,1);
struct g2d_buf *dstM = g2d_alloc (frame->width * frame->height * 3,1);
memcpy(srcM->buf_vaddr, frame->data, size);
struct g2d_surface src,dst;
src.planes[0] = srcM->buf_paddr;
src.planes[1] = 0; //srcM->buf_paddr;
src.planes[2] = 0; //srcM->buf_paddr;
src.left = 0;
src.top = 0;
src.right = frame->width;
src.bottom = frame->height;
src.stride = frame->step;
src.width = frame->width;
src.height = frame->height;
src.rot = G2D_ROTATION_0;
src.format = inputFormat;
cv::Mat out(frame->height, frame->width, CV_8UC3, dstM->buf_vaddr );
dst.planes[0] = dstM->buf_paddr;
dst.left = 0;
dst.top = 0;
dst.right = out.cols;
dst.bottom = out.rows;
dst.stride = out.step1();
dst.width = out.cols;
dst.height = out.rows;
dst.rot = G2D_ROTATION_0;
dst.format = G2D_RGB888 ;
int r = g2d_blit(G2D_Handler, &src, &dst);
if (r!=0) puts("convertFrame :: ERROR g2d_blit");
r=g2d_finish(G2D_Handler);
if (r!=0) puts("convertFrame :: ERROR g2d_finish");
char name[128];
snprintf(name,128,"g2dOutput_%d.png", inputFormat );
cv::imwrite(name,out);
g2d_free (srcM);
return out;
}如果使用 inputFormat = G2D_YUYV,我们可以得到更好的结果,但从附图中可以看出,这远远不够正确。
谁能告诉我们如何解决这个问题?
提前感谢!
我有了突破。
i.MX 图形用户指南》指出
”
在 i.MX 6(i.MX 6Quad Plus 除外)上,RGB 步幅对齐为 16 字节,在 i.MX 6Quad Plus、i.MX 7ULP 和 i.MX 8 系列设备上,无论是源表面还是目标表面,RGB 步幅
对齐均为 1 像素。
”
尽管我使用的是 i.mx8MP 而且应该不需要步幅对齐,但我还是将步幅值更改为 16 字节对齐,g2d 操作(YUYV 到 RGB888)成功了!
令人讨厌的是,我的应用程序现在需要处理额外的步长。再说一遍,在 Kirkstone 上不需要这种步幅对齐(特别是这个版本的 yocto 清单—— imx-5.15.52-2.1.0.xml:为 L5.15.52-2.1.0 版本添加清单 [YOCIM... · nxp-imx /imx-manifest @842ad7b)
差不多是这样
g2d_surface srcSurface;
g2d_surface dstSurface;
srcSurface.format = G2D_YUYV;
srcSurface.left = 0;
srcSurface.right = 1920;
srcSurface.top = 0;
srcSurface.bottom = 1080;
srcSurface.stride = 1920;
srcSurface.width = 1920;
srcSurface.height = 1080;
srcSurface.blendfunc = G2D_ZERO;
srcSurface.global_alpha = 0;
srcSurface.clrcolor = 0;
srcSurface.rot = G2D_ROTATION_0;
srcSurface->planes[0] = src_g2d_buf->buf_paddr;
srcSurface->planes[1] = 0;
srcSurface->planes[2] = 0;
dstSurface.format = G2D_RGB888;
dstSurface.left = 0;
dstSurface.right = 300;
dstSurface.top = 0;
dstSurface.bottom = 300;
dstSurface.stride = 300;
dstSurface.width = 300;
dstSurface.height = 300;
dstSurface.blendfunc = G2D_ZERO;
dstSurface.global_alpha = 0;
dstSurface.clrcolor = 0;
dstSurface.rot = G2D_ROTATION_0;
srcSurface->planes[0] = dst_g2d_buf->buf_paddr;
srcSurface->planes[1] = 0;
srcSurface->planes[2] = 0;
int result = g2d_blit(_handle, src, dest);
你怎么能在 Kirkstone 上将 YUYV 转换为 RGB888。我永远无法完成这项工作。你会分享代码吗?但是,谢谢
YUYV 到 RGBX8888 可以正常工作,正如我已经在下面说过的那样。也许这对你的应用程序来说没问题,因为你可以忽略 " X " 元器件,因为不在乎。
我也在 IMX8M Plus 上使用 G2D。奇怪的是,YUYV 转 RGB888 在 Kirkstone 上运行正常,但在 Scarthgap 上,g2d 库却打印出目标格式无效的错误信息。
有可能解决这个问题吗?
感谢您的迅速反馈,Ivan,
,我实施了您的解决方案,但我的图像还是坏了(见附件)。我还附上了代码,也许你会发现一些明显的问题。
你使用的是什么 CPU?
不清楚您为什么要
src.bottom = height/2;
src.height = height/2;
Thx
大家好
是的,我已经解决了这个问题:
这只是所用尺寸的问题。
void *G2D::convert(void *imageBuffer, int width, int height){ int size = width * height *2; struct g2d_surface src,dst; src.planes[0] = srcM->buf_paddr; src.planes[1] = 0; src.planes[2] = 0; src.left = 0; src.top = 0; src.right = width; src.bottom = height/2; src.stride = width *2; src.width = width; src.height = height/2; src.rot = G2D_ROTATION_0; src.format = G2D_YUYV; dst.planes[0] = dstM->buf_paddr; dst.left = 0; dst.top = 0; dst.right = width; dst.bottom = height; dst.stride = width ; dst.width = width; dst.height = height; dst.rot = G2D_ROTATION_0; dst.format = G2D_RGB888 ; memcpy(srcM->buf_vaddr, imageBuffer, size); int r = g2d_blit(G2D_Handler, &src, &dst); if (r!=0) puts("convertFrame :: ERROR g2d_blit"); r=g2d_finish(G2D_Handler); if (r!=0) puts("convertFrame :: ERROR g2d_finish"); return dstM->buf_vaddr; }
希望对你有用!
嗨,伊万,
,你能解决这个问题吗?
我也遇到了同样的问题。
谢谢
您好 @Bio_TICFSL,
我也有同样的问题:
在 NXP imx8mp G2D GPU (GC520L) 上,YUYV 转 RGBX 可以正常工作:
G2D_YUYV 转 G2D_RGBX8888 可以正常工作
但 YUYV 转 RGB(24 位 RGB888)不能正常工作。我有和上面一样的破损图片。
G2D_YUYV 至 G2D_RGB888
有什么提示可以解决这个问题吗?
谢谢
你好@Bio_TICFSL、
是否有与此话题相关的新闻?
BR
你好 ivan_garcia
目前,libg2d 不支持将 YUYV 转换为 BGR。我将与 R&D 团队讨论,以便启用。
此致