数字图像处理实验——灰度映射
图像灰度映射实验
SEU_Digital-Image-Processing-Lab/Lab2
1.实验目标
本实验要求实现一个大灰度动态范围的灰度图像浏览器。该程序可以读取一个自定义格式 的灰度图像文件(格式定义见下文),设计简易的人机交互方式选择“灰度窗”,将灰度窗映 射到[0,255]并显示。
2.具体要求:
程序使用 C++语言编写,集成开发环境可以选择 vs 或 Qt,不允许使用 opencv 等第三方库。
设计人机交互界面,用户可以方便设置/调整灰度窗参数(窗宽和窗位),将 此灰度窗映射到[0,255]并显示。
鼓励扩展图像浏览功能,但不做要求,也不计入本次实验成绩。
自行编写程序从文件中读出实验图像数据。实验图像数据有效灰度范围[0, 4095],即 12 位有效灰度,每像素 2 字节(最高 4 位数据无效,有效灰度保 存于低 12 位)。数据文件为自定义格式(非标准格式),文件中的数据存放 如下图:
文件开始的 4 字节存放图像宽,其后 4 字节存放图像高,此两参数均为无符 号长整型(unsigned long),紧随其后为按光栅扫描顺序(从左向右,逐行 扫描)存放的像素值,像素值为无符号短整型(unsigned short)。所有多字 节数据都按 intel 顺序(即低字节在前,高字节在后)存放。文件不包含其它 数据。
当图像尺寸大于窗口尺寸时,应选择合适的方案由用户调整图像在窗口显示 的区域(如使用窗口滚动条、鼠标抓取图像拖动等),不允许缩小图像以适 应窗口尺寸显示。
- 两幅实验图像保存于文件 lung.raw 和 knee.raw 中,上交的实验结果应包含 以下三幅截屏图像(以下灰度窗的位置记为 [窗位,窗宽],其中窗位表示灰 度窗中央位置的灰度值,窗宽表示灰度窗的宽度):[1] lung.raw 文件包含的 图像,以灰度窗[2048,4096]显示,并将胸脊(胸椎)置于画面的中间位 置;[2] lung.raw 文件包含的图像,以灰度窗[3000, 2000]显示,并将肺 (左、右肺任选)置于画面的中间位置;[3] knee.raw 文件包含的图像,以 灰度窗[250,500]显示,并将膝关节置于画面的中间位置。
3. 实现方法
读入图像
实验给出的图像是用于医学影像的raw格式,不能直接用之前的CImage的load函数了。于是使用最原始的文件读写将图片数据读进来。这段代码读入的是名为“lung.raw“的文件。
1 | FILE* fplung; |
新建CImage图像
实验中发现CImage的create操作是需要指定调色板的,否则的话就会显示一片黑色。由于不知道怎么新建调色板,在做实验时就使用了上一次实验时图片的调色板
1 | CImg.Destroy(); |
灰度映射类
数据成员和成员函数
保存转换前和转换后的图像数据数组,并提供一个将图像数据转为CImage的方法
1 |
|
将图像数据数组转换为CImage类
1 | void CGrayImg::TransintoCImage(void) |
灰度映射方法
灰度映射实现起来其实并不是很难,其实只是一个分段线性函数。
其中参数x为窗位,w为窗宽。
灰度映射就是将小于窗口下界的设为0大于窗口上界的设为最大灰度值,剩下的按比例进行映射。
1 | void CGrayImg::GrayMapping(int x, int w) |
设置滚轮实现图片浏览
这个要求是最难实现的一个要求,主要还是由于对于MFC的机制不熟悉。其主要的实现机制在自己的ImgWnd类里。
1 | void CImgWnd::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) |