程序设计实践报告 BMP._第1页
程序设计实践报告 BMP._第2页
程序设计实践报告 BMP._第3页
程序设计实践报告 BMP._第4页
程序设计实践报告 BMP._第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验报告第二次程序设计实践:DIB图像处理姓名:学院:信息与通信工程学院学号:班级:11111一、课题概述1. 课题目标和主要内容A. 打开BMP文件,并显示到屏幕上,BMP图像支持1、4、8、24bit非压缩图像。B. 对BMP文件进行处理,如变为灰度图像、二值化、平滑、连通域分析等操作,包括:a) 将原始图像转换为8bit灰度图像,并在界面中显示。b) 将8bit灰度图像转换为8bit二值图像(图像中只有黑、白两种颜色),并在界面中显示。c) 对二值图像进行平滑、连通域分析等操作,并在界面中显示。C. 能将界面中的图像保存到新的BMP文件中。D. 所有处理效果可以在界面中实时展示。E. 本

2、设计中除了显示图像、窗口设计功能采用Windows API来实现外,对BMP文件的其他操作全部单独设计相应的类完成。好处是即使不在Windows环境下,该类依然可以处理BMP文件。2. 开发平台和环境:Win32应用程序,用Microsoft Visual Studio 2013开发环境。3. 系统的主要功能:A. 文件操作:a) 打开新BMP文件b) 保存当前BMP文件c) 退出B. 导航视窗:a) 图像速览b) 颜色通道c) 框图切换C. 图像处理:a) 转8bit灰度图b) 4邻域平滑c) 8邻域平滑d) 二值化图像e) 黑色-4邻域连通域分析D. HSL色彩空间处理:a) 建立HSL空

3、间b) 修改色相、饱和度、亮度。c) 撤除HSL空间4. 主要编程点:A. Win32程序消息循环处理;B. 位图的识别、判断;C. 位图数据的改写、输出;D. DIB与DDB的转换,内存DC的使用;E. 小型内存管理分配;F. 视窗切换、屏幕输出与刷新;G. 数据结构:顺序表、链表;H. 读取、保存DIB二进制流;I. 色相、饱和度、亮度调整;J. 直方图的扫描和输出。二、系统总体框架1. 工程环境:a) 操作系统:Windows 10b) 开发环境:Visual Studio 2013 Ultimatec) 项目类型:Win32程序2. 主要程序流程3. 数据与操作:总的来说,用户操作、图

4、像数据结构、图像操作对象是相互独立、开放的三大模块。菜单用于输入输出原始数据流,或是操纵图像处理;数据结构方便统一管理所有DIB单元结构体间的关系链,可以直接存取这些单元数据;操作类对象首先要Link一个结构体以初始化常用数据,方便随后处理。4. 数据结构、功能扩展:在满足原有图像处理的基础上增加新功能a) 数据扩展:在基础结构中存放一个万能指针void*,要增加新的属性时,只需要在源文件中添加新的结构体,在主要函数中完成新结构体的创建和赋值,再令基础结构体中的扩展指针ext指向新结构体,就完成了属性添加,并且无需大幅度更动基础结构体内容,便完成了数据扩展。b) 函数功能扩展:在满足 “里氏代

5、换”原则基础上,即基类出现的地方以子类替代仍然保证程序正常运作,通过原始基类继承出新的派生类,保留原始接口同时增加新的接口,实现功能扩展。三、系统详细设计1. 图像处理DIBProcess模块:A. 图像数据结构体BMFHB. 图像数据结构体BMIHC. 图像数据结构体RGBQUADD. 图像数据结构体DIBUnitE. 矩阵模板类Matrix F. 图像处理基类DIBProcG. 图像处理派生扩展类DIBProcEx2. 内存DC模块MemoryDC3. 小型内存池管理类MemoryPoolA. 页结点结构体 B. 块结点结构体C. 检验节点结构体D. 内存管理类E. 应用示意图4. 主函数

6、模块(主要是功能相关性模块)A. 主要头文件 B. 主要全局量C. 主要功能性函数声明D. 菜单功能设计a) 文件 b) 导航 c) 操作 d) HSL空间操作 四、关键算法分析1. 算法1:int IsBmp(const DIBUnit&);A. 算法功能:根据读取的文件流二进制数据判断是否为能处理的位图。B. 基本思想:根据BMP文件头的定义和特征信息判断位图是否正确C. 算法逻辑:(这里判断5个关键点)a) BMFH结构的bfType应恒为定值0x4D42;b) BMIH结构的biSize应等于sizeof(BMIH),即程序只处理INFO信息头。c) BMIH结构的biCompress

7、ion应为0,表示未压缩,程序不处理压缩图。d) BMFH结构的bfSize属性和bfOffBits属性的值应该和BMIH结构的biHeight值和biWidth值有等式关系,即:bfSize bfOffBits = biHeight * cxBytes;其中cxBytes为图的字节宽度。2. 算法2:void operator(const DIBUnit&);A. 算法功能:读取一个DIB单元结构并解析获得相关数据B. 基本思想:解析DIB结构中的BMFH,BMIH信息。数据运算完成后保存 在类的私有成员里。C. 算法逻辑:a) 获取图像实际字节宽。根据BMP文件定义,每个扫描行的字节数必须

8、为4的倍数,因此根据BMIH结构的biBitCount颜色位深属性和biWidth像素宽属性,即不足1字节的按1字节计(例如单色图和4bit图),总的字节数保证能被4整除。用switch语句判断有:b) 获取像素数组的字节大小srcSize,有几种方法:i. srcSize = bmfh.bfSize - bmfh.bfOffBits; /即总大小减偏移量ii. srcSize = bmih.biHeight * cxBytes; /即高度 乘以 实际宽度iii. 教训!最好不要根据bmih.biImageSize属性直接得到图的总大小,许多24位图的biImageSize属性值为0。3. 算

9、法3:void ToGray_8bit(BMIH *pDstInfo, BYTE *pDstBits);A. 算法功能:将图片转换为8bit灰度图B. 算法思想:首先判断图的位深,如果是单色图和4bit图,则先转换为8bit图(转换前后图片内容不应发生改变,编程运行时检查这一点以确保转换是否正确),然后再对每个像素(1个字节)对应调色板的RGB分量进行灰度计算,所得值替代像素值(不是替代调色板值);如果是24bit图,则处理时利用每个像素点(3个字节)进行灰度计算直接得到8bit灰度图。无论哪种位深的图,最终都必须将调色板设置成256长度且有对应关系:ColorTablei中Red=Green

10、=Blue=I;最后还得设置新图像的infoheader信息头和fileheader文件头C. 算法逻辑:a) 单色图:对原像素数组每个字节进行8次“按位与”运算,自高位到低位依次判断是位值是0还是1;单色图本身不需要灰度处理。b) 4bit图:对原像素数组的每个字节进行两次位运算,取出高4位和低4位,作为新8bit图的对应调色板索引号,再根据每个像素点对应调色板的RGB分量进行灰度计算。如果只是为了完成灰度显示,则最简单的方法是直接更改调色板,但实际遇到个错误,就是往后的平滑等处理时如果仍采用原来的调色板和调色板索引号就会混乱不堪,所以这里无论如何也得同时改调色板和像素数组!c) 24bit

11、图:对原像素数组每次取3个字节,分别得到RGB分量。d) 8bit图:不需要进行图像格式转换,且每个字节对应1个像素,直接取对应调色板中的RGB值进行灰度计算e) 最后配置图像信息,其中:i. 文件头调整:bfSize和bfOffBits属性,得到正确图像大小ii. 信息头调整:biImageSize属性和biBitCount属性,确定位深为8iii. 调色板调整:调色板为256长度,且每个调色板RGB分量和索引号一致4. 算法4:Smooth(int n, BYTE *pBuffer);A. 算法功能:完成灰度图的4领域或8领域平滑处理B. 算法思想:一幅图分为6区域特别处理:四个顶点、上下

12、左右边界以及中间区域;平均算法采用简单算术平均,优点是整型运算,量小效率高C. 算法逻辑(以8邻域模糊为例):依次处理6块区域:5. 算法5:void ToBinValue_8bit(BYTE *pBuffer);A. 算法功能:实现灰度图的二值化B. 算法思想:找到一个合适的阈值,当灰度值大于该值时,颜色变为白色(255,255,255);当灰度值小于该值时,颜色变为黑色(0,0,0)。这里简单地采用平均值算法寻找阈值,即遍历所有像素点的灰度,统计得到平均灰度并将其作为阈值。C. 算法逻辑:a) 寻找平均值阈值(简单通过2重循环完成统计)b) 第二次双循环遍历像素数组,灰度大于阈值则为白,小

13、于则为黑6. 算法6:Island();A. 算法功能:实现8bit灰度二值化图像的连通域分析。B. 算法思想:采用压栈思想实现连通域统计和标号。从图像某一个像素点出发(一般选择第1点),检查当前点是否为已存在连通域标记,否则再检查是否为黑点,如果为未标记的黑点,则标记它,然后检查周围4邻域是否存在未标记的、未入栈的黑点,如果存在,则将它们送入栈中;一旦栈中非空,则每次从栈顶取点检查,一次压栈中所有点的连通域标号一样。栈空后则继续下一个位置的点检查。实际编程中,考虑使用一个while循环和动态数组stack模拟栈操作,这是因为,栈中已标记的点可以提前出栈,减少堆积,而普通递归函数调用无法做到这

14、一点。C. 算法逻辑:7. 算法7:void RGBtoHSL(HSLpoint *pHSL);A. 算法功能:实现RGB颜色空间向HSL颜色空间的转换,在HSL空间,可以直接调整色相、饱和度和亮度B. 算法思想:考虑到颜色种类,这里仅实现24位图的HSL空间转换,因为24位图颜色丰富,能基本表现所有颜色。C. 算法逻辑:根据已知的(R,G,B)a) M=max(R,G,B);b) m=min(R,G,B);c) H=60 * G - BV + 360 % 360; M=R60 * B - RV + 120; M=G 60 * R - GV + 240; M=Bd) L=M+m2e) S=M-

15、m1-|2L-1|f) 其中,H为色相,取值0-360;S为饱和度,取值为0-1之间的浮点数;L为亮度,取值为0-1之间的浮点数。g) 在HSL空间可以直接调整HSL属性,但要将图像输出,还得将HSL空间逆转换为RGB空间。8. 算法8:void* newPage(size_t new_size), void* allocate(size_t need_size)内存的开辟和申请【本部分内容借鉴于上学期数据结构中的链表知识】A. 内存开辟:内存页的新开辟需要在向系统申请成功后配置好页头结点【保存当前页的容量等信息并链接好下一结点】,配置好每页的头尾块结点【方便free内存块的处理】B. 内存申

16、请:从第一个块结点开始遍历,检查符合条件空闲块,第一个符合条件的就立即分配【全部分配或部分分配】;由于内存页使用的是前插法的单向链表,而第一个块结点是最新申请内存页的第一个块结点,故一般能完全快速分配。如果第一次分配中不存在符合条件的块,则考虑调用newPage()函数,开辟一块更大的内存页【程序中设定为1.5倍】,再从新页中获得申请。如果开辟失败,则返回申请失败。块一旦分配,则新增一个块结点,并调整好双向链表关系,以及块上标志的容易关系。五、程序运行分析1. 主界面:主视窗(上)用于查看图片和菜单操作,副视窗用来浏览、切换保存在内存中的图像。如图所示2. RGB通道频谱分析:显示各颜色亮度分量所占比重大小,如图所示:3. 灰度及其频谱:4. 平均二值化5. 邻域平均6. HSL空间变换:(依次是原图,处理后图像),其中调整了亮度,饱和度。六、归纳总结本次简单的程序设计实践旨在初步了解BMP文件的处理和初步认识软件工程实践的运作方式。主要以了解程序框架设计和算法逻辑为目的,故采取了一些必要措施

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论