Matlab图像处理学习笔记(九):获取叠加物体的数量并进行分割

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010278305/article/details/42809619

本笔记说明如何对叠加物体的数量进行计数,并对其进行分割。

本文算法思路参考了Nash的思路,图像也是采用Nash的图像,为叠加硬币,链接:http://opencv-code.com/tutorials/count-and-segment-overlapping-objects-with-watershed-and-distance-transform/

本文涉及到的主要知识点如下:

1、距离变换。

2、基于分水岭变换的分割。

其中,本文采用基于标记符控制的分水岭分割,源该算法的思路来自冈萨雷斯的数字图像处理(MATLAB版)(第二版)。

算法过程如下:

1、对原始图像进行二值化。

2、对二值化后的图像进行距离变换,并归一化到0~1。

3、对距离变换以0.5为阈值进行二值化,之后获得连通分量的数量即为硬币的数量。

4、用sobel算子求梯度的幅度(因为梯度幅度图像沿物体边缘有较大模值,故理想情况下,对梯度图像进行分水岭变换可得到沿物体边缘的分水岭脊线)。

5、用最小覆盖技术处理图像,使得局部最小区域仅出现在标记过的位置(不然会导致过分割,使脊线出现在不该出现的位置)。

6、进行分水岭变换。

本文对应的matlab源代码如下:

%function:
%       用距离变换获得叠加硬币的数量,并用分水岭变换对叠加的硬币进行分割
%referrence:
%       http://opencv-code.com/tutorials/count-and-segment-overlapping-objects-with-watershed-and-distance-transform/
%       冈萨雷斯,数字图像处理(MATLAB版)(第二版)
%date:2015-1-17
%author:chenyanan
%转载请注明出处:http://blog.csdn.net/u010278305

%清空变量,读取图像
clear;close all
src = imread('images/watershed-disttrans-src-img.jpg');

figure('name','Process'),
%显示原始图像
subplot(2,2,1),imshow(src),title('src'),

%转换为灰度图像
gray=rgb2gray(src);
gray = im2double(gray);
subplot(2,2,2),imshow(gray),title('gray'),

%用ostu方法获取二值化阈值,进行二值化并进行显示
level=graythresh(gray);
bw=~im2bw(gray,level);
subplot(2,2,3),imshow(bw),title('bw'),

%Get the distance transform and normalize the result to [0,1] so we can visualize and threshold it,
dist = bwdist(bw);
maxDist=max(max(dist));
dist=dist./maxDist;
dist=im2bw(dist,0.5);

%获取边界,得到连通边界的数量
[B,Lbound] = bwboundaries(dist,'noholes');
ncomp = length(B);

titlenum=sprintf('coins:%d',ncomp);
subplot(2,2,4),imshow(dist),title(titlenum),

%Create the marker image for the watershed algorithm.
markers=dist;
%We also need to draw the background marker. 
%Assuming that the objects located at the center of the image, 
%we simply draw a marker near the border.
markers(2:8,2:8)=1;

%用sobel算子来求梯度模值
%梯度幅值在物体边缘有较大值,通过对梯度模值进行分水岭变换,
%理想情况下,可得到沿物体边缘的分水岭脊线
h=fspecial('sobel');
g=sqrt(imfilter(gray,h,'replicate').^2+...
       imfilter(gray,h','replicate').^2);

%由于存在大量的局部最小值,直接应用watershed会导致过度分割,故先用最小覆盖技术处理图像,
%使得局部最小区域仅出现在标记过的位置
g2 = imimposemin(g,markers);

%Perform the watershed algorithm.
L=watershed(g2);

%将分水岭的像素值改为255
f2=gray;
f2(L==0)=255;

%绘制识别结果
figure('name','Result');
subplot(1,2,1),imshow(f2),title('watershed pixels'),

%用不同颜色来标记每个前景物体和背景
dst = label2rgb(L);
subplot(1,2,2),imshow(dst);title('watershed region'),

运行结果如下:



源图像如下:



猜你喜欢

转载自blog.csdn.net/u010278305/article/details/42809619