在进行VideoNet的程序(在http://www.codeproject.com/Articles/7573/VideoNetb下载的)学习中,发现在进行调试时,
1. 运行到 ConvertRGB2YUV 函数时,在
*y++=( RGB2YUV_YR[*r] +RGB2YUV_YG[*g]+RGB2YUV_YB[*b]+1048576)>>16; 出down掉!
崩溃! 程序每次到这里崩溃,我也崩溃了!后来反复查网上帖子,有几个说的还行,总体说来,还是没有根本解决:出现这个问题的原因是摄像头采集到的数据是YUY2 的格式, 而ConvertRGB2YUV函数只认识RGB 的格式,所以需要将 YUY2的数据转换成RGB 的格式,于是又疯狂的搜索,终于找到这个宝贵的函数:
/************************************************************************/
/* 函数名称: YUY2_RGB2_ljh
/* 参数:unsigned char *YUY2buff,unsigned char *RGBbuff,long dwSize
YUY2buff 原始待转换的 YUY2 的数据
RGBbuff 转换后的 RGB 数据
dwSize 数组大小
/* 返回值:void
/* 作者:ljhua
/* 时间:2012-08-11
/************************************************************************/
void YUY2_RGB2_ljh(unsignedchar *YUY2buff,unsigned char *RGBbuff,longdwSize)
{
//
//C = Y - 16
//D = U - 128
//E = V - 128
//R = clip(( 298 * C + 409 * E + 128) >> 8)
//G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
//B = clip(( 298 * C + 516 * D + 128) >> 8)
unsigned char *orgRGBbuff = RGBbuff;
for( long count = 0; count < dwSize; count += 4 )
{
//Y0 U0 Y1 V0
unsigned char Y0 = *YUY2buff;
unsigned char U = *(++YUY2buff);
unsigned char Y1 = *(++YUY2buff);
unsigned char V = *(++YUY2buff);
++YUY2buff;
long Y,C,D,E;
unsigned char R,G,B;
Y = Y0;
C = Y - 16;
D = U - 128;
E = V - 128;
R = clip255(( 298 * C + 409 * E + 128) >> 8);
G = clip255(( 298 * C - 100 * D - 208 * E + 128)>> 8);
B = clip255(( 298 * C + 516 * D + 128) >> 8);
// R = clip255( round(1.164383 * C + 1.596027* E ) )
// G = clip255( round(1.164383 * C - (0.391762 * D) - (0.812968 * E) ) )
// B = clip255( round(1.164383 * C + 2.017232 * D ) )
*(RGBbuff) = B;
*(++RGBbuff) = G;
*(++RGBbuff) = R;
Y = Y1;
C = Y-16;
D = U-128;
E = V-128;
R = clip255(( 298 * C + 409 * E + 128) >> 8);
G = clip255(( 298 * C - 100 * D - 208 * E + 128)>> 8);
B = clip255(( 298 * C + 516 * D + 128) >> 8);
*(++RGBbuff) = B;
*(++RGBbuff) = G;
*(++RGBbuff) = R;
++RGBbuff;
}
}
unsigned char clip255(long v)
{
if(v < 0) v=0;
else if( v > 255) v=255;
return (unsigned char)v;
}
2. 把它加到程序中了, 终于是不再down了,用两台机器进行调试,发现传过来的图像居然是倒立的!(就是说:现在要对该图像进行翻转,才能达到与原图像相同) ,是否可以在调 DrawDibDraw 函数前对它的参数rgbdata,进行处理,但是如何处理才能达到我的目的呢?
于是,我用了最简单的 1和end元素交换的方法(参见贴的代码)_,可以得到不倒立的图像了,但颜色又发生了变化。
最简单的翻转:
void CVideoNetDlg::SwapArray(unsigned char *pS,UINT dwCount)
{
char temp;
for (UINT i = 0; i < dwCount / 2; i++)
{
temp = pS[i];
pS[i] = pS[dwCount - i -1];
pS[dwCount - i - 1] = temp;
}
}
所以,判断还是这里出了问题, 后来咨询我的前同事, HJB 终于给我指出了明路:把第一行与最后一行进行交换,第二行与倒数第二行进行交换…. 依次类推,于是我又写了个函数:
/************************************************************************/
/* 函数名称: SwapArrayljh2
/* 参数:unsigned char *pS,long dwCount
ps 数组名 dwcount 数组大小
// 进行交换数组的元素
// R G B R G B ......... (176 个 RGB ) 即:176 * 3 =
// R G B R G B .........
// R G B R G B .........
//.... 共 144 行
// 1) 将最后一行换到第一行, 依次类推;
// 2) 将每行的第一个点换到最后一个点, 依次类推; (参见注释:该操作不需要)
/* 返回值:void
/* 作者:ljhua
/* 时间:2012-08-11
/************************************************************************/
void CVideoNetDlg::SwapArrayljh2(unsigned char*pS, long dwCount)
{
chartemp;
longnToSwap = 0; // 要交换的序列号
longnLineSr = 0; //当前所在行数
longnPerLineTotal = IMAGE_WIDTH*3; // 每行的总个数 528
// 先进行 1) 操作
for(long i = 0; i < dwCount/2; i++)
{
nLineSr = i/nPerLineTotal; // 当前所在行数 0--527 第 0 行;528-1057 第1行
nToSwap= (IMAGE_HEIGHT - nLineSr-1)*nPerLineTotal + (i % nPerLineTotal);
temp= pS[i];
pS[i]= pS[nToSwap];
pS[nToSwap]= temp;
}
// 再进行 2) 操作:
// for(long j = 0; j< IMAGE_HEIGHT; j++) // 144 行每行都要进行交换
// {
// longnBase = (j*nPerLineTotal);
// intnBaseSub = 0;
// for(long i = nBase; i< (nBase+(nPerLineTotal)/2); i++)
// {
// if (0 == (i - nBase) % 3 )
// {
// nBaseSub= (i - nBase);
// }
//
// nToSwap= nBase + (525-nBaseSub) + (i % 3);
//
// temp= pS[i];
// pS[i]= pS[nToSwap];
// pS[nToSwap]= temp;
// }
// }
}
这样放到代码中,唉! 总算是解决问题了!
修改后的源代码放在csdn的资源库中,供大家免费下载!