数硬币-模式识别

0、闲话

在学校积攒下了两种实物——书和硬币。书放进了书柜,无话;1毛的硬币,却只能存进银行。于是,前几日我带着130多枚1毛的硬币去了银行……

事先我把100枚1毛的硬币用A4纸(大小正合适)卷好了,另30多枚依然放在木糖纯的瓶子里。到了柜台后,将其一并给了业务员。她服务态度蛮好的,仔细地数了30枚,然后拿起那一卷包好的问我是多少。我说,10块。她又掂了掂看了看,说,差不多。

可见,面对大量硬币银行的业务员也不愿意一个一个地去数。这可不像大面值的纸币,差上几张,自己这几天的辛苦就算奉献了。话说Mathematica的图像处理功能是非常强大的!回家后,打开Mathematica,又找了几个1毛的硬币……

1、程序及说明

1.1、静态版

首先,将硬币放在白纸上,不要重叠,尽量留有一定的间距;然后,在合适的光线下拍一张只有纸的硬币的照片。例如下图:

Coin考虑到光线和相机像素的不同,需要设置几个可调的参数,以增强程序的可用性。分别如下:

★ msize——缩小图片。对于数硬币,普通相机的像素都是绰绰有余的,所以需要截小一些,以节省计算开销。
★ thresholding——阈值。在不同的光照强度下,会得到暴光程度不的照片,需要合适的阈值才能把彩色图像转化为需要的二值图像。
★ itimes——迭代次数。此数越小,计算越快。为了方便,都是用的Mathematica现成的函数命令。各位朋友,可以在这一点上对此程序加以改进。另外,程序未经过全面测试,有待完善,有者建议请留言。

代码:

msize = 200;(*缩小图像,保持比例,宽和高都不超过msize。*)
itimes = 5;(*迭代次数,区分连在一起的硬币*)
thresholding = 0.3;(*转化为二值图像,阈值为yz*)
FileNameSetter[Dynamic[ipath]](*图像地址,以窗口方式选择*)
im = Import[ipath];(*载入图像*)
im1 = ImageResize[im, {Min[msize, ImageDimensions[im]]}](*缩小图像*)
im2 = Binarize[im1, thresholding] // ColorNegate;(*转化为二值图像,并取反色*)
im3 = FillingTransform[im2];(*填充小”洞”*)
im4 = Nest[MorphologicalTransform[#, “Min”] &, im3,
itimes];(*按”Min”方法变换图像,并迭代itimes次*)
st = “图像中共有(” <> ToString[MorphologicalEulerNumber[im4]] <> “)枚硬币。”;
Style[st, 14, Bold, Blue, “SubSubSection”](*输出结果*)

程序下载地址数硬币.nb(百度网盘)

下面是计算过程中的四张图片:im1,im2,im3,im4。

im1

Count Coins 4

im2

Count Coins 1im3

Count Coins 2im4

Count Coins 3

1.2、动态版

有了上面的核心代码,只需要稍加改进,Mathematica就可以通过连接电脑的摄像头自动数硬币了,这是实时的哦!由于程序需要连接摄像头,所以这里只给出CDF文件的下载地址,不在文章中展示。

下载地址数硬币.cdf(百度网盘)

预览图:

Count Coins cdf

 

 2、拓展阅读

Mathematica官网中有很多免费的课程,有不少都是非常经典的。在这儿,给大家推荐一段与本文相关的课程,内容包括CT图像处理,受损图像修复,识别骰子点数等。

点此进入课程>> Image Processing: Real-World Applications

课程截图:

20140125-1 20140125-2 20140125-3

Mathematica的图像处理功能不仅限于此,比如模糊图像复原,色阶分析与调整,形态组合识别,人脸识别,元件聚类等等。甚至仅用一条命令就能解决一个问题,比如元件分水岭函数“WatershedComponents”,就瞬间可以找出下面迷宫的解,有兴趣的朋友可以自己试试,实际上这一案例在帮助中的“Neat Examples”(可译为经典案例)下面可以找到。

20140125-4

注:第2节中的图片均来自Mathematica。

About the Author

野鹤

自由学者,爱好广泛,虽无一精通,却常乐在其中...

本博客已停止更新,请您移步到我的新博客阅读更多文章。