图像旋转+二线性插值算法

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;
}

学习考研数学中的线代数,你可以按照以下步进行准备: 1. 理论学习:先系统地学习线代数的基本概念、定理和质。可以选择一本权威的线代数教材,如《线代数》(李尚志)、《高等代数学》(郑光荣)等,逐章深入学习。 2. 刷题巩固:理论学习后,需要通过大量的练习题来巩固知识。可以使用教材中的习题,或者参考其他线代数的习题集,如《高等数学(理工类)习题解答与解析》(北京大学出版社)等。要注意选择难度适当的题目,从基础题开始逐渐提高。 3. 做真题和模拟考试:在考研复习过程中,要充分利用历年真题和模拟考试。可以在网络上搜索并下载往年的考研数学真题及其答案,进行针对练习和模拟考试。通过做真题,你可以熟悉考试形式和题型,提高解题速度和答题技巧。 4. 寻找辅导资料和在线课程:线代数是一个较为基础和广泛的数学学科,有很多优秀的辅导资料和在线课程可供参考。你可以在网上寻找相应的视频教程、讲义或课程笔记,以帮助更好地理解和掌握线代数的知识。 5. 加强与习题解析的联系:在学习线代数的过程中,要注重与习题解析的联系。对于每个习题,要认真思考解题思路和方法,理解习题解析中的每一步骤。这样能够提高解题能力和逻辑思维能力。 6. 组织学习时间和复习计划:制定合理的学习时间表和复习计划,将线代数的学习安排到每天的学习计划中。保持持续的学习态度和规律的复习,有助于更好地掌握线代数的知识。 最重要的是坚持不懈地学习和练习,多思考、多实践,才能在考研数学中取得好成绩。祝你考研顺利,加油!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值