移植EMCV到DM6467(2)——OpenCV程序调试

本文详细介绍了如何将EMCV移植到DM6467平台上,涉及YUV到RGB的颜色空间转换、存储格式理解、OpenCV程序的C语言重构以及DSP端的调试过程,包括内存分配、函数调用和数组赋值的调整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


在《移植EMCV到DM6467(1)》中已经实现了使用EMCV来创建图像并添加矩形框这么一个简单的功能,现在要在其基础上进行第二步操作。

首先,由于我们的DM6467开发板接收的视频来自TVP5150,PAL格式,颜色空间为YUV422semi-planar,而OpenCV中IplImage使用的是RGB格式图像,所以需要进行颜色空间转换。然后,由于EMCV中有很多C++风格的代码,需要改为C语言格式。

 

1        VS2010调试OpenCV程序

1.1  YUV转RGB

在嵌入式系统中,使用较多的是YUV颜色空间的图像,而在PC上则更多使用RGB格式。OpenCV中默认的也是使用RGB格式的图像,所以需要将YUV转换为RGB。

由于YUV是通过对RGB进行简单矩阵变换的来,所以转换比较方便,但是需要注意的是:TVP5150传输来的YUV视频数据其实真正的颜色空间格式应该是YCbCr,这与YUV之间有一点差异,所以在选择颜色空间转换的公式时需要特别注意,网上有很多转换的公式,但是很多人都没有说清楚到底是YUV转RGB还是YCbCr转RGB。如果转换公式使用错误,转换后的图像会变绿。

经过多方查找,比较和测试,最终选择下面这个公式进行转换,转换后的效果良好。

 

R = (1.164 * (Y - 16) + 1.596 * (V - 128))

G = (1.164 * (Y - 16) - 0.813 * (V - 128) - 0.391 * (U - 128))

B = (1.164 * (Y - 16) + 2.018 * (U  - 128))

 

Y = ( 0.257 * R + 0.504 * G + 0.098 * B + 16 )

U = (-0.148 * R - 0.291 * G + 0.439 * B + 128)

V = ( 0.439 * R - 0.368 * G - 0.071 * B + 128)

 

DM6467是一款以C64+为核心的定点DSP,相比以C67+为核心的浮点DSP,对于同一个浮点运算,定点DSP所耗费的时间大约是浮点DSP的20倍。对于这么大的性能差异,我们在开发DM6467的应用程序时必须尽量少用浮点运算。所以,对于上面的YUV和RGB转换,我们需要考虑如何进行优化,将浮点运算改为整形运算。这个任务等整个移植封装过程都完成之后再做。

 

1.2  存储格式

DM6467的VPIF在接收了TVP5150传输过来的视频之后,会将其存储为一种特殊的格式,即YUV422 semi-planar,Y分量单独存储,UV分量交错存储。具体格式如下图所示。

 

而常见的YUV422存储格式如下图所示。

  

必须对两种存储格式有清晰的理解才能在编程时正确寻址并运算。

 

1.3  程序编写

在编程时,最重要的两点就是前面说的颜色空间转换公式以及YUV的存储格式,另外还需要注意的是OpenCV的IplImage存储的RGB图像数据是按BGR顺序存储的,还有就是在转换时可能会出现数据越界,需要添加限幅代码,即限制数据大小为0到255。只要注意到这些细节问题,编程不会有太大问题。最终的代码如下所示。

 

#include <stdio.h>

#include "cv.h"

#include "highgui.h"

#define MR(Y,U,V) (1.164 * (Y - 16) + 1.596 * (V - 128))

#define MG(Y,U,V) (1.164 * (Y - 16) - 0.813 * (V - 128) - 0.391 * (U - 128))

#define MB(Y,U,V) (1.164 * (Y - 16) + 2.018 * (U  - 128))

 

#define MY(R, G, B) ( 0.257 * R + 0.504 * G + 0.098 * B + 16 )

#define MU(R, G, B) (-0.148 * R - 0.291 * G + 0.439 * B + 128)

#define MV(R, G, B) ( 0.439 * R - 0.368 * G - 0.071 * B + 128)

void YUV422_C_RGB( unsigned char* pYUV, unsigned char* pRGB, int height, int width);

void RGB_C_YUV422( unsigned char* pRGB, unsigned char* pYUV, int height, int width);

 

int main()

{  

    CvSize size; // pal frame, 422, YUV422 semi-planar

    size.height = 576;

    size.width = 720;

    CvPoint point1, point2; // draw a rectangle in the middle of an image

    point1.x = size.width / 2 - 50;

    point1.y = size.height / 2 - 50;

    point2.x = size.width / 2 + 50;

    point2.y = size.height / 2 + 50;

    CvScalar color = CV_RGB(0, 255, 0); // green

    unsigned ch

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值