任务 对一张暗度较高的图像进行处理,直方图均衡的结果差强人意。 感到有白色噪点分布,视觉效果不好。采用同态滤波的方式进行处理,滤波方式尝试理想滤波、butterworth滤波以及gaussian滤波。 代码 思路 按照光图像的成像原理,可以对一幅图像进行简单建模: 𝒇(𝒙,𝒚)=𝒊(𝒙,𝒚)·𝒓(𝒙,𝒚) 即把图像亮度 𝒇(𝒙,𝒚) 看成是由入射分量(入射到景物上的光强度)𝒊(𝒙,𝒚) 和反射分量(景物反射的光强度)𝒓(𝒙,𝒚) 组成。 同态滤波的基本思想是减少入射分量 ,并同时增加反射分量 𝒓(𝒙,𝒚) 来改善图像 𝒇(𝒙,𝒚) 的显示效果;𝒊(𝒙,𝒚) 在空间上变化缓慢,其频谱集中在低频段,𝒓(𝒙,𝒚) 反映图像的细节和边缘,其频谱集中在高频段。 为了将入射分量和反射分量分离,方便进行入射分离的削弱和反射分量的增强,需要对图像先取对数,再进行傅里叶变换,对频谱上设计相应的传递函数进行滤波后,反变换回空域,指数处理后就得到了相应的增强图像。 整个过程的流程是比较清晰的,最初容易迷惑的一点是如何获得入射分量 𝒊(𝒙,𝒚) 和反射分量 𝒓(𝒙,𝒚)——二者无法分离得到具体数据,只是在频域中有区分度。 此外,最核心的一点是设计滤波器实现对两种分量的作用,这对整个滤波效果的影响是最为显著的。过程中,我首先简化问题,设计理想滤波器实现,思路如下: 在傅氏变换后的频谱图中,未经频移时,低频分量在四个角落,高频分量在中心点处。为了符合认知,故先将变换后图片进行频移,进行处理后,再反向频移。 此后,为了达到更好的效果,又采用butterworth函数与gaussion函数实现滤波,并对其效果进行对比。 实现效果 理想滤波 代码 第一开始出现的效果很好,如右下角图所示,整个画面出现了一些事物的轮廓。但发现函数中未增加取指数部分,因此效果主体原因是动态范围压缩的作用(log(1+s))。当用直接动态压缩做为对比时,可见二者没有明显差别。 在原函数的基础上进行参数的调整,并没有较好的效果出现。 对不同截止频率得到的结果图像放大细节,可以看到有振铃效果出现。 butterworth滤波 用幂系数n可以改变滤波器的形状。n越大,则该滤波器越接近于理想滤波器。高通滤波即用1减低通滤波函数。 代码 不同截止频率 随着截止频率的提升,被压的低频成分增加,图像颜色愈深。 不同下限倍乘 不同上限倍乘 Gaussian滤波 代码 最终运用Gaussian滤波,将三者进行对比 对比总结 直方图均衡对于改善低照图图像的灰度分布有更好的效果,可以显著地凸显暗部,增强对比度,将原图中难以观察到的物体都能够很好地显示。但由于直方图均衡合并了一些灰度级,也使一些部位的边缘细节被抹去,例如车上的车窗,集装箱上的条纹等等。 而同态滤波仅仅对具有丰富,锐利边缘的细节进行了增强,但并不能改善原图像的暗部,因为原图像的暗部也是低频成分居多。 同时,直方图均衡的效果与图像本身的性质关联不大,在任何图像上都能取得不错的效果。但同态滤波参数的设置需要根据图像的特点进行配置,同一套参数在往往在另一幅图像上的效果很不理想,若想要同态滤波取得比较好的效果,需要先根据图像设置参数。 总的来说,直方图均衡更具有自适应性,同时能从图像总体上进行增强,无论是暗部还是高光,都起到增强对比度,提升细节的效果。同态滤波可以提升边缘的细节,压缩图像的动态范围,从而提升对比度。 参考文章 把一个矩阵矩阵范围拉伸到minVal~maxVal的范围内 数字图像处理-频域滤波-高通/低通滤波 《数字图像处理 实验报告》施珉
Category: 学习记录
关于自动化类课程,关于个人网站,关于感兴趣的领域,关于竞赛比赛……
在广阔天地学习,兼收并蓄
空域锐化滤波与高频增强滤波
任务 在空域进行系列实验后,形成一个灵活性较强的函数,能够传递3*3的卷积核进行卷积,若采用拉普拉斯算子,则为锐化滤波;同期进行频域增强的实验,比较二者的区别。 (另:想要实现对模糊图像的增强处理,目前没有方法) 空域锐化 代码 效果展示 不同算子 高频增强 采取理想高通滤波器,且进行近似简化——把圆形转化为矩形域,方便矩阵操作。可以快速一窥效果如何 代码 效果展示 显示的反变换图像为截去至原图大小后的结果(边缘被扩充),可以验证FFT算法的有效性。此外,可以看到,随着阈值的提高,图像的边缘处得到增强,大量细节丢失。直到最后损失所有信息。 参考文章 灰度图像的频率域滤波——理想高通滤波器(Matlab) matlab 傅里叶变换 高斯高通滤波
空域滤波-中值滤波
任务 在进行均值滤波后,相类的对空域的操作是中值滤波。即百分比滤波的一种特例,使中心点像素值为模板覆盖所有像素值排列后某特定位的值。 百分比滤波 代码 实现效果 与均值滤波对比 与均值滤波相比,去噪效果较好,且清晰度较高。 不同百分比对照 可见,在百分比选取在0.2~0.5之间时,去噪效果较好,当百分比升高,选取的像素值趋近噪点,使图像出现大片雪花。 修改模板大小 代码 实现效果 百分比选取固定值不变(中值0.5),随着模板的增大,图像的噪点趋于平滑。但模板更大时,整幅图像模糊化。
空域滤波——均值滤波
任务 对于空域滤波主要是提供某种卷积核,使图片中与这一模板相似的成分得到增强。 平滑滤波器 均值滤波 主要思路是,将边缘像素值保留,内部置0;因为整数运算更快,所以先将边缘*9,与之后进行处理的其他像素点的范围一致,再最终/9得到滤波后图像。 均值滤波函数 matlab的添加噪声函数imnoise需要下载图像处理工具箱,可以利用文章MATLAB–数字图像处理 添加椒盐噪声的方法得到椒盐噪声图像,进行滤波效果的展示。 椒盐噪声函数 结果展示 不同大小卷积核的作用效果 教材中提到的一点,当变换不同大小的平滑模板作为卷积核时,图像效果会有变化:具体表现在,平滑模板越大,噪声消除增强,但图像更模糊。 改进函数,可以对平滑模板的大小利用传参n进行设置。 模板大小可调节函数 实现效果 分别将模板大小调节为3×3/5×5/7×7/9×9,对比显示,可见效果确实与推测一致。 只是由于模板越大,保留的边缘也越大,出现了边缘像素值的噪声分布明显的情况,现提出两种解决方案: 直接截去边缘像素部分 对边缘像素部分减小模板进行计算 下面对方法二进行实现。 边缘处理 思路是,通过补-1(不在像素值0~255的有效值表示范围内)扩展原灰度图的大小,使得边缘的像素点也能够使用同一模板计算。 核心需要一个能够统计矩阵中不为-1个数的表达式,形如[cnt,~]=size(sum(convM(convM~=(-1)),3));其中cnt为矩阵convM中不为(~=)-1的个数。 边缘处理函数 最终效果 可见,此时边缘的噪声也得到了一定程度的去除。 参考文章 MATLAB–数字图像处理 添加椒盐噪声 matlab怎么求一个matrix中非0的平均值
快速傅里叶(递归)
matlab图像增强-利用位面图传输密文
2020.10.4更新: 发现虽然在图像中加入密文成功,但在利用函数imwrite()保存图像时,因为格式jpg为压缩格式,实际上对图像数据进行了变换,属于有损压缩。 因此需要选择矢量图的保存方式,如bmp.因此原本上传的图像无法正常解密,现在更新的图像可以。此处感谢@yezixuan的指正! 任务 数字图像课程中一个很有趣的一个地方是位面图,即把灰度图的8位拆解,并将各位输出图像。但前面的高位体现出图像的细节,低位几乎没有影响。因此老师提到一个思路是通过图像传输密文,这里进行模拟体验。 过程 获取位面图 首先将图片转为灰度图,再将灰度值用二进制编码表示,最终得到各平面的结果。 下面代码是第8位(最低位)的位面图输出过程,其他各位相似。 位面图像 加密 利用工具:汉字二进制转换器。将需要传递的文字信息转化为二进制编码。 下一步,只需要将二进制编码以约定形式集成到图片中,再通过叠加传输至对方手中,进行解密即可。 字符串切分 在工具中将utf-8编码的汉字转化为二进制,根据网页提供的资料可知,每个汉字对应的编码为3字节,即占据3*8bit=24bit。 不同的字符集对同一个多字节字符的编码可能不同,并且对其编码的字节数也可能不同。例如“中”字,Unicode使用4字节表示,UTF-8使用3字节,GB18030则使用2字节不同的编码表示。所以在汉字与二进制转换中需要考虑到字符的编码,通常,按照UTF-8编码与二进制进行转换。 汉字二进制转换器 因为matlab提供字符串分割函数split(str,’ ‘),与python中用法相同,即将字符串str用引号内的字符分割开来,且引号中的字符被舍去。 hint:与split()形成反函数的对应函数为join(),可以将得到的密文字符串重新合并。 需要注意的问题是,应用函数split()后得到的是cell类型的数组,不可能直接赋值给char类型的数组,需要强制类型转换。 加密效果 由于只更改了部分像素点灰度值的最末位,故显示在灰度图上肉眼不可区分,能够实现传输密文功能。 解密 下面是添加密文之后得到的图片,全部过程已经包含在代码中。有兴趣的朋友可以尝试解密,成功者惊喜奉上。 下载图片链接
matlab数字图像处理——直方图均衡重现老照片
任务 在课堂上学习了直方图均衡化的处理手段,看到外国女子的脸部增亮,这是在空域中实现变换增强的方法之一。尝试在matlab中实现相关方法,并用网上的老照片进行实验,效果不错。 过程 得到灰度图的直方图 灰度图的获取可以参考博文matlab数字图像处理——RGB转灰度图,当然也可以直接调用系统函数rgb2gray() 直方图其实是统计不同灰度等级的像素点数目大小,并通过除以图像像素点总数目,得到归一化结果/概率。 得到累积直方图 因为需要对灰度等级进行映射——把某个阶段的灰度值对应到均衡的结果,那么我们需要取得中间变量:累积直方图。 得到映射关系 映射关系可以利用matlab的矩阵运算实现,直接将表达式中的变量用矩阵替换即可。分别表述这行代码中变量的含义: cRecord:上一部分得到的累积直方图 256:总共的灰度等级 -1是因为在matlab中,uint8的范围在0~255 mapValue: 索引值继承等号右边唯一的矩阵——cRecord的含义,是每个灰度等级 内部的值表示通过运算映射得到新的灰度等级 根据新的映射关系修改原图的灰度值 这一步的目的比较清晰,已经通过上一步得到了映射关系,只要将原图中的灰度等级修改为映射后对应的灰度等级即可。 问题与解决方法 残影 整个过程比较顺利,只是第一次显示直方图时有些奇怪: 结果图P5只能隐约看到lena的轮廓,通过显示该图像的变量类型找到答案,变量并非图像的uint8类型,而是double类型。问题出在初始化变量上,我利用zeros()函数,当我把赋值改为强制类型转换后,问题解决。 class(newImg) ans = ‘double’ 结果展示 参考资料 如何提取特定位置以后的字符串(出处: MATLAB中文论坛) MATLAB中画柱状图
matlab数字图像处理——RGB转灰度图
应用不同算法或算式,实现RGB转灰度图,并对性能进行评估
matlab实现FFT(快速傅里叶变换)
任务 接上篇,尝试使用快速傅里叶变换实现空域到频域转换 过程 判定2的幂次 由算法可知,对于长度为2的幂次的序列可以进行变换,但对于大多数情况非2的幂次应该如何解决?答案是补零至2的幂次。 判定 简单的判定方法,利用2的幂次(M)在二进制中的独特性,首位为1,余位为0;且减1后(M-1)原首位为0,余位为1,则有M&M-1=0 matlab中的按位与函数为bitand(),与&不同 bitshift(num,n); num表示需要移位的数,十进制; n为正左移,负右移。 求大于一个数字的二进制的最高位 思路,通过移位,当非2次幂数的第i位移出使原数为0,则最高位为i。可以将2次幂数-1转换为相同情况。 函数实现 首先强制类型转换,转换为固定的uint8类型。 matlab没有三目运算符,则用if…else语句实现。将特殊情况0单独列出, 调用临近最高位的求取函数highestOneSite(M) 位的对换 算法实现需要将输入数据排列为满足算法需要的次序,可以推导发现,满足的映射规则为第x个数为x的二进制数颠倒后的结果。 a是0~255的整数 b=dec2bin(a,8);%b是8位’0′,’1’字符串 h=b(1:4); %高四位 l=b(5:8); %低四位 MATLAB中怎么将一个常数(0到255)转为8位二进制数–dukinkin 但在matlab中,由于数组下标从1开始,需要进行-1的操作进行映射 即F(abcd)《-》f(dcba) bottom-up实现 足足思索了几个小时,终于捋清x点变换的逻辑。 指数部分函数W表示 其中W可视为函数: matlab代码为: 首先从一维开始理解,由于需要变换的矩阵长度已经过判定2的幂次并补零至最邻近的2的幂次(N=2^n),则可通过不断奇偶二分,从原始的N点变换,分解为两个N/2点变换,再到N/4点变换、……、8点变换、4点变换、2点变换。最后的1点变换,因为公式(1)中u为0,则指数项为0,即1点变换视为原值。 上面的思路确定了如何从需要变换的函数得到分解因子,本次实现通过从因子逐层自底向上推出。重点在于清楚公式中的分子的表示,以及在存储矩阵中的位置。 二维实现 利用matlab实现DFT(离散傅里叶变换)与优化 的读取图像和灰度图转换,得到了灰度图像grayImg 再利用之前的频移函数showShiftImg(twoD)得到频移到中心点的图像。 matlab技巧——如何利用其他文件夹下的函数 addpath D:\Matlab即可使用路径D:\Matlab下的函数 结果展示 ans = 442 785 3 时间已过 17.532276 秒。 现在运行给定图像需要的时间实际为17.5s,相比于优化后的DFT的12s居然不降反升,所以要想达到更有效的应用,需要继续优化。 参考文章 《图像工程 (上)<图像处理和分析>》… Continue reading matlab实现FFT(快速傅里叶变换)
matlab实现DFT(离散傅里叶变换)与优化
任务 《数字图像处理》课程布置: 编写程序(建议Matlab )对某选定图像(自行转换为灰度图)展开傅里叶变换,提取傅里叶变换图像(将频率原点移至图像中心) , 并形成实验报告。 为与matlab中代码一致,便于理解,此处的公式我全部整理为数组从下标1开始。此外,增强特殊性,图像大小为NxM 基本知识 此前尝试用matlab实现傅里叶变换,用基本公式对方波函数进行傅氏变换。但其特点: 函数连续(在matlab进行抽样离散处理,绘制波形) 范围趋近无限(在matlab中把n取大值范围) 可见,对于模拟值用计算机进行傅氏变换需要首先进行离散处理,那么对于本身是离散值的数字图像,则直接利用离散傅里叶变换即可。 这里图像大小为NxM 前面括号内的系数其实可舍去,主要起到归一化的作用,因此形式不必纠结。 首先,将二重变换利用傅氏变换的性质可以分解为两次单重变换: 与公式相一致:本人代码先按行遍历,对列(y表示)变换;再按列遍历,对行(x表示)变换 过程 读取图像 测试图片选取经典上图,但大小是压缩的200×200,因此对于初次使用比较友好。 matlab中句末引号可选,不加则会输出左值结果至命令行窗口,如上述代码的size(Img) 转换为灰度图 通过在读取的图像信息判断是否为单通道,是则直接使用,否则将RGB图像通过转换函数rgb2gray()转换为灰度图。 三重循环实现 可以通过tic,toc放在代码前后进行时长测试 注意u和v的范围是从0开始取值 ans = 200 200 3 时间已过 12.674382 秒。 频移函数 这里直接显示经过处理后的傅氏变换的图像 核心是将原图四个角点移至中心位置,可以通过matlab中矩阵处理的语法便捷实现 由于非偶数会出现不能被2整除情况,因此需要做取整处理 优化 使用上述算法经过讨论,复杂度为O(N^3),并且在处理更大尺寸的图像(老师提供785×442)时,运行时间极长。 因为了解到matlab对矩阵运算具有高效快速优点,便把思考放在如何将算法通过矩阵运算实现。 思路同样是通过两个一维变换完成,因此只以分析按行遍历,对列(y)展开为例,对思路进行陈述。 观察到公式中的基函数部分其实已经固定,因此直接通过相乘获得某个频率分量(Vn)对应的不同y值得出(某个频率分量)所有计算需要的指数部分,如下所示: 共N列 下一步将图像信息与对应的分量对应相乘,得到,那么加和则是对每行相加——每一行的x保持不变。最终得到一维转换后的结果: 具体代码 时间已过 16.837070 秒。 此用时与分钟相比下降很多,但比较系统中的fft(),用时约为0.1s,因此下一步可以思考如何进行快速傅里叶变换的使用。 参考资料 Matlab-结构体数组的索引 matlab里的图像处理函数