This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DM6467 ARM端图像处理相关问题,YUV444数据在内存中是如何存储的?

Other Parts Discussed in Thread: TVP5158

硬件系统描述:

      摄像头采用的是PAL制式的模拟摄像头,通过TVP5158芯片读入数据。

      系统的板卡是DM6467的平台,我只是用了他的GPP的ARM核心来处理数据。

      输出的数据是CVBS的数据格式,通过同轴线将数据输出到7寸显示器上。

      系统使用的linux操作系统是Montasa的裁剪版。

软件系统描述:

我的这个图像处理的框架是基于ARM核心的,这个处理的流程分为了三个线程:

 pthread1:捕获线程

 pthread2:算法处理

 pthread3:显示线程

全局变量Process结构体中包含了两个重要的成员变量:

typedef struct Pro{

        int Frame_size; // 704*576

        int Frame_Width; // 704

        int Frame_Height; // 576

        TVP5158DemuxThrd_Handle param_f;

        TVP5158DemuxThrd_Handle param_s;

}Process_Exc,*Process_Exc_P;

 Process_Exc_P Process;

 param_s:存放了通过CMEM_alloc申请的捕获线程的数据缓冲的存放起始地址

 param_f:存放了通过CMEM_alloc申请的算法线程的数据缓冲的存放起始地址

三个线程之间的数据交换都加上了线程数据同步锁,防止在修改数据时,其他线程修改数据,保证线程的顺序执行,流程如下:

pthread1捕获线程(申请buffer后填入图像数据将数据起始地址存入param_f当中,打开param_f的数据锁)

pthread2算法处理(将parma_f中的对应的起始地址开始的图像数据使用memcpy到自身CMEM_alloc申请的缓冲区当中准备处理,将处理完成的数据的起始地址放到param_s中,并打开param_s的数据锁)

pthread3显示线程(将param_s中起始地址对应的图像输出通过DMA通道拷贝到指定的显示区域输出图像)

软件的情况如下:

以上是我的整个的算法处理的流程,在没进行算法处理之前都不存在问题,直接的数据copy能过完整的显示处图像,但是加上数据处理之后存在了问题,我将系统处理过程中涉及到的相关的数据打印了出来,如下:

我将捕获的图像前在initCapture中配置的v4l2_format的数据和在initDisplay中配置的v4l2_format的数据打印了出来,数据结果如下所示:

1、  Capture参数:

Width=712 Height=2500  v4l2_feild=0 bytesperline=712

sizeimage=3827200  clolorspace=0  priv=0  pixelformat=943929433

2、  Display 参数:

Width=720 Height=576  v4l2_feild=0 bytesperline=720

sizeimage=4147200  clolorspace=0  priv=0  pixelformat=943929433

    通过上述的参数,我们由pixelformat参数得知,pixelformat= v4l2_fourcc('Y', '4', '4', '4'),也就是说我们的数据采集的格式是YUV444的全采样的数据格式。需要根据硬件来确定数据是隔行显示还是按照top&bottom的方式来存储数据!

实际打印的数据的结果如下所示:

串口打印的是我在copy捕获缓冲区数据之后的数据的内容,下面的图像分别时copy的代码和显示的图像的情况,我们打印出来的数据的情况是出现一大段的269488144这个数据之后又会出现变化的数据。如下图所示:

拷贝并printf打印数据

打印的结果

接下来是存在的问题:

1、 请问为什么在Capture的v4l2_format参数中的Height的数值是2500,这样做的目的是什么呢?                                                  ***

2、我如何才能明确的确定v4l2_format参数中的v4l2_field的具体内容,现在的得到的是v4l2_feild=0,应该如何确定呢?                             **

3、我应该如何读取保存在内存中的数据,来进行图像处理的相关操作,由于数据他自身存储方式的不确定,我不是很清楚应该如何读取数据内容,将灰度部分处理,将YUV数据转换成Y的数据(我将U=V赋值为0x80这个时候图像是灰度图像吗?)                                                               ****

4、我在拷贝出数据之后对图像的数据进行了打印,打印的结果如我发您的图所示,数据当中有很多269488144,这样的unsigned int型的数据重复出现,和图像本身有什么关系呢?变化的数据才是图像的数据吗?                                                                                             **

 

简单的算法接口:

int LIB_linerTrans(const unsigned char *in_data,unsigned char *out_data,const float slope, int intercept,short imgHeight,short imgWidth)

{

         int tmp;

         int pixelNums = imgHeight*imgWidth;

         int n;

         for (n=0; n<pixelNums; n++)

         {

                   tmp = ((int)in_data[n] * slope + intercept);

                   out_data[n] = (unsigned char)( tmp>255?255: ( tmp < 0?0: tmp ) );

         }

         return 1;

}

  • 你好,

    TV5158输出应该都是YUV422的格式啊。

  • TVP5158输出的YUV422数据具体是哪一种呢?我想了解一下怎么去查看TVP5158采集数据的类型?

    我查阅了相关的资料显示DM6467支持的YUV的数据格式是YUV422 Semi-Planar(不支持YUV422-Interleaved、YUYV、UYVY 这样的数据格式),那么这种数据存储

    的方式如下所示:

     这里我们可以看到数据的存储方式是Y分量和UV分量分开的,每个像素点需要2Bytes来存储对应的数据。

    还想请教一下在输出到CVBS这种AV视频的数据过程中,图像在内存中是如何存储的呢?

    通过对CVBS信号的了解,我们得知图像的不同分量数据是通过各种调制方法加载到模拟型号CVBS上的,加载的方式如下图所示:

    CVBS型号的种类:

    • 亮度信号——包含视频图像的强度(亮度或暗度)信息
    • 色彩信号——包含视频图像的色彩信息
    • 同步信号——控制在电视显示屏等显示器上信号的扫描

    1、单色复合信号是由两个成分组成的:亮度和同步。如下显示了这个信号(通常成为Y信号)

    2、色彩信号通常被称为C信号,如下所示:

    3、复合彩色视频信号通常成为彩色视频、消隐与同步(CVBS)信号示Y与C之和,如下图所示:  CVBS = Y + C

    这样就能调制出一个标准的CVBS信号,那么我们的图像数据是按照怎样的顺序来完成上述的相关的操作的呢?我们看到下面这张时序图:

    在这个时序图当中,首先是水平的同步时序时钟,然后是我们的灰度数据Y和色度数据UV,直到完成偶场的图像数据之后,出现了垂直方向的同步数据,接下来就是

    奇数场的数据,同样的也有水平方向的同步数据,最后完成整张图像的显示!  通过这样的分析,我们认为数据是按照上面叙述的这样的数据存储方式是否合理

    呢?