注册 登录
  • 注册时,本站名称为:RGB空格3S博客,注意中间的空格。
  • 2018.10.14本人利用业余时间接遥感数据处理与编程小活,欢迎骚扰,QQ:853060844
  • 2018.8.14本站全面接入google广告
  • 本人闲暇时间(周末及其他闲暇时间)接遥感图像处理与IDL编程小活,欢迎骚扰,qq:853060844
  • 2017.2.14今天收到45条恶意评论(全是外文),故评论时请填写必要信息,匿名评论全部拉黑,迫不得已而为之
  • 2017.1.27,2017年春节及至,我谨代表本人祝大家新春快乐,本人年终总结文章请访问:2016年终总结
  • 为防止恶意转载,本站全面禁止复制,并添加图片水印:RGB 3S博客www.ixxin.cn。
  • 本站正式更名为RGB 3S博客,本站将撤消所有非3S内容,其将转移到新博客江湖时代

Opencv学习一之图像旋转

C/C++ admin 1824次浏览 已收录 2个评论
[隐藏]

前言

Opencv中是没有直接图像旋转的函数的,只能通过仿射变换实现,但在实现过程中会出现部门内容被裁剪的情况,在解决这个问题上,耗费了一点时间,走了一些弯路,故记录之。
Opencv各版本可在:https://www.ixxin.cn/software.html下载到,需要注意的是Opencv版本越高,支持的VS版本也越高。

主要问题

主要问题就是,旋转后,图像会变大,如图:
bigger
解决方法:
解决方法
第二个问题就是,把图像比例放大后,旋转中心不会变,导致图像还是被裁切状态,如图:
问题
解决方法就是把旋转中心移到新生成图像的中点。

代码

Opencv1代码:

 
IplImage* rotateImage1(IplImage* img,int degree){  
    double angle = degree  * CV_PI / 180.;   
    double a = sin(angle), b = cos(angle);   
    int width = img->width;    
    int height = img->height;    
    int width_rotate= int(height * fabs(a) + width * fabs(b));    
    int height_rotate=int(width * fabs(a) + height * fabs(b));    
    // [ m0  m1  m2 ] ===>  [ A11  A12   b1 ]  
    // [ m3  m4  m5 ] ===>  [ A21  A22   b2 ]  
    float map[6];  
    CvMat map_matrix = cvMat(2, 3, CV_32F, map);    
    CvPoint2D32f center = cvPoint2D32f(width / 2, height / 2);    
    cv2DRotationMatrix(center, degree, 1.0, &map_matrix);    
    map[2] += (width_rotate - width) / 2;    
    map[5] += (height_rotate - height) / 2;    
    IplImage* img_rotate = cvCreateImage(cvSize(width_rotate, height_rotate), 8, 3);   
    cvWarpAffine( img,img_rotate, &map_matrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(0));    
    return img_rotate;  
}  

Opencv2代码:(注:注释中有Opencv1的调试代码,可以忽略不看,本程序还实现了Opencv1跟Opencv2联合使用,转换的代码)

/*
作者:山科_xxin
时间:2017-03-19 23:04:38
功能:图像旋转
类别:Opencv学习
Opencv版本2.4.11
IDE:VS2010
*/
#include<iostream>
#include<stdlib.h>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
//#include<cv.h>
//#include<highgui.h>

using namespace std;
using namespace cv;

int fsbh(Mat srcimg)
{
	Mat dstimg;
	Mat rotimg;
	int row,col;
	Point2f srcTri[3];
	Point2f dstTri[3];
	Mat warpMat(2,3,CV_32FC1);//2*3矩阵,float类型;

	srcimg = imread("G:/opencv/1.jpg");
	if(!srcimg.data)
	{
		cout<<"读取错误"<<endl;
		return false;
	}
	row = srcimg.rows;
	col = srcimg.cols;
	cout<<"行:"<<row<<"列:"<<col<<endl;
	//三种方法创建
	//dstimg = Mat::zeros(srcimg.rows,srcimg.cols,srcimg.type());
	//dstimg = Mat::zeros(srcimg.size(),srcimg.type());
	//dstimg.create(srcimg.size(),srcimg.type());

	srcTri[0] = Point2f(0,0);
	srcTri[1] = Point2f(col-1,0);
	srcTri[2] = Point2f(0,row-1);

	dstTri[0] = Point2f( col*0.0, row*0.33 );
    dstTri[1] = Point2f( col*0.85, row*0.25 );
    dstTri[2] = Point2f( col*0.15, row*0.7 );

	warpMat = getAffineTransform(srcTri,dstTri);

	warpAffine(srcimg,dstimg,warpMat,dstimg.size());

	Point2f center(col/2,row/2);
	int degree = -30;  
	double angle = degree*CV_PI/180; //转换为弧度 
	double scale = 1;
	double a = sin(angle);
	double b = cos(angle);
	int width = col;
	int height = row;

	int rewidth = int(height*fabs(a)+width*fabs(b));
	int reheight = int(width*fabs(a)+height*fabs(b));
	cout<<rewidth<<endl<<reheight<<endl;
	Mat rot = getRotationMatrix2D(center,degree,scale);
	double* p = (double*)rot.data; 
	p[2] += (rewidth-width)/2;
	p[5] += (reheight-height)/2;
	//rotimg = Mat::zeros(rewidth,reheight,srcimg.type());
	//warpAffine(srcimg,rotimg,rot,srcimg.size(),0,0,0);
	warpAffine(srcimg,rotimg,rot,cv::Size(rewidth,reheight),0,0,0);
	/*
	//IplImage->Mat
	IplImage *ipimg;
	ipimg = &IplImage(srcimg);
	float map[6];
	CvMat map_matrix = cvMat(2,3,CV_32F,map);
	CvPoint2D32f center1 = cvPoint2D32f(width/2,height/2);
	cv2DRotationMatrix(center1, degree, 1.0, &map_matrix);
	map[2] += (rewidth - width)/2;    
    map[5] += (reheight - height)/2;
	IplImage* img_rotate = cvCreateImage(cvSize(rewidth, reheight), 8, 3);
	cvWarpAffine(ipimg,img_rotate, &map_matrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(0));
	Mat test = img_rotate;
	*/
	imshow("原图",srcimg);
	//imshow("变换后",dstimg);
	//namedWindow("30°旋转",1);
	imshow("30°旋转",rotimg);


	return 0;
}
int main()
{
	Mat srcimg;
	string filepath;
	filepath = "G:\\opencv\\1.jpg";
	srcimg = imread(filepath,1);
	fsbh(srcimg);
	waitKey(0);
	system("pause");
	return 0;

}

结果:
结果

后语(更新预告)

接下来会更新两个Python的模块,很有用的模块,还会更新学习Opencv(C++),GDAL(C++,Python),ENVI二次开发。


xxin blog , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Opencv学习一之图像旋转
喜欢 (5)
支付宝[853060844@qq.com]
分享 (0)
admin
关于作者:
坐标山科大遥感系小鲜肉一枚。
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(2)个小伙伴在吐槽
  1. 厉害了吆
    匿名2017-03-20 09:36 回复 iPhone 10_1_1 | 未知浏览器
    • 还是你厉害
      匿名2017-03-27 23:58 回复 Android 7.0 | Chrome 53.0.2785.49