=摘要=

图像处理老师的课很"抽像",很会"跳"....刚讲了一点"RBG转灰度图",就马上进军图像的几何变换了,同时也带来了一个新的实验(作業):.

要求:旋转弧度: 0

对于我这个"好学生"来说...当然掩盖不了心中的好奇心----图像旋转是怎么实现的?于是经过一定的探索(主要是matlab的用法)...终于实现了这个"旋转":)

本文就是关于这个"探索"过程的一点文字记录啦.

=预览一下=

matlab有一个图像处理工具(IPT),里面已经有一个图像旋转算法的实现了...函数名:imrotate(源图像,旋转角度)...这里将给出:源图像,IPT版本处理过的旋转后图像,我自己的算法处理过的旋转图像:

==原图像==

==IPT(imrotate)实现旋转==

==我自己的旋转函数結果==

==说明==

上面的旋转对于玩过图像处理PS的人来说是不是太简单了?在PS里面或者其他图像处理工具里面对于图像的旋转是"极"简单的...一点就是了:)

上面的"旋转"在生活中经常看到...你把一张生活照旋转一下就感觉到了哈.

=什么是图像的旋转=

图像的旋转是图像几何变换的一种...看到上面预览的图就能知道...旋转前后的图像的像素的RGB都是没有改变的,改变的只是每一个像素的所在位置....这个就是旋转的本质:

把原图像像素从原点(x,y)放到目标位置点上(x',y')..这个(x,y)到(x',y')的转换是经过旋转计算而来的...那么这个图像处理就是旋转处理(几何变换).

再看看上面的图,还真的发现只是图像的像素点的位置改变了,图像本身的彩色信息并没有改动什么.

=怎么SHOW旋转后的图像=

=图像是怎么显示的=

图像的显示都是基于矩阵像素来显示的...上面每一张图像的图像信息其实是一个RGB矩阵来的.所以必须把旋转后的图像放到一个像素矩阵中才能显示这个旋转后的图像.

设一张图像的大小是col*row的.那么以这个图像对角线为直径的圆就能够包含这个图像经旋转后的图像..在这里因为图像的显示是矩阵式的,所以这里以图像对角线为边长构造一个正方形来保存旋转后的图像.从上面旋转后的图像可以看出效果啦,旋转后的图像就包含在这个正方形的矩阵中.

=计算旋转图像所需要的正方形=

因为图像是col*row的,所以这个正方形的边长 new_img_size = (col^2+row^2)^0.5;

这样使用matlab就可以生成一个存储最终图像的rgb矩阵了:

img_rotated = uint8(zeros(new_img_size , new_img_size , 3);//%一个像素由RGB三个分量表现.

=怎么旋转?=

现在来到正题了,上面已经把旋转的原理给讲清楚了...本质就是找到原点(x,y)的新位置(x',y'),然后把原点的像素复制到目标点上就行了...上面也提到了一点:旧坐标到新坐的变的是"旋转"而来的...下面来体现一下旋转的原因:

设一个原点P,P的坐标是:(x,y),这里的x是列分量,y是行分量.

那么P点离图像左上角的距离是:r=(x^2+y^2)^0.5; 同时p到(1,1)点的连线与列方向有一个夹角:a

此时r,x,y的关系可以进一步表示成:

x = r*cos(a);

y = r*sin(a);

到了这里可以知道(x,y)本身与"旋转"角度有一定的关系了,....下面就将p点绕(1,1)这点顺时针旋转b角度...得到p的新位置(x',y')..由r,x,y的关系可以得到r,x',y'的关系如下:

x' = r*cos(a+b);

y' = r*sin(a+b);

进一步化简:

x' = r*cos(a)*cos(b) - r*sin(a)*sin(b);

y' = r*sin(a)*cos(b) + r*cos(a)*sin(b);

然后再结合r,x,y的关系得到x,y,x',y'的关系如下:

x' = x*cos(b) - y*sin(b);

y' = y*cos(b) + x*sin(b);

于是上面提到的点旋转位置关系就出来了....即(x,y)经过顺时针旋转b角度后可以得到(x',y')..这个转换公式就是上面的线性方程..写成matlab的方式就是如下啦:

[x',y'] = [cos(b) -sin(b);sin(b) cos(b)]*[x,y]; //%这里的x'不是x的转置哦.

好了,到此为止,我们有了旋转公式了...下面就可以利用这个公式对原图的每一个像素点(x,y)计算其旋转后的位置(x',y')了,然后就是复制图像的像素点了(简单不?)...

=怎么复制像素点=

由上面两节可以看出,图像旋转后的像素应该保存在img_rotated当中. 同时每一个像素的坐标都是正的,即没有(-10,-10)坐标位置的像素点..而从上面(x,y)到(x',y')的计算过程可以看出....x'或者y'都可能出现是负值的问题...于是不能够在计算出x',y'后就直接把x,y处的像素复制到x',y'...因为x',y'可能是一个非法的位置.

从上面的图来看,这个问题还是可以解决了..要不然上面我就不能做出那么像样的旋转了呵呵.

为了让x',y'合法,让我们来看看原图像顺时针旋转后,原图上哪些点会导致对应的x',y'不合法...

经过分析.不难看出只有x'这个变量会出现负值,而x'为负值时x的值就分布在图像的左下角处....

而且x'达到最小负数的绝对值是row*sin(b).注意y'永远是一个正的...因为题目的要求可以知道..而且矩阵的左上角是(1,1).即采用计算机的坐标系统.

好了,找到了x'不合法的原因了...这个时候就可以找找解决方法了....联想到图像旋转后是存储在img_rotated当中的...而且原图的左下角像素显示在img_rotated的左边界上面...所以解决方法就是计算完成x',y'后,再将x',y'右移一段距离,以让x'始终是正值...很明显,这右移的距离大小就是row*sin(b),注意这里y'是不需要调整的.

所以最终x,y得到的目标位置x'',y''就由如下公式计算了.

x'' = x*cos(b) - y*sin(b) + row*sin(b);

y'' = y*cos(b) + x*sin(b);

(可以看出与上面x',y'的计算没有差多少,只是图像右移了下呵呵)

得到了x'',y''的同时,我们也知道原图像素(x,y)的目标位置就是img_rotated(x'',y'')

哈哈,终于写到这里了...这里也标记着我的这个旋转算法的尾声了....正个算法就是找到(x,y)在img_rotated的显示位置(x'',y'')..

经过上面的算法处理后,我是能够看到图像"旋转"了...但是也能明显发现:图像的质量很差...因为img_rotated当中也许多有规律性的背景点没有得到原图像的像素来填充...

=存在像素空洞的图像=

下图是直接运用上面算法进行的旋转处理后的图像:

=解决空洞像素问题=

仔细看看有空洞像素的图像可以看出,没有像素填充的点都是有规律的....再想想上面的计算都是基于三角函数的,而且三角函数的值都是小数...于是原因就可以猜出来了.:原点(x,y)到(x'',y'')的计算不是连续的,因为x'',y''是有取整操作的....这个就是造成空洞的原因了...

哈哈,知道原因了...查找解决方案就有方向了...

由上面可以知道是x'',y''有取整操作...造成部分点没有达到其对应的点上去...

所以我在计算x'',y''的时候故意加上了+0.5,-0.5分量到x''或者y''分量上去..目的是把x'',y''周围不可能由x,y达到的点用x,y像素点去填充...这个思想也是今天老师在课堂说的"插值"问题(老师也向我们演示这个问题,他的解决方法是x'',y''周围8个没有填充的像素点用x'',y''点去填充)

经过上面的x'',y''调整...图像旋转后的的空洞点就没有了,表面上看起来就是我们想要的旋转后的图像了.呵呵...

没有考虑到像素空洞的图像:

=图像边界齿距=

我个人感觉我的这个算法还是有问题的,于是与IPT工具里面的旋转图像算法相比...結果是我旋转后的图像不仅在尺寸要比imrotate的输出图像要大一点点,而且边界上面的齿距也没有imrotate的输出图像那么完美.(这点我用老师的算法比较也是一样.)

于是我想应该是因为上面x'',y''调整问题了...把边界某些点复制多出来了....于是一个一个调整算法(-0.5,+0.5)..最终调试成功了....四个边界的齿距都与IPT的imrotate的输出图像99%一致了(但是右下角的一个点有点不一样呵呵)

下面是一张显示齿距的图像块:

=算法复杂度=

上面提到了就是对图像每一个点的坐标进行计算,然后把点上的像素数据复制到目标坐标上...所以对于一个col*row大小的图像,我这个图像处理算法的时间复杂度是:O(N^2);

=小结=

呼呼...写到这里也不容易的(写了1小时多一丁点),特别是对于我这种没杂写过文字的人.

上面討論了我是怎么实现这个图像旋转算法,同时也考虑了一些图像像素点空洞,边界齿距问题...

如果还是有点不明白的,那直接可以结合我的m文件源代码看看,源代码我放到csdn.download里面咯...核心代码量是20行吧.

=源代码=

地址:

http://download.csdn.net/detail/abee23/4176587 上面是我刚接触图像处理的第二个实验笔记,其中一定有很多不够专业的说法...在这里原谅小弟啦...:) 最后:欢迎拍砖:)

用matlab实现任意点图片的旋转_(实验二) --- 图像旋转变换---matlab实现相关推荐

  1. 用matlab实现任意点图片的旋转_图像旋转MATLAB实现代码

    图像旋转 MATLAB 实现 function [I,I1,I2] = irotating( i, x0) [m, n] = size(i); %get the size of the image m ...

  2. 用matlab实现任意点图片的旋转_Matlab实现图像旋转

    %%%%%% 对图像进行旋转处理 clc;clear;close; naturalimag=imread('xuanzhuan.bmp');%jpegtu.jpg figure(1); imshow( ...

  3. MATLAB中如何让分度值小点,实验6 干涉的matlab模拟.doc

    实验6 干涉的matlab模拟.doc MATLAB在光信息处理中的应用课程上机实验(三峡大学2013年)实验6干涉的MATLAB模拟一.实验目的掌握双缝干涉.牛顿环的MATLAB模拟.二.实验内容1 ...

  4. matlab resampc函数,基于contourlet变换的红外与可见光图像融合matlab源码

    基于contourlet变换的红外与可见光图像融合matlab源码 matlab 2020-12-1 下载地址 https://www.codedown123.com/53619.html 基于con ...

  5. thinkphp5 图片压缩旋转_【好工具】在线免费无限制的PDF处理工具(转换、编辑、分割、合并、压缩)...

    在线好用的 PDF 编辑工具,PDF 转文档,PDF 压缩.编辑.分割不再难,解密 PDF 文档也在行,快来试试- 作者 & 编辑 | Leong SmallPDF SmallPDF http ...

  6. thinkphp5 图片压缩旋转_有非常多的图片,该怎么制作PPT?

    hello,大家好,我是利兄~ 上周有一位粉丝朋友问我:"多张图片的PPT到底该如何排版,有什么小妙招没?" 所以,今天,我们就来聊聊PPT中多图排版的问题? 通常情况下,遇到多张 ...

  7. 随机生成元素升序向量_实验二MATLAB运算基础 -

    持这段文字的格式: 在英式用法中,引号通常是单引号,如'Fire!'. In GB usage quotation marks are usually single: 'fire!'. 6. 用结构体 ...

  8. 信号与系统仿真实验——实验二 傅立叶变换MATLAB的实现及傅里叶变换性质的分析

    [ 实验目的] 1.利用MATLAB分析非周期信号的频谱 2.观察信号频谱变化验证傅里叶变换性质 [ 实验内容] [ 实验报告要求] (1)记录实验一和实验三中的波形: (2)总结实验二中频谱特性曲线 ...

  9. ios 图片居中裁剪_使用居中图像iOS启动屏幕故事板

    1 - I want to use a LaunchScreen.storyboard in my app 2 - In this launch screen I need to insert a b ...

最新文章

  1. 线性回归之数学:求导公式
  2. How is HashMap return type handled to be converted to a json string
  3. 刘汝佳训练指南——数论专题知识点总结:
  4. 用JavaScript将字符串中的单词大写
  5. 学习笔记之23-typedef
  6. 14007.xilinx-备份镜像
  7. NodeJS 加密 —— crypto 模块
  8. iocomp控件的应用
  9. ELementD对象
  10. 大数据环境搭建之hadoop完全分布式搭建
  11. 社区发现算法之——Louvain
  12. 恩智浦智能车大赛----笔记
  13. Python程序设计实验——1.尼姆游戏
  14. 电影片段素材网,自媒体必备素材网站推荐,视频素材免费下载网站
  15. java实现pdf旋转_基于Java实现PDF文本旋转倾斜
  16. VB.net单exe文件内MP3和WAV音乐文件播放
  17. 蓝本蓝科技:社群变现的模式有哪些?
  18. 计算机最新行情调研报告,2020年中国笔记本电脑市场调研报告
  19. GPIO 按键及矩阵键盘程序------/* 自己实验确认并总结 */
  20. 建模--知名软件介绍

热门文章

  1. 【二叉树:3】线索二叉树
  2. Signal信号处理
  3. Qt (高仿Visio)流程图组件开发(二) 基本图元绘制 图元间连线绘制
  4. dotnet 基于 debian 创建一个 docker 的 sdk 镜像
  5. “感受野”的直观理解
  6. 笔记本屏幕颜色校证,有效解决屏幕发白、刺眼问题
  7. c语言法定节日日历程序,C 语言写的日历
  8. 每天记忆五个词根之四
  9. 缺陷检测相关论文阅读总结(记录自己读过的论文主要内容/Ideas)
  10. 一款APP从设计稿到切图过程全方位揭秘(IOS版)