图像处理实验报告
更新时间:2023-10-27 09:55:01 阅读量: 综合文库 文档下载
数字图像处理实验报告
专 业: 计算机科学与技术 学 号: 20121004357 学生姓名: 李世荣 班 级: 191123 指导教师: 徐凯
图像的旋转变换
一、 实验目的:
主要是图像的旋转变换的编程实现,具体包括图像的读取、改写,图像的镜像,图像的转置,旋转变换等.
具体要求如下:
编程实现以任意角度对图像进行旋转变换; 在MFC的操作环境下达到实验目的。
二、 实验原理及算法:
1、图像旋转的定义
图像旋转是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程。当然这
个点通常就是图像的中心。既然是按照中心旋转,自然会有这样一个属性:旋转前和旋转后的点离中心的位置不变. 根据这个属性,我们可以得到旋转后的点的坐标与原坐标的对应关系。旋转后,图像的大小一般会改变。和图像平移一样,既可以把转出显示区域的图像截去,也可以扩大图像范围以显示所有的图像。与图像平移一样,图像旋转也是图像的位置变换,对于旋转后超出源图像范围的区域要处理为不显示。
旋转后的图像不会变形,但是其垂直对称轴和水平对称轴都发生了改变,旋转后像素的坐标需要经过较复杂的数学运算得出。而且图像在经过旋转变换后,其宽度和高度都要发生变化,所以原始图像的中心点和输出图像的中心点的坐标是不同的。图像的旋转不再是由一个矩阵变换就能获得坐标的映射关系,它涉及多次矩阵变换。 2、图像旋转的算法
设图像绕任意点 C(x0,y0 )旋转θ角度,如图所示:
我们可通过以下几个步骤来实现该旋转变换:
(1)将指定的任意旋转中心C(x0,y0)平移到坐标原点O,变换矩阵为Ts1 (2)使图像绕坐标原点逆时针旋转θ角,变换矩阵为Tr
(3)使旋转中心从坐标原点平移回原来的位置C(x0,y0)。变换矩阵为Ts2 所以图像绕任意点阵: C(x0,y0)的旋转过程为将每一象素点的齐次坐标的行向量右乘变换矩
则,
[x',y',1] = [x,y,1] · T = [(x-x0)cosθ+(y-y0)sinθ+x0 ,-(x-x0)sinθ+(y-y0)cosθ+y0 , 1] 即:
x' = (x - x0)cosθ + (y - y0)sinθ + x0 y' = - (x - x0)sinθ + (y - y0)cosθ + y0 利用上式,就可以实现图像的旋转。
三、 实验流程图
程序开始 单击“文件->打开”打开一幅图像 单击“几何变换->图像旋转” 获取旋转角度 计算旋转角度的正弦和余弦 计算原图和新图四个角的坐标 计算旋转后图像实际宽度和高度 更新DIB中图像的宽度和高度 针对图像每行每列进行操作 计算指向新DIB第i行,第j个像素的指针 计算该像素在原DIB中的坐标 否 判断坐标是否在原图范围内 是 计算指向原DIB在该坐标下像素的指针 复制像素 将该像素赋值为255 否 判断旋转是否成功 是 替换DIB,更新DIB大小和调色板,设置脏标记 重新设置滚动视图大小,并更新视图 提示用户 程序结束 四、 实验结果 原图:
旋转90°后:
四、总结与体会:
这次专选课学到最大的东西,是自己总算有MFC编程的概念了,很多东西不通过自己的编程是绝对不能真正理解.比如说封装性,这次编程,很好地利用了类的封装性.另外,比如MFC是基于消息响应机制的,这就决定了,要利用鼠标或者菜单响应函数去实现功能,而用c语言编写程序的时候,完全是按主函数的线程来的.
刚开始的时候做的是位图的读取和显示,实在是不知从哪里做起,所以就照着从图书馆里借来的教材上敲了前面的部分,但是慢慢地也看懂了代码的意思.不过后来的基本上都是从网上找的了,但是算法还是基本上和书上差不多.不过自己想的时候还是有很多细节的部分没有注意到,比如说,强制数据类型转换,有些是由于函数调用引起的,有些是由于不
等号两边数据的匹配问题,还有的是由于指针的移动,直到这个时候,才真正明白实习书上程序为什么那么多强制类型转换,虽然书上很多东西不是尽善尽美,但是对于我这种刚开始学会编程的人还是有很多可以学习的地方的.
如老师所说,算法的效率是很重要的.要提高算法的效率,一个是要简化计算(不得不说,这需要数学基础),另外一个就是要避免许多重复的计算.在参考书上的程序里,很多时候,为了避免这种重复的计算(在循环中表现尤其明显),会把某些数当常数算出来,只要后来加上这个常数就可以,这样,效率高很多.
另外,对许多出错的情况,我的程序里也没有做好.这也是我应该向别人程序学习的地方.
部分源代码附录:
* 函数名称: RotateDIB() * 参数:
* LPSTR lpDIB
- 指向源DIB的指针
* int iRotateAngle - 旋转的角度(0-360度)
* 返回值: HGLOBAL - 旋转成功返回新DIB句柄,否则返回NULL。 * 说明:
* 该函数用来以图像中心为中心旋转DIB图像,返回新生成DIB的句柄。 * 调用该函数会自动扩大图像以显示所有的象素。函数中采用最邻近插 * 值算法进行插值。
************************************************************************/ HGLOBAL CDibImage::RotateDIB(LPSTR lpDIB, int iRotateAngle) {
lWidth; lHeight;
// 源图像的宽度
LONG LONG LONG LONG LONG LONG LPSTR LPSTR HDIB LPSTR LPSTR LPSTR
// 源图像的高度
lNewWidth; lNewHeight; lLineBytes;
// 旋转后图像的宽度 // 旋转后图像的高度
// 图像每行的字节数
// 旋转后图像的宽度(lNewWidth',必须是4的倍数) // 指向源图像的指针
// 指向源象素的指针 // 旋转后新DIB句柄
// 指向旋转图像对应象素的指针
lNewLineBytes; lpDIBBits; lpSrc; hDIB; lpDst;
lpNewDIB; // 指向旋转图像的指针
lpNewDIBBits;
LPBITMAPINFOHEADER lpbmi; LPBITMAPCOREHEADER lpbmc;
i; j; i0; j0;
// 指向BITMAPINFO结构的指针(Win3.0) // 指向BITMAPCOREINFO结构的指针
LONG LONG LONG LONG
// 循环变量(象素在新DIB中的坐标)
// 象素在源DIB中的坐标
float fRotateAngle; float fSina, fCosa;
// 旋转角度(弧度) // 旋转角度的正弦和余弦
// 源图四个角的坐标(以图像中心为坐标系原点)
float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4; // 旋转后四个角的坐标(以图像中心为坐标系原点)
float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4; float f1,f2;
lpDIBBits = FindDIBBits(lpDIB); lWidth = DIBWidth(lpDIB);
// 找到源DIB图像象素起始位置 // 获取图像的\宽度\(4的倍数)
lLineBytes = WIDTHBYTES(lWidth * 8);// 计算图像每行的字节数 lHeight = DIBHeight(lpDIB); // 将旋转角度从度转换到弧度
fRotateAngle = (float) RADIAN(iRotateAngle); fSina = (float) sin((double)fRotateAngle); fCosa = (float) cos((double)fRotateAngle);
// 获取图像的高度
// 计算旋转角度的正弦 // 计算旋转角度的余弦
// 计算原图的四个角的坐标(以图像中心为坐标系原点) fSrcX1 = (float) (- (lWidth - 1) / 2); fSrcY1 = (float) ( (lHeight - 1) / 2); fSrcX2 = (float) ( (lWidth - 1) / 2); fSrcY2 = (float) ( (lHeight - 1) / 2); fSrcX3 = (float) (- (lWidth - 1) / 2); fSrcY3 = (float) (- (lHeight - 1) / 2); fSrcX4 = (float) ( (lWidth - 1) / 2); fSrcY4 = (float) (- (lHeight - 1) / 2);
// 计算新图四个角的坐标(以图像中心为坐标系原点) fDstX1 = fCosa * fSrcX1 + fSina * fSrcY1; fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1; fDstX2 = fCosa * fSrcX2 + fSina * fSrcY2; fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2; fDstX3 = fCosa * fSrcX3 + fSina * fSrcY3; fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3; fDstX4 = fCosa * fSrcX4 + fSina * fSrcY4; fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4; // 计算旋转后的图像实际宽度
lNewWidth = (LONG)(max(fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2)) + 0.5); // 计算新图像每行的字节数
lNewLineBytes = WIDTHBYTES(lNewWidth * 8); // 计算旋转后的图像高度
lNewHeight = (LONG)(max(fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2)) + 0.5); // 两个常数,这样不用以后每次都计算了
f1 = (float) (-0.5 * (lNewWidth - 1) * fCosa - 0.5 * (lNewHeight - 1) * fSina
+ 0.5 * (lWidth - 1));
f2 = (float) ( 0.5 * (lNewWidth - 1) * fSina - 0.5 * (lNewHeight - 1) * fCosa
+ 0.5 * (lHeight - 1));
// 分配内存,以保存新DIB
hDIB = (HDIB) ::GlobalAlloc(GHND, lNewLineBytes * lNewHeight +
*(LPDWORD)lpDIB + PaletteSize(lpDIB));
if (hDIB == NULL) { }
lpNewDIB = (char * )::GlobalLock((HGLOBAL) hDIB); // 复制DIB信息头和调色板
memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB + PaletteSize(lpDIB)); // 找到新DIB象素起始位置
lpNewDIBBits = FindDIBBits(lpNewDIB);
return NULL;
lpbmi = (LPBITMAPINFOHEADER)lpNewDIB; lpbmc = (LPBITMAPCOREHEADER)lpNewDIB;
// 更新DIB中图像的高度和宽度 if (IS_WIN30_DIB(lpNewDIB)) { } else { }
// 针对图像每行进行操作
// 对于其它格式的DIB
lpbmc->bcWidth = (unsigned short) lNewWidth; lpbmc->bcHeight = (unsigned short) lNewHeight; // 对于Windows 3.0 DIB lpbmi->biWidth = lNewWidth; lpbmi->biHeight = lNewHeight;
for(i = 0; i < lNewHeight; i++) {
for(j = 0; j < lNewWidth; j++) {
// 针对图像每列进行操作
// 指向新DIB第i行,第j个象素的指针 // 注意此处宽度和高度是新DIB的宽度和高度
lpDst = (char *)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j; // 计算该象素在源DIB中的坐标
i0 = (LONG) (-((float) j) * fSina + ((float) i) * fCosa + f2 + 0.5); j0 = (LONG) ( ((float) j) * fCosa + ((float) i) * fSina + f1 + 0.5); // 判断是否在源图范围内
if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) {
// 指向源DIB第i0行,第j0个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; // 复制象素
}
}
} else { }
*lpDst = *lpSrc;
// 对于源图中没有的象素,直接赋值为255 * ((unsigned char*)lpDst) = 255;
return hDIB; }
正在阅读:
图像处理实验报告10-27
招展书(中英文全)05-10
湿法冶炼工岗位实习周记原创范文05-14
河南省六市2013届高中毕业班第二次联合考试(word版)理综07-05
小学语文六年级下册复习宝典01-26
隐框玻璃幕墙设计计算书07-09
压力蒸汽灭菌效果监测方法完整版04-17
程序设计说明书07-03
平均数问题12-13
公司经典部门职能和岗位职责07-01
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 图像处理
- 实验
- 报告
- 红河人才网:2014年屏边县事业单位招聘128人
- 关于对外协产品采购不合格处理流程及考核办法
- 2017-2018学年第二学期七年级英语期末考试试卷(人教版含听力)
- 益阳市2011年政府工作报告
- 以点带面 以面促体
- 2013广东公务员申论三试题及答案解析
- 关于跟踪体会
- 浏阳市教育局 - 图文
- 电子基础考试必备十套试题
- 佛山市三水燃气有限公司三水区天然气利用可行性研究报告-广州中撰咨询
- 桥隧工岗位实习周记原创范文
- 基于嵌入式操作系统VxWorks的多任务并发程序设计(5)――中断与任务
- 公共关系口才
- 人教版四年级下册语文集体备课 01、《古诗词三首》
- dsc系统i报警中心方案
- 初中生物课程实验教学论文
- 纪律作风整顿教育活动个人剖析材料
- 工程量计算示例解答汇总 - 图文
- 电化学与氧化还原平衡
- 2008年专利代理人考试真题及答案-专利法律知识