图像旋转+二线性插值算法
2012-12-21 18:44
260 查看
long BilinearInterpolateD( const SwImage & pic,double fx,double fy ) { #define BILINEAR4_UNITRPOC(a,b,c,d) ((a<<22) +(b-a)*rx2048 + (c-a)*ry2048 + (a-b-c+d)*rxry ) long x = (long)fx; long y = (long)fy; unsigned char * c0 = ( unsigned char* )(pic.buffer) + ((pic.width * y + x)<<2); unsigned char * c2 = c0 + ( pic.width <<2 ); long rx = (long)(( fx - x ) * 2048); long ry = (long)(( fy - y ) * 2048); long rx2048 = rx << 11; long ry2048 = ry << 11; long rxry = rx * ry; long rr = BILINEAR4_UNITRPOC( *(c0+2), *(c0+6), *(c2+2), *(c2+6) ); long gg = BILINEAR4_UNITRPOC( *(c0+1), *(c0+5), *(c2+1), *(c2+5) ); long bb = BILINEAR4_UNITRPOC( *(c0), *(c0+4), *(c2), *(c2+4) ); return ((rr>>22<<16) | (gg>>22<<8) | bb>>22); #undef BILINEAR4_UNITRPOC } //使用SSE汇编指令集
BOOL SwImgRotateBilinearSSE( SwImage * pPicDest, const SwImage & picSrc, float angle ) { long srcw = picSrc.width; long srch = picSrc.height; long halfsrcw = srcw >> 1; long halfsrch = srch >> 1; long neg_halfsrcw = -halfsrcw; long neg_halfsrch = -halfsrch; long destw = 0; long desth = 0; SwColor * pDest = NULL; long isx = 0; long isy = 0; __declspec(align(16)) float arc = angle * _PI_DIV_180_FS; __declspec(align(16)) float sina = sin( arc ); __declspec(align(16)) float cosa = cos( arc ); __declspec(align(16)) float fhalfsrcw = (float)srcw * 0.5f; __declspec(align(16)) float fhalfsrch = (float)srch * 0.5f; SwImgCalcRotExtent( srcw, srch, sina, cosa, &destw, &desth ); if( ( destw <= 0 ) || ( desth <= 0 ) ) return FALSE; SwImgAlloc( pPicDest, destw, desth ); pDest = pPicDest->buffer; __declspec(align(16)) float srcx0 = -(destw * 0.5f)*cosa + (-(desth * 0.5f)*sina); __declspec(align(16)) float srcy0 = -(destw * 0.5f)*sina - (-(desth * 0.5f)*cosa); __declspec(align(16)) float fsx = 0; __declspec(align(16)) float fsy = 0; _asm movaps xmm0,srcx0 _asm movaps xmm1,srcy0 for (int y = 0; y < desth; y++) { _asm movaps xmm2,xmm0 _asm movaps xmm3,xmm1 for ( int x = 0; x < destw; x++) { __asm { cvtss2si eax,xmm2 // if( isx > halfsrcw || isx < neg_halfsrcw ) goto over; cmp eax,halfsrcw jg LOOP2_OVER cmp eax,neg_halfsrcw jl LOOP2_OVER cvtss2si eax,xmm3 // if( isy > halfsrch || isy < neg_halfsrch ) goto over; cmp eax,halfsrch jg LOOP2_OVER cmp eax,neg_halfsrch jl LOOP2_OVER movss xmm4,xmm2 movss xmm5,xmm3 addss xmm4,fhalfsrcw subss xmm5,fhalfsrch movss fsx,xmm4 movss fsy,xmm5 // 将 fsy 绝对值,并截取整数部分到 isy fld dword ptr[fsy] fabs fst dword ptr[fsy] fisttp dword ptr[isy] // 因为 BinlinearInterpolate4 并不进行任何的参数检查 // 所以这里进行预先判断 cvtss2si eax,xmm4 // eax = (int)fsx add eax,2 cmp eax,srcw jnb LOOP2_OVER mov eax,isy add eax,2 cmp eax,srch jnb LOOP2_OVER // 将参数压放栈中,调用函数 BinlinearInterpolate4 fld dword ptr[fsy] sub esp,8 fstp qword ptr[esp] fld dword ptr[fsx] sub esp,8 fstp qword ptr[esp] mov eax,dword ptr[picSrc] push eax call BilinearInterpolateD add esp,14h // 现在将函数的返回值赋给 p[x] mov ecx,dword ptr[x] mov edx,dword ptr[pDest] mov dword ptr[edx+ecx*4],eax LOOP2_OVER: addss xmm2,cosa addss xmm3,sina } } pDest += destw; _asm addss xmm0,sina _asm subss xmm1,cosa } return TRUE; }
相关文章推荐
- Android OpenGL YUV 旋转花屏解决、Camera获取图像
- leetcode。 48. 旋转图像
- 图像旋转
- ov5642图像旋转方法
- 图像旋转算法原理
- YUV420SP图像旋转算法
- Java实现-旋转图像
- CImage图像旋转与缩放
- C++算法,将一个图像逆时 针旋转 90 度
- C/C++ BMP(24位真彩色)图像处理(4)------图像の旋转
- 【数字图像处理】<纯C++>读取、裁剪、缩放、旋转和存储8位bmp灰度图像
- 《Computer Vision:Algorithms and Applications》学习笔记(一)——图像旋转算法与实现
- C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)
- Leetcode刷题记——48. Rotate Image(旋转图像)
- 图像旋转 20150301
- 09:图像旋转翻转变换
- (2015年郑州轻工业学院ACM校赛题)I 旋转图像
- OpenCv调整图像大小及仿射变换(旋转)
- 使用方向梯度直方图估计图像旋转角度
- C/C++ BMP(24位真彩色)图像处理(4)------图像の旋转