首先我们来想一想,如果我们要对一张图片中的的某件物品进行计数,我们有哪些方
法;
除了用肉眼进行观察,对计算机来说我们有哪些方法;
下面我们将使用MATLAB来对一张满是硬币的图片中的硬币进行计数,图片如下:
显然对计算机来说,图像的颜色复杂,分析起来就越困难,所以我们根据这张图的具体
情况(物品的颜色和背景的颜色差距很大,但是自身的颜色差距又不大),可以采用将图片
灰度化、再黑白二值化,然后在会二值化的图像进行标注计数,来达到计数的目的。
(1)首先打开MATLAB软件,将工作目录转到这张图片所在的文件夹下,再新建一个脚
本或者实时脚本都行,也可以直接用命令行来写后面的代码也没问题;
注:脚本代码的执行可以直接点F5,也可以单击上方的绿色的三角形图标;
(2)第二步在脚本框或者命令行中输入以下代码并执行将目标图片引入进来并查看图
像:
image = imread("这里放图片的路径");
imshow(image);
image就是引入进来的名字,而imread(filename)函数就是从图形文件读取图像;
imshow(I),就是显示图像。
(3)第三步就是将图像转化成灰度图,执行以下代码,并查看效果:
gray_image = rgb2gray(image);
imshow(gray_image);
rgb2gray(RGB或颜色图)将RGB图或者颜色图转化成灰度图;
(4)第四步就可以直接用自动二值化化函数,也可以像我这样一步步自己来,先查看以
下灰度图中硬币和背景的颜色值的范围:
imtool(gray_image);
然后再按照下图操作,查看:
然后我们发现硬币部分的颜色值大多都在一百五十往上两百多,而背景部分的颜色值大
多都在四五十左右,所以我们可以根据这些数据手动大概选择一个二值化的依据阈值;
(5)第五步我们将灰度图二值化成黑白的,并查看效果,这里我们以颜色值120作为分
界线,灰度图中颜色值大于等于120的将变为1,小于120的变为0:
bw_image = gray_image > 120;
imshow(bw_image);
(6) 第六步,由上图我们可以发现,在图中仍然存在很多噪点,所以我们需要消除噪
点,使统计更准确,接下来初步除噪:
bw_image2 = imfill(bw_image,"holes");
imshow(bw_image2);
imfill(BW,"holes")填充图像区和孔;
(7)第七步,显然经过初步除噪后,仍然还有几个小的噪点 ,所以我们需要进行进一
步的处理:
SE = strel("disk",5);
bw_image3 = imerode(bw_image2,SE);
imshow(bw_image3);
其中strel("disk",r)是创建一个半径为r盘形的结构元素,这里的这个半径可以根据你
所需要除去的噪点的大小来调整(一定要确保硬币之间互相不连通),imerode(I,SE)就
(8)第八步,显然经过去除噪点后,每一个硬币都已经成为了一个单独的图像区,可以
用来统计计数了:
[L,num] = bwlabel(bw_image3);
disp(num);
[L,n] = bwlabel(BW),
即在 BW 中找到的连通对象的数量并返回给n,
bwlabel(BW)就是用来对二维二值图像中的连通分量进行标注的;
最后得出的就是计数后的结果15,显然是正确的 ;
如果还想了解这些函数的具体应用的话可以到MATLAB的官方帮助网站上去搜索函数名查看
即可,这里我给出一个官网地址:帮助中心 - MATLAB & Simulink