实际项目中用到了彩色图像到灰度图像的转换,算法上没什么好说的,关键在于速度,国外的halcon的公司是公认的做图像处理算法很牛的公司,可是他们的这个彩色转灰度的函数还是比较满足不了实际的应用,为此,自己写这么一个函数,经过测试,我的这个函数在同样的测试环境下,速度是halcon的6倍。显示了MMX,SSE技术的强大。
void MMX_colortogray(_MMx_colortogray* rclData)
{
_asm
{
mov esi,rclData
pxor MM1,MM1
mov eax ,[esi]_MMx_colortogray.coefb
movd MM7,eax
PSHUFW MM7,MM7,0
mov eax ,[esi]_MMx_colortogray.coefg
movd MM6,eax
PSHUFW MM6,MM6,0
mov eax,[esi]_MMx_colortogray.coefr
movd MM5,eax
PSHUFW MM5,MM5,0
mov edi,[esi]_MMx_colortogray.colorprB
mov ebx,[esi]_MMx_colortogray.colorprG
mov eax,[esi]_MMx_colortogray.colorprR
mov edx,[esi]_MMx_colortogray.graypr
mov ecx,[esi]_MMx_colortogray.count
test ecx,ecx
lea edi,[edi+4*ecx]
lea ebx,[ebx+4*ecx]
lea eax,[eax+4*ecx]
lea edx,[edx+4*ecx]
neg ecx
push ebp
loop_start:
movd MM0,[edi+4*ecx]
PUNPCKLBW MM0,MM1
movd MM2,[ebx+4*ecx]
PUNPCKLBW MM2,MM1
MOVD MM3,[eax+4*ecx]
PUNPCKLBW MM3,MM1
PMULLW MM0,MM7
PMULLW MM2,MM6
PMULLW MM3,MM5
PADDUSW MM0,MM2
PADDUSW MM0,MM3
PSRLW MM0,8
PACKUSWB MM0,MM0
MOVD [edx+4*ecx],MM0
inc ecx
jnz loop_start
}
_asm
{
pop ebp
EMMS
}
}
void MMX_ColorConvertGray(char* ColorprR,char *ColorprG,char* ColorprB ,
char* Graypr,double r,double g,double b,
long width,long height,RECT ROI)
{
long lLinebytes=WIDTHBYTTE(width);
_MMx_colortogray Tdata;
char *prB=ColorprB+(ROI.top)*lLinebytes+ROI.left;
char *prG=ColorprG+(ROI.top)*lLinebytes+ROI.left;
char *prR=ColorprR+(ROI.top)*lLinebytes+ROI.left;
long roi_width;
long roi_height;
roi_width=fabs(ROI.right-ROI.left)+1;
roi_height=fabs(ROI.bottom-ROI.top)+1;
long roi_linebytes=WIDTHBYTTE(roi_width);
long lb=b*(1<<8);
long lg=g*(1<<8);
long lr=r*(1<<8);
Tdata.coefb=lb;
Tdata.coefg=lg;
Tdata.coefr=lr;
Tdata.count=(int)(roi_linebytes/4+1);
char* copyprb=prB;
char* copyprg=prG;
char* copyprr=prR;
char* copygary=Graypr;
int y=0;
while (true)
{
if(y>=roi_height-1) break;
Tdata.colorprB=copyprb;
Tdata.colorprG=copyprg;
Tdata.colorprR=copyprr;
Tdata.graypr=copygary;
MMX_colortogray(&Tdata);
copyprb+=lLinebytes;
copyprg+=lLinebytes;
copyprr+=lLinebytes;
copygary+=roi_linebytes;
++y;
}
}