一.前言
最近准备做一个图形检测项目练手,奈何选用的UVC摄像头支持YUYV或MJPG格式不能直接使用,对网上大部分关于yuyv转rgb888转化算法都如下原代码所示(我自己也搞不清这代码是从那抄的,所以未贴引用网址)。虽然有现成代码现成可抄来用,奈何选用平台主控NUC977(主频300M,不支持浮点运算和硬件解码)实在太差,直接怼上去比放PPT还慢。随其改其代码,主要针对浮点运算修改,以及重复计算修改,改完之后可以明显感觉到性能提升。
大家可以进行查阅,比较学习,敝人也是参考各位大佬代码,希望可以共同学习,如有意见可以共同讨论。
二.原代码
int video_device::yuyv_2_rgb888(const void *p, int size, unsigned char *frame_buffer)
{
int i,j;
unsigned char y1,y2,u,v;
int r1,g1,b1,r2,g2,b2;
const char *pointer;
size++;
pointer = (const char *)p;
for(i=0;i<480;i++)
{
for(j=0;j<320;j++)
{
y1 = *( pointer + (i*320+j)*4);
u = *( pointer + (i*320+j)*4 + 1);
y2 = *( pointer + (i*320+j)*4 + 2);
v = *( pointer + (i*320+j)*4 + 3);
r1 = y1 + 1.042*(v-128);
g1 = y1 - 0.34414*(u-128) - 0.71414*(v-128);
b1 = y1 + 1.772*(u-128);
r2 = y2 + 1.042*(v-128);
g2 = y2 - 0.34414*(u-128) - 0.71414*(v-128);
b2 = y2 + 1.772*(u-128);
if(r1>255) r1 = 255;
else if(r1<0) r1 = 0;
if(b1>255) b1 = 255;
else if(b1<0) b1 = 0;
if(g1>255) g1 = 255;
else if(g1<0) g1 = 0;
if(r2>255) r2 = 255;
else if(r2<0) r2 = 0;
if(b2>255) b2 = 255;
else if(b2<0) b2 = 0;
if(g2>255) g2 = 255;
else if(g2<0) g2 = 0;
*(frame_buffer + ((480-1-i)*320+j)*6 ) = (unsigned char)b1;
*(frame_buffer + ((480-1-i)*320+j)*6 + 1) = (unsigned char)g1;
*(frame_buffer + ((480-1-i)*320+j)*6 + 2) = (unsigned char)r1;
*(frame_buffer + ((480-1-i)*320+j)*6 + 3) = (unsigned char)b2;
*(frame_buffer + ((480-1-i)*320+j)*6 + 4) = (unsigned char)g2;
*(frame_buffer + ((480-1-i)*320+j)*6 + 5) = (unsigned char)r2;
}
}
// pr_debug("\tchange to RGB OK \n");
return 0;
}
三.优化代码
int video_device::yuyv_2_rgb888(const void *p, int size, unsigned char *frame_buffer)
{
int i,j;
unsigned char y1,y2;
int r1,g1,b1,r2,g2,b2,u,v;
unsigned char *pointer;
for(i=0; i<size; i++)
{
pointer = (unsigned char *)p + i*4;
y1 = * pointer++;
u = *( pointer++) - 128;
y2 = *( pointer++);
v = *( pointer ) - 128;
r1 = (266*v) >> 8;
g1 = (88*u) + ((183*v)) >> 8;
b1 = (454*u) >> 8;
r2 = y2 + r1;
g2 = y2 - g1;
b2 = y2 + b1;
r1 = y1 + r1;
g1 = y1 - g1;
b1 = y1 + b1;
if(r1>255) r1 = 255;
else if(r1<0) r1 = 0;
if(b1>255) b1 = 255;
else if(b1<0) b1 = 0;
if(g1>255) g1 = 255;
else if(g1<0) g1 = 0;
if(r2>255) r2 = 255;
else if(r2<0) r2 = 0;
if(b2>255) b2 = 255;
else if(b2<0) b2 = 0;
if(g2>255) g2 = 255;
else if(g2<0) g2 = 0;
pointer = frame_buffer + i*6;
*(pointer++) = (unsigned char)b1;
*(pointer++) = (unsigned char)g1;
*(pointer++) = (unsigned char)r1;
*(pointer++) = (unsigned char)b2;
*(pointer++) = (unsigned char)g2;
*(pointer ) = (unsigned char)r2;
}
// pr_debug("\tchange to RGB OK \n");
return 0;
}