调试经验--图像
随着芯片技术的发展,嵌入式设备也拥有较强的图像处理能力了。而其中的佼佼者,davinci平台提供了很强的图像处理功能。
在davinci平台的使用过程中,我们遇到几个图像相关的问题:
1,图像质量差;
2,上位机显示图像色度不正确;
3,颜色分量;
4,yuv数据传输时的裁切。
一、图像质量差
背景:
在描述问题前,说明一下我们嵌入式设备的开发工作流程,应该有助于说明问题。
主板是硬件开发人员参考dm6446开发板的原理图设计的,软件是以dvsdk1.3为开发工具进行的,视频输入是标清的模拟视频,在视频输出端接显示器可以查看图像。arm接收到输入图像后,传送给dsp,dsp分析图像之后,将结果返回给arm,arm将部分结果,以osd的方式叠加在输出图像上。
关于图像的buffer,简单说明一下:
dm6446的图像输入buffer,与图像输出buffer,是在两个不同的内存区域,我们叠加的osd信息,是在输出buffer中实现的。
另外有PC上的配置软件,可以进行设备的配置,其中有一个抓图功能,是使用PC上的配置软件下发捕获图像命令,嵌入式程序执行捕获,即从输入的图像buffer中取出一幅yuv来,然后上传给PC。
问题现象:
在dm6446平台上,接入标清的模拟视频输入,在视频输出端接显示器查看图像,发现图像质量不好,现象如下:
有模糊的彩色短条移动,在短条所在行附件,运动物体通过时抖动很厉害(彩色短条的形状比较类似于我们叠加的字符信息OSD);
不但OSD会造成画面影像移动,其他醒目物体也有类似模糊影像移动。
进行单张抓图,图像上也有彩条。
图像底部是黑条,没有图像。
进一步的测试:
采用对比法,正常的程序运行,是既有视频输入也有视频输出,并且还有较多其它功能。我们对系统功能进行简化,进行同样硬件环境下的对比运行测试。
视频环路程序:同时有输入输出,将输入的图像直接送至输出,输出画面有OSD叠加。此时,捕获的图像中还是有OSD的影像,图像底部无图像。
视频解码显示程序:这是dvsdk中自带的例程,进行视频解码,然后视频输出。此时,图像清晰、完整。
分析:
图像有影子移动,是模拟信号的干扰,当只进行视频输出时图像清晰,说明视频输出部分的线路没有问题,则视频输入部分线路有问题。
单张抓图的图像上也有彩条,说明了视频输出对视频输入有影响:OSD只用于输出,而抓图抓的只是输入图像,可见输出干扰了输入。
图像底部无图像,是嵌入式软件对图像的设置有问题。
原因:
问题分两部分,一个是图像上有影子移动,一个是图像底部无图像。
图像上有影子移动:
板卡的视频输出线反向走过整块板卡,其中有一段与输入线很接近,干扰了输入信号。
对于这个问题,后来还知道,还有一条分离输入输出问题的测试方法:VPBE可以设置为彩条输出,可以区分输出图像显示问题的来源是图像还是驱动 。
图像底部无图像:
是设置图像参数时出了问题,由于osd层是使用半字节表示一个像素,又需要osd层的宽度是32字节对齐的,带来一个问题:720/2=360不是32的倍数,所以,需要使用一个比360大的又最接近的32的倍数,本系统中使用的是384:
OSD属性层:384×576
在设置透明度时,原来设置的是720×576/2 的区域,改为768×576/2 ,恢复varInfo.yres=576,图像及OSD都能全屏显示。
下表简单描述了视频输出的buffer:
设备名 数据内容 缓冲区大小 每像素占字节数
/dev/fb/0 --> OSD内容 1440×576 2 (RGB565)
/dev/fb/2 --> OSD透明度 384×576 0.5 (行宽384,有效使用360)
/dev/fb/3 --> 视频图像 1440×576 2 (UYVY)
二、上位机显示图像色度不正确
现象:
在嵌入式设备输出端连接的显示屏上,图像显示正常。在用PC上的配置软件抓图,显示的图像不正常。
分析:
图像显示不正常的地方,往往是画面中最亮的地方,可能是某些值在转换中越界,
原因:
分析代码,是在dm6446系统中,使用的是yuv,而在PC上显示,是使用的RGB,在进行格式转换时,某些值越界了。例如,在RGB色彩系统中,3个255就是白色,若其中一个越界,造成两个255与一个0,就成了黄色。
三、颜色分量
高清图像输出,采用3个颜色分量Y、Cb、Cr,输出,使用色差分量线外接显示器。
分量 Y、 Cb、 Cr
用颜色线表示 绿、 蓝、 红
与我们通常说得RGB有较大的差异,RGB的全0为黑色,全255为白色。
而YCbCr的几种典型颜色,我们有必要知道一下:
0, 0, 0 绿色
255,255,255 粉红色
255,0,255 黄色
255,255,0 亮篮色
四、yuv数据传输时的裁切
bt656、bt1120都禁止使用0与255。当遇到0时,应当转换为1;当遇到255时,应该转换为254。
dm6467的vport in与out口都没有进行数据裁减。真正实现数据裁剪的,是内核驱动。
例如,在dvsdk1.4中,使用vport传输yuv数据,就没有裁切;而在dvsdk3.10中,就实现了0与255的裁切。
当遇到数据裁切时,有时会导致新的问题,例如,我想覆盖yuv的第一行来传输某些信息,若被裁切了,数据就不是原来的意义了。
此时,我们可以使用数据转换法,即让0与255不出现就是了。比较简单的方法,我使用两字节来表示一个字节:0-253,我用高字节置1,低字节使用1-254来表示;而254-255,我使用高字节置2,低字节为1-2即可。