在Python下利用OpenCV来旋转图像的教程


Posted in Python onApril 16, 2015

OpenCV是应用最被广泛的的开源视觉库。他允许你使用很少的代码来检测图片或视频中的人脸。

这里有一些互联网上的教程来阐述怎么在OpenCV中使用仿射变换(affine transform)旋转图片--他们并没有处理旋转一个图片里的矩形一般会把矩形的边角切掉这一问题,所以产生的图片需要修改。当正确的使用一点代码时,这是一点瑕疵。
 

def rotate_about_center(src, angle, scale=1.):
  w = src.shape[1]
  h = src.shape[0]
  rangle = np.deg2rad(angle) # angle in radians
  # now calculate new image width and height
  nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))*scale
  nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))*scale
  # ask OpenCV for the rotation matrix
  rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale)
  # calculate the move from the old center to the new center combined
  # with the rotation
  rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0]))
  # the move only affects the translation, so update the translation
  # part of the transform
  rot_mat[0,2] += rot_move[0]
  rot_mat[1,2] += rot_move[1]
  return cv2.warpAffine(src, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)

从原始图像的中心到目标图像的中心,在旋转中的仿射变换必须结合 仿射变换的平移。一个在平面中(2D)的仿射变换是一个2x2的矩阵A和一个平移的向量a-它取得原始点p = (x,y)到目标:Ap + a.结合了两次变换Ap + a和Bp+b,先做A然后是B,软后得到了 B(Ap + a)+ b --另一个与矩阵BA和向量Ba + b的仿射变换。

在此情况下,我们正在把旋转功能与平移合并。作为相似变换的平移具有2x2矩阵I与运动矢量m的特征,所以,以Ip + m表示,我们想首先平移到新的中心,饭后旋转它,这样,在应用Ip + m 后我们旋转Rp + r,产生Rp + Rm + r,这解释了为什么我们不得不只增加两个系数。

附言:悲哀地说,如果numpy把输入的数据看作是矢量的矢量,而不是矩阵,那解释了乘法算子不是矩阵乘法,所以,我们必须明确地写入np.dot。

又附言:我们使用兰索斯插值,这一般对扩展有利而对把规模缩得非常小不利;考虑到应用方面,我们应该改编这个插值。

再附言:与Python的相互作用因cv2模块而改善很多,但是因为numpy的坐标不同于OpenCV,所以仍不可避免地有一些为完善之处。另外,因某个原因,OpenCV始终把各单元当作度数而不是弧度使用,等等。就numpy而言,图像阵列中的坐标是以[y,x]次序存取的,如首先垂直向下增加,接着水平向右增加一样。就OpenCV而言,大小用(宽度,高度)表示,次序正相反。

Python 相关文章推荐
python实用代码片段收集贴
Jun 03 Python
python 网络爬虫初级实现代码
Feb 27 Python
如何利用Fabric自动化你的任务
Oct 20 Python
python 3.7.0 安装配置方法图文教程
Aug 27 Python
python数据批量写入ScrolledText的优化方法
Oct 11 Python
在python中使用with打开多个文件的方法
Jan 07 Python
pytorch实现从本地加载 .pth 格式模型
Feb 14 Python
Python 保存加载mat格式文件的示例代码
Aug 04 Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
Sep 21 Python
Python中过滤字符串列表的方法
Dec 22 Python
Python集合的基础操作
Nov 01 Python
解决Python保存文件名太长OSError: [Errno 36] File name too long
May 11 Python
在Python中使用Neo4j数据库的教程
Apr 16 #Python
使用Python的Zato发送AMQP消息的教程
Apr 16 #Python
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
Apr 16 #Python
使用Python编写一个简单的tic-tac-toe游戏的教程
Apr 16 #Python
Python基于scrapy采集数据时使用代理服务器的方法
Apr 16 #Python
在Python的gevent框架下执行异步的Solr查询的教程
Apr 16 #Python
使用Python的Treq on Twisted来进行HTTP压力测试
Apr 16 #Python
You might like
PHP开发之归档格式phar文件概念与用法详解【创建,使用,解包还原提取】
2017/11/17 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
2018/06/13 PHP
laravel-admin表单提交隐藏一些数据,回调时获取数据的方法
2019/10/08 PHP
jquery $.ajax入门应用一
2008/11/19 Javascript
JavaScript 三种不同位置代码的写法
2009/10/25 Javascript
JavaScript 字符串与数组转换函数[不用split与join]
2009/12/13 Javascript
javascript new一个对象的实质
2010/01/07 Javascript
javascript实现数字+字母验证码的简单实例
2014/02/10 Javascript
IE浏览器IFrame对象内存不释放问题解决方法
2014/08/22 Javascript
JS实现至少包含字母、大小写数字、字符的密码等级的两种方法
2015/02/03 Javascript
JavaScript时间转换处理函数
2015/04/14 Javascript
jquery+php实现滚动的数字特效
2015/11/29 Javascript
浅谈Vue2.0中v-for迭代语法的变化(key、index)
2018/03/06 Javascript
小程序转发探索示例
2019/02/19 Javascript
小程序云开发之用户注册登录
2019/05/18 Javascript
小程序两种滚动公告栏的实现方法
2019/09/17 Javascript
微信小程序实现时间戳格式转换
2020/07/20 Javascript
vuex 多模块时 模块内部的mutation和action的调用方式
2020/07/24 Javascript
[03:49]DOTA2 2015国际邀请赛中国区预选赛第二日现场百态
2015/05/27 DOTA
[52:14]VG vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python实现在windows服务中新建进程的方法
2015/06/30 Python
Python搜索引擎实现原理和方法
2017/11/27 Python
Django数据库表反向生成实例解析
2018/02/06 Python
使用PIL(Python-Imaging)反转图像的颜色方法
2019/01/24 Python
Python3 解决读取中文文件txt编码的问题
2019/12/20 Python
Python数据持久化存储实现方法分析
2019/12/21 Python
Python运行DLL文件的方法
2020/01/17 Python
django的autoreload机制实现
2020/06/03 Python
python简单利用字典破解zip文件口令
2020/09/07 Python
html5教你做炫酷的碎片式图片切换 (canvas)
2017/07/28 HTML / CSS
Myprotein加拿大官网:欧洲第一的运动营养品牌
2018/01/06 全球购物
《跨越百年的美丽》教学反思
2014/02/11 职场文书
个人四风问题整改措施
2014/10/24 职场文书
护士医德考评自我评价
2015/03/03 职场文书
情侣之间的道歉短信
2015/05/12 职场文书
安全教育培训心得体会
2016/01/15 职场文书