0、闲话
在学校积攒下了两种实物——书和硬币。书放进了书柜,无话;1毛的硬币,却只能存进银行。于是,前几日我带着130多枚1毛的硬币去了银行……
事先我把100枚1毛的硬币用A4纸(大小正合适)卷好了,另30多枚依然放在木糖纯的瓶子里。到了柜台后,将其一并给了业务员。她服务态度蛮好的,仔细地数了30枚,然后拿起那一卷包好的问我是多少。我说,10块。她又掂了掂看了看,说,差不多。
可见,面对大量硬币银行的业务员也不愿意一个一个地去数。这可不像大面值的纸币,差上几张,自己这几天的辛苦就算奉献了。话说Mathematica的图像处理功能是非常强大的!回家后,打开Mathematica,又找了几个1毛的硬币……
1、程序及说明
1.1、静态版
首先,将硬币放在白纸上,不要重叠,尽量留有一定的间距;然后,在合适的光线下拍一张只有纸的硬币的照片。例如下图:
考虑到光线和相机像素的不同,需要设置几个可调的参数,以增强程序的可用性。分别如下:
★ 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
im2
1.2、动态版
有了上面的核心代码,只需要稍加改进,Mathematica就可以通过连接电脑的摄像头自动数硬币了,这是实时的哦!由于程序需要连接摄像头,所以这里只给出CDF文件的下载地址,不在文章中展示。
下载地址:数硬币.cdf(百度网盘)
预览图:
2、拓展阅读
Mathematica官网中有很多免费的课程,有不少都是非常经典的。在这儿,给大家推荐一段与本文相关的课程,内容包括CT图像处理,受损图像修复,识别骰子点数等。
点此进入课程>> Image Processing: Real-World Applications
课程截图:
Mathematica的图像处理功能不仅限于此,比如模糊图像复原,色阶分析与调整,形态组合识别,人脸识别,元件聚类等等。甚至仅用一条命令就能解决一个问题,比如元件分水岭函数“WatershedComponents”,就瞬间可以找出下面迷宫的解,有兴趣的朋友可以自己试试,实际上这一案例在帮助中的“Neat Examples”(可译为经典案例)下面可以找到。
注:第2节中的图片均来自Mathematica。
这个视频怎么下载啊?
在线看呗,看完从缓存提取出来。