OpenCV 下的图像任意角度的旋转

//OpenCV 下的图像任意角度的旋转
//需要intel公司的OpenCV的支持.
//OpenCV 4下的图像任意角度的旋转
//待旋转的图像IplImage* Img_old
//返回的旋转后图像 IplImage* Img_tmp.
//旋转的角度,单位度.
//三种不同的方法.其中方法二没有完全测试,方法一可以满足大部分需要
//Vastsky - Nercita   2005 6 12  
//vastsky_sun#126.com
IplImage * CCropMeasureView::FitRotate (IplImage* Img_old, double angle,int method)
{
	IplImage* Img_tmp = NULL; 
	double anglerad  = (CV_PI* (angle/180)) ;
	int newheight =int (fabs(( sin(anglerad)*Img_old->width )) + fabs(( cos(anglerad)*Img_old->height )) );
	int newwidth  =int (fabs(( sin(anglerad)*Img_old->height)) + fabs(( cos(anglerad)*Img_old->width)) );
	Img_tmp = cvCreateImage(cvSize(newwidth,newheight), IPL_DEPTH_8U, 3);
	cvFillImage(Img_tmp,0);//目的图像 使用扩展的大小
	IplImage* dst = cvCloneImage( Img_old );//目的图像 与原图像等大  
	float m[6];            
	CvMat M = cvMat( 2, 3, CV_32F, m );
	if(1==method)
	{
		//方法一  提取象素四边形,使用子象素精度
		int w = Img_old->width;
		int h = Img_old->height;
		m[0] = (float)(cos(angle*CV_PI/180.));
		m[1] = (float)(sin(angle*CV_PI/180.));
		m[2] = w*0.5f;
		m[3] = -m[1];
		m[4] = m[0];
		m[5] = h*0.5f;
		cvGetQuadrangleSubPix( Img_old, dst, &M, 1, cvScalarAll(0));
		cvGetQuadrangleSubPix( Img_old, Img_tmp, &M, CV_INTER_LINEAR, cvScalarAll(0));//+CV_WARP_FILL_OUTLIERS
		//方法一  提取象素四边形,使用子象素精度
	}
	if(2==method)
	{
		//方法二 使用 二维旋转的仿射变换矩阵 存在问题 要求输入和输出图像一样大 旋转中心不对
		CvPoint2D32f center;
		center.x=float (Img_old->width/2.0+0.5);//float (Img_tmp->width/2.0+0.5);
		center.y=float (Img_old->height/2.0+0.5);//float (Img_tmp->height/2.0+0.5);   
		cv2DRotationMatrix( center, angle,1, &M);
		cvWarpAffine( Img_old, dst, &M,CV_INTER_LINEAR,cvScalarAll(0) );//小图
		//小目标图像
		//对图像进行扩展
		//只能一定角度以内 不同象限的不同对待
		int dx=int((newwidth -Img_old->width )/2+0.5);
		int dy=int((newheight-Img_old->height)/2+0.5); 
		uchar* old_ptr,*temp_ptr;
		for( int y=0 ; y<Img_old->height; y++) //为了不越界
		{ 
			for (int x=0 ; x< Img_old->width; x++)
			{
				old_ptr = &((uchar*)(Img_old->imageData + Img_old->widthStep*y))[(x)*3];
				temp_ptr = &((uchar*)(Img_tmp->imageData + Img_tmp->widthStep*(y+dy)))[(x+dx)*3];
				temp_ptr[0]=old_ptr[0]; //green 
				temp_ptr[1]=old_ptr[1]; //blue
				temp_ptr[2]=old_ptr[2]; //Red
			}
		}
		center.x=float (Img_tmp->width/2.0+0.5);
		center.y=float (Img_tmp->height/2.0+0.5);   
		cv2DRotationMatrix( center, angle,1, &M);
		IplImage* temp = cvCloneImage( Img_tmp );//生成输出图像 
		cvWarpAffine( Img_tmp, temp    , &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) );//大图
		Img_tmp=cvCloneImage( temp );
		//问题
		//cvWarpAffine( Img_tmp, Img_tmp, &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) );//大图
		//方法二 使用 二维旋转的仿射变换矩阵
	}
	if(3==method)
	{
		//方法三 透视变换
		CvPoint2D32f src_point[4];
		CvPoint2D32f dst_point[4];
		src_point[0].x=0.0;                    
		src_point[0].y=0.0;
		src_point[1].x=0.0;                    
		src_point[1].y=(float) Img_old->height; 
		src_point[2].x=(float) Img_old->width; 
		src_point[2].y=(float) Img_old->height;
		src_point[3].x=(float) Img_old->width; 
		src_point[3].y=0.0;


		dst_point[0].x=0;               
		dst_point[0].y=(float) fabs(( sin(anglerad)*Img_old->width ));

		dst_point[1].x=(float) fabs(( sin(anglerad)*Img_old->height));              
		dst_point[1].y=(float) fabs(( sin(anglerad)*Img_old->width ))+(float) fabs(( cos(anglerad)*Img_old->height));

		dst_point[2].x=(float) fabs(( sin(anglerad)*Img_old->height))+(float) fabs(( cos(anglerad)*Img_old->width));
		dst_point[2].y=(float) fabs(( cos(anglerad)*Img_old->height));

		dst_point[3].x=(float) fabs(( cos(anglerad)*Img_old->width));
		dst_point[3].y=0;


		float newm[9];            
		CvMat newM = cvMat( 3, 3, CV_32F, newm );
		cvWarpPerspectiveQMatrix(src_point,dst_point,&newM);

		cvWarpPerspective(Img_old,dst,&newM,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0) );
		cvWarpPerspective(Img_old,Img_tmp,&newM,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0) );

		//方法三 透视变换
	}
	//  cvNamedWindow( "dst_litter", 1 );
	//  cvShowImage( "dst_litter", dst );
	// cvNamedWindow( "dst_big", 1 );
	// cvShowImage( "dst_big", Img_tmp );
	return Img_tmp;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值