opencv ---getRotationMatrix2D函数
getRotationMatrix2D函数
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h> using namespace cv;
using namespace std; /// 全局变量
char* source_window = "Source image";
char* warp_window = "Warp";
char* warp_rotate_window = "Warp + Rotate"; /** @function main */
int main( int argc, char** argv )
{
Point2f srcTri[3];
Point2f dstTri[3]; Mat rot_mat( 2, 3, CV_32FC1 );
Mat warp_mat( 2, 3, CV_32FC1 );
Mat src, warp_dst, warp_rotate_dst; /// 加载源图像
src = imread( argv[1], 1 ); /// 设置目标图像的大小和类型与源图像一致
warp_dst = Mat::zeros( src.rows, src.cols, src.type() ); /// 设置源图像和目标图像上的三组点以计算仿射变换
srcTri[0] = Point2f( 0,0 );
srcTri[1] = Point2f( src.cols - 1, 0 );
srcTri[2] = Point2f( 0, src.rows - 1 ); dstTri[0] = Point2f( src.cols*0.0, src.rows*0.33 );
dstTri[1] = Point2f( src.cols*0.85, src.rows*0.25 );
dstTri[2] = Point2f( src.cols*0.15, src.rows*0.7 ); /// 求得仿射变换
warp_mat = getAffineTransform( srcTri, dstTri ); /// 对源图像应用上面求得的仿射变换
warpAffine( src, warp_dst, warp_mat, warp_dst.size() ); /** 对图像扭曲后再旋转 */ /// 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵
Point center = Point( warp_dst.cols/2, warp_dst.rows/2 );
double angle = -50.0;
double scale = 0.6; /// 通过上面的旋转细节信息求得旋转矩阵
rot_mat = getRotationMatrix2D( center, angle, scale ); /// 旋转已扭曲图像
warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() ); /// 显示结果
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src ); namedWindow( warp_window, CV_WINDOW_AUTOSIZE );
imshow( warp_window, warp_dst ); namedWindow( warp_rotate_window, CV_WINDOW_AUTOSIZE );
imshow( warp_rotate_window, warp_rotate_dst ); /// 等待用户按任意按键退出程序
waitKey(0); return 0;
}
说明
定义一些需要用到的变量, 比如需要用来储存中间和目标图像的Mat和两个需要用来定义仿射变换的二维点数组.
Point2f srcTri[3];
Point2f dstTri[3]; Mat rot_mat( 2, 3, CV_32FC1 );
Mat warp_mat( 2, 3, CV_32FC1 );
Mat src, warp_dst, warp_rotate_dst;加载源图像:
src = imread( argv[1], 1 );
以与源图像同样的类型和大小来对目标图像初始化:
warp_dst = Mat::zeros( src.rows, src.cols, src.type() );
仿射变换: 正如上文所说, 我们需要源图像和目标图像上分别一一映射的三个点来定义仿射变换:
srcTri[0] = Point2f( 0,0 );
srcTri[1] = Point2f( src.cols - 1, 0 );
srcTri[2] = Point2f( 0, src.rows - 1 ); dstTri[0] = Point2f( src.cols*0.0, src.rows*0.33 );
dstTri[1] = Point2f( src.cols*0.85, src.rows*0.25 );
dstTri[2] = Point2f( src.cols*0.15, src.rows*0.7 );你可能想把这些点绘出来以获得对变换的更直观感受. 他们的位置大概就是在上面图例中的点的位置 (原理部分). 你会注意到由三点定义的三角形的大小和方向改变了.
通过这两组点, 我们能够使用OpenCV函数 getAffineTransform 来求出仿射变换:
warp_mat = getAffineTransform( srcTri, dstTri );
我们获得了用以描述仿射变换的
矩阵 (在这里是 warp_mat)将刚刚求得的仿射变换应用到源图像
warpAffine( src, warp_dst, warp_mat, warp_dst.size() );
函数有以下参数:
- src: 输入源图像
- warp_dst: 输出图像
- warp_mat: 仿射变换矩阵
- warp_dst.size(): 输出图像的尺寸
这样我们就获得了变换后的图像! 我们将会把它显示出来. 在此之前, 我们还想要旋转它...
旋转: 想要旋转一幅图像, 你需要两个参数:
- 旋转图像所要围绕的中心
- 旋转的角度. 在OpenCV中正角度是逆时针的
- 可选择: 缩放因子
我们通过下面的代码来定义这些参数:
Point center = Point( warp_dst.cols/2, warp_dst.rows/2 );
double angle = -50.0;
double scale = 0.6;我们利用OpenCV函数 getRotationMatrix2D 来获得旋转矩阵, 这个函数返回一个
矩阵 (这里是 rot_mat)rot_mat = getRotationMatrix2D( center, angle, scale );
现在把旋转应用到仿射变换的输出.
warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() );
最后我们把仿射变换和旋转的结果绘制在窗体中,源图像也绘制出来以作参照:
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src ); namedWindow( warp_window, CV_WINDOW_AUTOSIZE );
imshow( warp_window, warp_dst ); namedWindow( warp_rotate_window, CV_WINDOW_AUTOSIZE );
imshow( warp_rotate_window, warp_rotate_dst );等待用户退出程序
waitKey(0);
结果
编译上述例程之后, 我们给出一个图像的路径作为参数. 比如这样一幅图片:

仿射变换后我们获得:

最后, 应用了一个负角度旋转 (记住负角度指的是顺时针) 和基于一个缩放因子的缩放之后, 我们得到:

转自:http://blog.csdn.net/qq_18343569/article/details/47952591
opencv ---getRotationMatrix2D函数的更多相关文章
- opencv —— getRotationMatrix2D、warpAffine 仿射变换实现图像旋转缩放
仿射变换的基本概念 仿射变换是一种二维坐标(x, y)到二维坐标(u, v)的线性变换,其数学表达式形式如下: 对应的齐次坐标矩阵表示形式为: 仿射变换保持了二维图形的“平直性”(直线经仿射变换后依然 ...
- opencv-6-图像绘制与opencv Line 函数剖析
opencv-6-图像绘制与opencv Line 函数剖析 opencvc++qt 开始之前 越到后面, 写的越慢, 之前还抽空去看了下 学堂在线那篇文章提供的方法, 博客第一个人评论的我, 想想还 ...
- 【记录一个问题】macos下lldb调试opencv的一个程序,出现“failed to load objfile for”错误,并且无法调试进入opencv的函数
opencv编译使用了Debug版本,打开了BUILD_WITH_DEBUG_INFO=ON选项. 发现问题后,我又在CMAKE_CXX_FLAGS_DEBUG中设置为 -g -ggdb3,在CMAK ...
- 学习OpenCV——Gabor函数的应用
原文:http://blog.csdn.net/yao_zhuang/article/details/2532279 下载cvgabor.cpp和cvgabor.h到你的C/C++工程目录下 注:在我 ...
- 【麦子学院】OpenCV教程函数总结
个自带样例. parter 1: No1. adaptiveskindetector.cpp 利用HSV空间的色调信息的皮肤检測,背景不能有太多与肤色相似的颜色.效果不是特别好. No2. bagof ...
- Opencv常用函数
一.图像读写与简单处理 1. Mat cv::imread(const String& filename, int flags=IMREAD_COLOR). imread函数加载filenam ...
- opencv: flip函数的使用;
flip函数用于图像翻转,比较方便.在opencv中有几种形式: C++: void flip(InputArray src, OutputArray dst, int flipCode) Pytho ...
- OpenCV绘图函数
OpenCV几个绘图函数 矩形 rectangle(Mat& img,Point pt1, Point pt2, const Scalar&color, int thickness=1 ...
- [opencv] copyTo函数的使用方法
OpenCV中image.copyTo()有两种形式: 1.image.copyTo(imageROI),作用是把image的内容粘贴到imageROI: 2.image.copyTo(imageRO ...
随机推荐
- 升级webpack2
更新:webpack3已经出来了,官方说从2到升级到3不用改一行配置,98%的人没有错误. 项目中用的是webpack1.webpack2已经出来一段时间了.决定升级.其实改动不是很大.修改加测试共花 ...
- sqlyog mysql 外键引用列找不到想要的字段的原因
这是因为引用列必须为一个主键才行
- python的多继承关系
python和C++一样,支持多继承.概念虽然容易,但是困难的工作是如果子类调用一个自身没有定义的属性,它是按照何种顺序去到父类寻找呢,尤其是众多父类中有多个都包含该同名属性. class P1 #( ...
- R绘图 第四篇:绘制箱图(ggplot2)
箱线图通过绘制观测数据的五数总括,即最小值.下四分位数.中位数.上四分位数以及最大值,描述了变量值的分布情况.箱线图能够显示出离群点(outlier),离群点也叫做异常值,通过箱线图能够很容易识别出数 ...
- 移动端H5页面上传图片或多张图片
传统PC网页上传文件,大家都已经熟悉,这里不做介绍. 本文简单介绍移动端常用上传图片功能.灵活使用轮询或长连接可实现PC与移动端数据同步,即PC端需要上传的图片是移动拍照下来或移动端硬盘储存的,不需要 ...
- 基于AngularJs的单页面程序
基于AngularJs的单页面程序 在Abpzero的后台管理系统是一个AngularJs的单页面程序.当你登陆后,系统会跳转到"ApplicationController",然后 ...
- Js_图片切换左右点击
<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content=&q ...
- 阿里云rds 备份和还原
阿里云rds 备份和还原 转发:https://www.cnblogs.com/lin1/p/8617764.html 转发:https://help.aliyun.com/knowledge_det ...
- Svn 提示错误:previous operation has not finished 解决方案
svn提交遇到恶心的问题,可能是因为上次cleanup中断后,进入死循环了. 解决方案: 找到你项目的.svn文件,查看是否存在wc.db 网上下载SQLite Expert工具,手动打开wc.db, ...
- Hyperledger Fabric的一些密码学常识
Hash 哈希(Hash)算法主要作用是将一段任意长度的数据,经过计算转换成一段定长的数据. 这种算法的特性是:几乎不能通过Hash的结果推导出原文.并且几乎没有可能找到两个不同的信息,对两个信息进行 ...