点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

本文转自|OpenCV学堂

01

引言

初学图像处理,很多人遇到的第一关就是图像旋转,图像旋转是图像几何变换中最具代表性的操作,包含了插值、背景处理、三角函数等相关知识,一个变换矩阵跟计算图像旋转之后的大小公式就让很多开发者最后直接调用函数了事,但是其实这个东西并没有这么难懂,可以说主要是之前别人写的公式太吓人,小编很久以前第一次接触的也是被吓晕了!所以决定从程序员可以接受的角度从新介绍一下图像旋转基本原理与OpenCV中图像旋转函数操作的基本技巧。

图像旋转基本原理

旋转涉及到两个问题,一个是图像旋转之后的大小会发生改变,会产生背景,通过背景填充方式都是填充黑色,此外旋转还是产生像素的位置迁移,新的位置像素需要通过插值计算获得,常见的插值方式有最近邻、线性插值、立方插值等。

首先看旋转之后的图像宽高变化,如下图所示:

这个是正常的平面坐标系中的旋转矩阵,可以简写为:

是一个2x3的矩阵,但是在图像中左上角是原点,要实现围绕图像的中心位置旋转,M就要重新计算,所以OpenCV中的图像旋转矩阵为:

其中scale是表示矩阵支持旋转+放缩,这里可以把Scale=1。第三列是图像旋转之后中心位置平移量。

函数支持

OpenCV中支持图像旋转的函数有两个,一个是直接支持旋转的函数,但是它支持的是90,180,270这样的特殊角度旋转。

void cv::rotate   (InputArray    src,OutputArray dst,int rotateCode
)

其中rotateCode参数必须为:

ROTATE_180,
ROTATE_90_CLOCKWISE
ROTATE_90_COUNTERCLOCKWISE

函数warpAffine支持任意角度的旋转,通过定义M矩阵实现

void cv::warpAffine(InputArray      src, // 输入图像OutputArray dst, // 输出图像InputArray      M, // 旋转矩阵Size         dsize, // 输出图像大小int   flags = INTER_LINEAR, // 像素插值方式int   borderMode = BORDER_CONSTANT, // 背景填充默认为常量const Scalar &        borderValue = Scalar() // 填充颜色默认为黑色
)

但是M如何生成与获取,OpenCV中提供了一个函数根据输入的参数自动生成旋转矩阵M,该函数为:

Mat cv::getRotationMatrix2D(Point2f   center,double    angle,double    scale
)

代码演示

原图

使用自定义的M矩阵实现图像旋转

h, w, c = src.shape
# 定义矩阵
M = np.zeros((2, 3), dtype=np.float32)
# 定义角度
alpha = np.cos(np.pi / 4.0)
beta = np.sin(np.pi / 4.0)
print("alpha : ", alpha)
# 初始化矩阵
M[0, 0] = alpha
M[1, 1] = alpha
M[0, 1] = beta
M[1, 0] = -beta
cx = w / 2
cy = h / 2
tx = (1-alpha)*cx - beta*cy
ty = beta*cx + (1-alpha)*cy
M[0,2] = tx
M[1,2] = ty
# 执行旋转
dst = cv.warpAffine(src, M, (w, h))
cv.imshow("rotate-center-demo", dst)

重新计算旋转之后的图像大小,实现无Crop版本的图像旋转

h, w, c = src.shape
M = np.zeros((2, 3), dtype=np.float32)
alpha = np.cos(np.pi / 4.0)
beta = np.sin(np.pi / 4.0)
print("alpha : ", alpha)# 初始旋转矩阵
M[0, 0] = alpha
M[1, 1] = alpha
M[0, 1] = beta
M[1, 0] = -beta
cx = w / 2
cy = h / 2
tx = (1-alpha)*cx - beta*cy
ty = beta*cx + (1-alpha)*cy
M[0,2] = tx
M[1,2] = ty# change with full size
bound_w = int(h * np.abs(beta) + w * np.abs(alpha))
bound_h = int(h * np.abs(alpha) + w * np.abs(beta))# 添加中心位置迁移
M[0, 2] += bound_w / 2 - cx
M[1, 2] += bound_h / 2 - cy
dst = cv.warpAffine(src, M, (bound_w, bound_h))
cv.imshow("rotate without cropping", dst)

背景随便变化+无Crop版本的图像旋转动态演示

degree = 1.0
d1 = np.pi / 180.0
while True:alpha = np.cos(d1*degree)beta = np.sin(d1*degree)M[0, 0] = alphaM[1, 1] = alphaM[0, 1] = betaM[1, 0] = -betacx = w / 2cy = h / 2tx = (1 - alpha) * cx - beta * cyty = beta * cx + (1 - alpha) * cyM[0, 2] = txM[1, 2] = ty# change with full sizebound_w = int(h * np.abs(beta) + w * np.abs(alpha))bound_h = int(h * np.abs(alpha) + w * np.abs(beta))M[0, 2] += bound_w / 2 - cxM[1, 2] += bound_h / 2 - cyred = np.random.randint(0, 255)green = np.random.randint(0, 255)blue = np.random.randint(0, 255)dst = cv.warpAffine(src, M, (bound_w, bound_h), borderMode=cv.BORDER_CONSTANT, borderValue=(blue, green, red))cv.imshow("rotate+background", dst)c = cv.waitKey(1000)if c == 27:breakdegree += 1print("degree", degree)if degree > 360:degree = degree % 360

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

经验 | OpenCV图像旋转的原理与技巧相关推荐

  1. OpenCV图像旋转的原理与技巧

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 转自|OpenCV学堂 01 引言 初学图像处理,很多人遇到的第一 ...

  2. python opencv 图像旋转

    python opencv 图像旋转 原图 顺时针旋转 代码: import cv2 path = '2.jpg' img = cv2.imread(path,1) trans_img = cv2.t ...

  3. OpenCV图像旋转,指定填充背景颜色边界颜色

    OpenCV图像旋转,指定填充背景颜色边界颜色 OpenCV与图像旋转有关的函数: (1)warpAffine函数 void cv::warpAffine ( InputArray  src,     ...

  4. OpenCV:OpenCV图像旋转的代码

    OpenCV图像旋转的代码 cv::transpose( bfM, bfM ) 前提:使用两个矩阵Mat型进行下标操作是不行的,耗费的时间太长了.直接使用两个指针对拷贝才是王道.不知道和OpenCV比 ...

  5. OpenCV 图像旋转、平移、缩放

    本文是 OpenCV图像视觉入门之路的第7篇文章,本文详细的进行了图像的缩放 cv2.resize().旋转 cv2.flip().平移 cv2.warpAffine()等操作. OpenCV 图像旋 ...

  6. 图像旋转的原理,实现与优化

    文章目录 图像旋转的原理 图像旋转的实现 最近邻插值 双线性插值 双线性的优化 图像旋转的原理 图像旋转的原理其实很简单,为了简化公式的推导,这里我们假设绕原点 ( 0 , 0 ) (0,0) (0, ...

  7. 图像旋转的原理与实现

    图像旋转的原理与实现 图像旋转的原理与实现 一般图像的旋转是以图像的中心为原点,旋转一定的角度,也就是将图像上的所有像素都旋转一个相同的角度.旋转后图像的的大小一般会改变,即可以把转出显示区域的图像截 ...

  8. OpenCV 图像旋转

    在OpenCV中图像旋转首先根据旋转角度和旋转中心获取旋转矩阵,然后根据旋转矩阵进行变换,即可实现任意角度和任意中心的旋转效果. cv2.getRotationMatrix2D(center, ang ...

  9. opencv 图像旋转_用Dlib和OpenCV还能做什么?这个开源项目实现了驾驶员疲劳检测...

    Dlib 和 OpenCV 这两个库已经在深度学习和人脸识别领域逐渐有了自己的一席之地,基于它们的各种开源项目的越来越多,今天 Gitee 上这个开源项目也是基于 Dlib 和 OpenCV 的,具体 ...

最新文章

  1. 程序语言(编程语言)汇总大全
  2. ORACLE搭建Stream过程中报错【error收集】
  3. 设置材质阿尔法通道和双面渲染
  4. 问题集锦13:数据库升级后,程序无法连接数据库
  5. SQL注入:4、数据库可写
  6. Bootstrap 分页导航
  7. mysql内存态_MySQL · 社区动态 · MySQL内存分配支持NUMA
  8. img内联块元素的操作
  9. 多重句柄怎么处理_golang异常处理详解
  10. JavaWeb——jdbc与dbcp数据库连接
  11. error log php 邮件,error_log()怎么向外发送邮件。
  12. pyspark分类算法之梯度提升决策树分类器模型GBDT实践【gradientBoostedTreeClassifier】
  13. 基于Android设备的 Kali Linux渗透测试教程(内部资料)
  14. 如何用Python批量获取生意参谋商品来源信息
  15. 在线购物系统1.1设计类图
  16. 调整计算机繁体,在线繁体转换
  17. 全量查询与分页查询合二为一的思考
  18. Oracle RAC 安装指北 10gR2+OEL5.11
  19. 三种古典密码的认识(置换密码,代换密码和轮换密码)
  20. Android解决监听AppBarLayout的滑动状态来动态设置标题时报requestLayout() improperly called by错误问题

热门文章

  1. Python一键转Java?“Google翻译”你别闹
  2. Alphabet旗下自驾公司Waymo入华,变身“慧摩”!
  3. Microsoft HoloLens 入华一周年,都有哪些进展?
  4. AI一分钟|美团确认收购摩拜;特斯拉今年第一季度产量创历史新高
  5. ACMMM2017 | 电子科大斩获最佳论文!中科院自动化所多媒体计算组获得IEEE期刊最佳论文!
  6. Spring的Controller是单例还是多例?怎么保证并发的安全
  7. 常用的设计模式汇总,超详细!
  8. 优秀的 Java 项目代码都是如何分层的?
  9. 春节假期是弯道超车的好机会!
  10. 机器学习调参自动优化方法