switch ( VcImageProc ) case 2:Introduction of 灰度阈值变换算法 Demo —— “纯粹的线条”

来源:转载

一、前言

之前在《VcImgProc小插曲》中,笔者对系列博文的安排做了一些调整,把对 DEMO 的介绍(也就是本篇博文啦)放在了前面,提前进入情景。

为什么要提前?第一,我考虑到 “自顶向下” 的学习方法效果往往比 “自底向上” 更好,能够更早接触实际问题,学习起来也更加有劲儿;第二,数字图像处理的算法实现是个技术活儿,在笔者眼中,技术的意义并不在技术本身,而在于它所能够带来的改变。

本篇博文首先从某一特定情景出发,引入了自己遇到的一个小问题,然后介绍了解决此问题所需的算法——灰度阈值变换的原理,最终初步讨论了如何实现此算法,为后文做铺垫。

二、情景

笔者是一个业余的钢笔书法爱好者,喜欢没事儿在纸上涂涂写写,字也就慢慢练好了。

首先展示一下我的绝世神兵 —— 英雄616,超便宜(10元)却超级好用!

喜欢边听歌边练字,非常有感觉,下面是摘抄的 JJ《醉赤壁》的歌词:

写完了当然用相机拍一下保存起来,可惜我在 camera 方面是个小白,傻瓜相机也觉得我傻!结果自然照出来的效果不行了,底色太暗了,整体上呈现一种灰蒙蒙的感觉,

该怎么办?怎样把讨厌的灰色背景去掉的同时,又不会破坏钢笔字本身的线条?

三、灰度阈值变换

现在,我们从数字图像处理的角度来分析如何解决这个问题,可以分为两步来进行:

(1)转换成灰度图像

首先,上面的图像是 24 位真彩色图像,每一个像素都包含 R、G、B 分量,每个分量占用 8 bit。但是对于钢笔字来说,就是白底黑字嘛,其他的颜色基本上毫无意义,所以我们首先就要把 24 位的真彩色凸显转换成 8 位灰度图像。所谓灰度图像,就是每一位的像素由 8 bit 构成,可以表示从 0(纯白色) ~ 255(纯黑色) 一共 256 个灰度级。这样转换之后,处理起来会更加方便,也可以减小图片的大小。

从RGB转换成灰度图像,我们可以利用现有的公式:

接着我们按下 Ctrl + M,出现一个对话框:

这就是灰度变换的坐标图了,怎么看呢?横轴代表源图像的灰度级(0~255),纵轴轴代表变换后的图像的灰度级(0~255),而坐标轴中的曲线就表示两者之间的对应关系了!大家可以看到曲线初始化的时候,它的表达式可以写作:

这里我们设置的阈值是77,在 77 以下的灰度级全部变成白色,以上则变为黑色。

再看看变换后的图像吧:

对比一下之前的图像:

可以发现,变换后,钢笔线条显得非常醒目,清晰挺拔,可以说基本上达到了所要的效果。(有个小缺憾就是把第一行反光的文字基本上腐蚀得几乎看不见了......)

五、结语

上面,我们借助强大的 PS 的力量,预演了灰度阈值变换算法,

PS 强大归强大,但是强大的终究是软件(而不是你),如果不懂得背后运行的算法,那么你只是个工具的使用者罢了。再说了,每个程序员可都是天生的 DIYER ,呵呵,“自己动手,丰衣足食” 可是毛爷爷留给我们 coder 的箴言! 恩,接下来我们就考虑如何来动手实现灰度阈值变换算法。

那么在搭建好 Vc 平台后,我们想要在平台上实现此算法,接下来该做些什么呢?

(1)图像处理类

要处理图像,首先得有个封装图像数据和一些基本函数的类才好吧,这样的话可以充分利用类的好处,更加方便。

c# 中有 Bitmap,而 MFC 中也有 CImage。那是不是直接用 CImage 就万事大吉了?不是,原因会在下一篇博文中讨论。

(2)必要的 MFC 知识(只是必要的...) 

借助 MFC 实现算法演示,总得对 MFC 有最基本的了解吧,至少要懂 Document/View 结构,还有 CMenu(菜单类)+ CDialog(对话框类)这一些必须用到的控件有一定了解。

以上两点,也是接下来的两篇博文所要讨论的类容,敬请期待系列博文之:

swicth ( VcImageProc ) case 3:CImg 和 CImgProc —— 图像操作和处理类

绿色通道:好文要顶关注我收藏该文与我联系


分享给朋友:
您可能感兴趣的文章:
随机阅读: