opencv实现图像旋转

1.旋转后图像变大,但是原图像部分保持不变

法1:

#include "cv.h"
#include "highgui.h"

int main()
{
	double degree = 30; // rotate 30 degree
	double angle = degree  * CV_PI / 180.; // angle in radian
	double a = sin(angle), b = cos(angle); // sine and cosine of angle

	// Load source image as you wish
	IplImage *imgSrc = cvLoadImage("l:\\test\\5.jpg");
	int w_src = imgSrc->width;
	int h_src = imgSrc->height;
	cvNamedWindow ("src", 1);
	cvShowImage ("src", imgSrc);
	// Make w_dst and h_dst to fit the output image
	int w_dst = int(h_src * fabs(a) + w_src * fabs(b));
	int h_dst = int(w_src * fabs(a) + h_src * fabs(b));

	// map matrix for WarpAffine, stored in statck array
	double map[6];
	CvMat map_matrix = cvMat(2, 3, CV_64FC1, map);

	// Rotation center needed for cv2DRotationMatrix
	CvPoint2D32f pt = cvPoint2D32f(w_src / 2, h_src / 2);
	cv2DRotationMatrix(pt, degree, 1.0, &map_matrix);

	// Adjust rotation center to dst's center,
	// otherwise you will get only part of the result
	map[2] += (w_dst - w_src) / 2;
	map[5] += (h_dst - h_src) / 2;


	// We need a destination image

	IplImage *imgDst = cvCreateImage(cvSize(w_dst, h_dst), 8, 3);
	cvWarpAffine(
		imgSrc, 
		imgDst,
		&map_matrix,
		CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS,
		cvScalarAll(0)
		);

	// Don't forget to release imgSrc and imgDst if you no longer need them
	cvNamedWindow( "dst_big", 1 );
	cvShowImage( "dst_big", imgDst);
	cvWaitKey(0);
	cvReleaseImage(&imgSrc);
	cvReleaseImage(&imgDst);
	return 0;
}

 

法2:

#include "cv.h"
#include "highgui.h"
#include "math.h"

// clockwise 为true则顺时针旋转,否则为逆时针旋转
IplImage* rotateImage(IplImage* src, int angle, bool clockwise)
{
	angle = abs(angle) % 180;
	if (angle > 90)
	{
		angle = 90 - (angle % 90);
	}
	IplImage* dst = NULL;
	int width =
		(double)(src->height * sin(angle * CV_PI / 180.0)) +
		(double)(src->width * cos(angle * CV_PI / 180.0 )) + 1;
	int height =
		(double)(src->height * cos(angle * CV_PI / 180.0)) +
		(double)(src->width * sin(angle * CV_PI / 180.0 )) + 1;
	int tempLength = sqrt((double)src->width * src->width + src->height * src->height) + 10;
	int tempX = (tempLength + 1) / 2 - src->width / 2;
	int tempY = (tempLength + 1) / 2 - src->height / 2;
	int flag = -1;

	dst = cvCreateImage(cvSize(width, height), src->depth, src->nChannels);
	cvZero(dst);
	IplImage* temp = cvCreateImage(cvSize(tempLength, tempLength), src->depth, src->nChannels);
	cvZero(temp);

	cvSetImageROI(temp, cvRect(tempX, tempY, src->width, src->height));
	cvCopy(src, temp, NULL);
	cvResetImageROI(temp);

	if (clockwise)
		flag = 1;

	float m[6];
	int w = temp->width;
	int h = temp->height;
	m[0] = (float) cos(flag * angle * CV_PI / 180.);
	m[1] = (float) sin(flag * angle * CV_PI / 180.);
	m[3] = -m[1];
	m[4] = m[0];
	// 将旋转中心移至图像中间
	m[2] = w * 0.5f;
	m[5] = h * 0.5f;
	//
	CvMat M = cvMat(2, 3, CV_32F, m);
	cvGetQuadrangleSubPix(temp, dst, &M);
	cvReleaseImage(&temp);
	return dst;
}

int main(int argc, char **argv)
{
	IplImage *src = 0;
	IplImage *dst = 0;

	int angle = 75;

	src = cvLoadImage("L:\\Test\\6.JPG");

	dst = rotateImage(src, angle, false);
	cvNamedWindow("dst", 1);
	cvShowImage("dst", dst);
	cvWaitKey(0);

	cvReleaseImage(&src);
	cvReleaseImage(&dst);
	return 0;
}



2.图像大小始终不变,实现裁剪

法1:

#include "cv.h"
#include "highgui.h"
#include "math.h"
void main( )
{
	IplImage *Img_old=cvLoadImage("L:\\Test\\6.JPG");
	IplImage* Img_tmp =cvCloneImage( Img_old); 

	int angle=45;
	float m[6];            
	CvMat M = cvMat( 2, 3, CV_32F, m );
	CvPoint2D32f center;
	center.x=float (Img_old->width/2.0+0.5);
	center.y=float (Img_old->height/2.0+0.5);   
	cv2DRotationMatrix( center, angle,1, &M);

	cvWarpAffine(Img_old,Img_tmp, &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0) );

	cvNamedWindow ("src", 1);
	cvShowImage ("src", Img_old);
	cvNamedWindow( "dst", 1 );
	cvShowImage( "dst", Img_tmp );

	cvWaitKey(0);
	cvReleaseImage(&Img_old);
	cvReleaseImage(&Img_tmp);
}

 

法2:

#include "cv.h"
#include "highgui.h"
#include "math.h"
void main( )
{
	IplImage *Img_old=cvLoadImage("L:\\Test\\6.JPG");
	IplImage* Img_tmp = NULL; 

	int angle=45;
	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);

	//对图像进行扩展
	//只能一定角度以内 不同象限的不同对待
	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
		}
	}//这里去掉就不行了

	float m[6];            
	CvMat M = cvMat( 2, 3, CV_32F, m );
	CvPoint2D32f center;
	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 );

	cvNamedWindow ("src", 1);
	cvShowImage ("src", Img_old);
	cvNamedWindow( "dst", 1 );
	cvShowImage( "dst", Img_tmp );
	cvWaitKey(0);
	cvReleaseImage(&Img_old);
	cvReleaseImage(&Img_tmp);
}


 

3.图像大小不变,原图像内容也均保留,但是是由缩放所达到的

#include "cv.h"
#include "highgui.h"

int _tmain(int argc, _TCHAR* argv[])
{
   CvPoint2D32f srcTri[3],dstTri[3];
   CvMat* rot_mat=cvCreateMat(2,3,CV_32FC1);
   CvMat* warp_mat=cvCreateMat(2,3,CV_32FC1);
   IplImage *src,*dst;

   if(argc==2 && ((src=cvLoadImage(argv[1],1))!=0))
   {
      dst=cvCloneImage(src);
      dst->origin =src->origin ;
      cvZero(dst);
      //compute warp matrix
      srcTri[0].x =0;                            //src top left
      srcTri[0].y=0;
      srcTri[1].x =src->width -1;         //src top right
      srcTri[1].y=0;
      srcTri[2].x=0;                            //src bottom left offset
      srcTri[2].y=src->height -1;
      dstTri[0].x=src->width *0.0;       //dst top left
      dstTri[0].y=src->height *0.33;
      dstTri[1].x=src->width *0.85;     //dst top right
      dstTri[1].y=src->height *0.25;
      dstTri[2].x=src->width *0.15;     //dst bottom left offset
      dstTri[2].y=src->height *0.7;
      cvGetAffineTransform(srcTri,dstTri,warp_mat);
      cvWarpAffine(src,dst,warp_mat);
      cvCopy(dst,src);
      //compute rotation matrix
      CvPoint2D32f center=cvPoint2D32f(src->width /2,src->height /2);
      double angle=-50.0;
      double scale=0.6;
      cv2DRotationMatrix(center,angle,scale,rot_mat);
      //do the transformation
      cvWarpAffine(src,dst,rot_mat);
      cvNamedWindow("Affine_Transform",1);
      cvShowImage("Affine_Transform",dst);
      cvWaitKey();
    }

   cvReleaseImage(&dst);
   cvReleaseMat(&rot_mat);
   cvReleaseMat(&warp_mat);
   return 0;
}


 

 

  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值