图像旋转


旋转前

旋转后

矩阵表示

def rotate(img, angle):H, W, C = img.shapeanglePi = angle * math.pi / 180.0cosA = math.cos(anglePi)sinA = math.sin(anglePi)out = np.zeros((H, W, C), dtype=np.uint8)  # 必须是8 不然显示不出图像for y in range(H):for x in range(W):x0 = int(x * cosA + y * sinA)y0 = int(y * cosA - x * sinA)if 0 < x0 < W and 0 < y0 < H:  # 计算结果是这一范围内的x0,y0才是原始图像的坐标。out[y0, x0] = img[y, x]return out


旋转后的图像有很多“蜂窝煤”。主要是点转换后要取整。导致原图中有些点映射到同一个点,而生成的图中有些点在原图中没有点映射到它。所以出现了很多“蜂窝煤”。

以图像的中心进行旋转


在矩阵中的坐标系通常是AB和AC方向的,而数学坐标系坐标系是DE和DF方向的。

令图像表示为M×N的矩阵,对于点A而言,两坐标系中的坐标分别是(0,0)和(-N/2,M/2)

矩阵中点(x’,y’)转换为笛卡尔坐标系(x,y)的转换关系为:

逆变换为

最后结果
1.首先将图像坐标系转换为数学坐标系。
2.使用旋转公式对坐标进行旋转。
3.将旋转后的数学坐标系转换为图像坐标系。

def rotate(img, angle):H, W, C = img.shapeanglePi = angle * math.pi / 180.0cosA = math.cos(anglePi)sinA = math.sin(anglePi)out = np.zeros((H, W, C), dtype=np.uint8)  # 必须是8 不然显示不出图像for y in range(H):for x in range(W):x0 = int(cosA * x - sinA * y - 0.5 * W * cosA + 0.5 * H * sinA + 0.5 * W)y0 = int(sinA * x + cosA * y - 0.5 * W * sinA - 0.5 * H * cosA + 0.5 * H)if 0 < x0 < W and 0 < y0 < H:  # 计算结果是这一范围内的x0,y0才是原始图像的坐标。out[y0, x0] = img[y, x]return out

完整显示图片

图片旋转后图片可能变大

N’和M’对应于新图的宽和高

新图像的宽和高计算公式

def rotate(img, angle):H, W, C = img.shapeanglePi = angle * math.pi / 180.0cosA = math.cos(anglePi)sinA = math.sin(anglePi)# 三角函数计算出来的结果会有小数,所以做了向上取整的操作。# size = (W + 1, H + 1)new_height = math.ceil(H * cosA + W * sinA)new_width = math.ceil(W * cosA + H * sinA)out = np.zeros((new_height+1, new_width+1, C), dtype=np.uint8)  # 必须是8 不然显示不出图像for y in range(H):for x in range(W):x0 = int(cosA * x - sinA * y - 0.5 * W * cosA + 0.5 * H * sinA + 0.5 * new_width)y0 = int(sinA * x + cosA * y - 0.5 * W * sinA - 0.5 * H * cosA + 0.5 * new_height)# if 0 < x0 <= new_width and 0 < y0 <= new_height:  # 计算结果是这一范围内的x0,y0才是原始图像的坐标。out[y0, x0] = img[y, x]return out

解决蜂窝煤

采用向后映射法,也可采用后向映射+双线性插值法
图像旋转的过程:1.将图像坐标转换为数学坐标。2.使用图像旋转的逆公式。3.将数学坐标转换为图像坐标。

def rotate(img, angle):H, W, C = img.shapeanglePi = angle * math.pi / 180.0cosA = math.cos(anglePi)sinA = math.sin(anglePi)new_height = math.ceil(H * np.cos(anglePi) + W * np.sin(anglePi))new_width = math.ceil(W * np.cos(anglePi) + H * np.sin(anglePi))out = np.zeros((new_height+1, new_width+1, C), dtype=np.uint8)  # 必须是8 不然显示不出图像dx_back = 0.5 * W - 0.5 * new_width * cosA - 0.5 * new_height * sinAdy_back = 0.5 * H + 0.5 * new_width * sinA - 0.5 * new_height * cosAfor y in range(new_height):for x in range(new_width):x0 =int( x * cosA + y * sinA + dx_back)y0 = int(y * cosA - x * sinA + dy_back)if 0 < x0 < W and 0 < y0 < H:  # 计算结果是这一范围内的x0,y0才是原始图像的坐标。out[y, x] = img[y0, x0]  #。return out


参考链接 https://www.cnblogs.com/xianglan/archive/2010/12/26/1917247.html
参考链接:https://www.cnblogs.com/liwill/p/13875745.html

python数字图像处理笔记10 图像旋转相关推荐

  1. python数字图像处理笔记02 图像的采集

    采样和量化 一幅图像必须要在空间和灰度上都离散化才能被计算机处理. 空间坐标的离散化叫做空间采样(简称采样),它确定了图像的空间分辨率.灰度值的离散化叫做灰度量化(简称量化),它确定了图像的幅度分辨率 ...

  2. Python数字图像处理---1.1图像的像素格式与图像读写

    目录 前言 图像像素格式 图像读写 前言 本专栏面向所有希望或有兴趣从事数字图像处理工作.学习或研究的朋友,编程语言采用了当下最火的Python语言. Python是一种跨平台的计算机设计语言,也是一 ...

  3. python数字图像处理怎么保存图像_python数字图像处理(五) 图像的退化和复原...

    import cv2 import numpy as np import matplotlib.pyplot as plt import scipy import scipy.stats %matpl ...

  4. python数字图像处理(17):边缘与轮廓

    在前面的python数字图像处理(10):图像简单滤波 中,我们已经讲解了很多算子用来检测边缘,其中用得最多的canny算子边缘检测. 本篇我们讲解一些其它方法来检测轮廓. 1.查找轮廓(find_c ...

  5. 数字图像处理笔记(一)——图像存储空间,分辨率,图像内插

    数字图像处理笔记(一)--图像存储空间,分辨率,图像内插 本系列笔记是笔者在学习冈萨雷斯<数字图像处理>第三版时做的总结,日后看的时候方便点,如果有幸得到大家的讨论,喜上眉梢. 本节参考书 ...

  6. 数字图像处理笔记-02(图像空域增强技术及联合运用)

    数字图像处理笔记-02(图像空域增强技术及联合运用) (一) 图像增强 1.1 基本概念 由于图像在传输或者处理过程中会引入噪声或使图像变模糊,从而降低了图像质量,甚至淹没了特 征,给分析带来了困难. ...

  7. python绘制灰度图片直方图-python数字图像处理实现直方图与均衡化

    在图像处理中,直方图是非常重要,也是非常有用的一个处理要素. 在skimage库中对直方图的处理,是放在exposure这个模块中. 1.计算直方图 函数:skimage.exposure.histo ...

  8. python数字图像处理以及绘图

    1, subplot的使用 matlab中的用法: subplot(m,n,p)或者subplot(m n p) subplot是将多个图画到一个平面上的工具.其中,m和n代表在一个图像窗口中显示m行 ...

  9. 数字图像处理笔记2-nbsp;边沿检…

    原文地址:数字图像处理笔记2- 边沿检测与提取,轮廓跟踪(转)作者:小草帽 7.1 边沿检测 我们给出一个模板 和一幅图象 .不难发现原图中左边暗,右边亮,中间存在着一条明显的边界.进行模板操作后的结 ...

最新文章

  1. 如何以初学者角度写好一篇国际学术论文?
  2. 3.5.5 CSMA/CA 协议
  3. 【转】 LINUX中IPTABLES和TC对端口的带宽限制 端口限速
  4. DataGridView中实现点击单元格Cell动态添加自定义控件
  5. malloc线程安全
  6. python 安卓app按钮数字识别_Python 手写数字识别-knn算法应用
  7. ubuntu php7 memcache,linux上安装php7 memcache扩展
  8. strace命令(收集整理,常看常新)
  9. Redis数据类型使用场景及有序集合SortedSet底层实现详解
  10. 屏幕元素创建的基本语法
  11. python-编程之美
  12. 微信小程序滑动切换选项卡
  13. Fibonacci Heaps
  14. 计算机职称photoshop,职称计算机考试photoshop核心通关技巧
  15. 观景台售票情况数据分析【Python】
  16. SecureCRT方向键不可用
  17. xp系统怎么创建新宽带连接服务器地址,XP宽带连接怎么创建?
  18. 【渝粤教育】电大中专电子商务网站建设与维护 (28)作业 题库
  19. 微信小程序项目启动错误“Error: ENOENT: no such file or directory, open”
  20. java tongpaiyu danliantiao_五年级语文第一学期词语表

热门文章

  1. kindeditor 上传视频mp4
  2. Spring面试之循环依赖(allowCircularReferences)
  3. Luenberger Observer线性观测器设计
  4. 在dos中分析线程死锁堆栈消息的案例----用Thread简单Demo,教会你如何分析堆栈消息
  5. 随身wifi刷全网通基带和获取root权限安装面具模块折腾教程
  6. CMS-by-Asp.net
  7. 软考中级软件设计师难不难_为什么这么难处理设计师
  8. Station娱乐影音系统
  9. mes系统核心业务流程及应用场景介绍
  10. 在线开票服务器设置,开票机服务器IP地址和端口更改操作说明 - 重庆市国家税务局....doc...