您的位置:首页 > 编程语言 > MATLAB

不用递归的方法计算米粒的个数和每个米粒的面积,matlab实现

2011-10-28 22:05 706 查看
% 利用系统自带的米粒图片rice.png, 对该图片进行预处理后,计算该点中每个米粒的面积和所有米粒的个数,中间用到了求一个点所在的连通域的算法
clear all
clc
close all
I = imread('rice.png');
edI = edge(I, 'canny');
fhI = imfill(edI, 'hole');
se = strel('disk', 4);
opI = imopen(fhI, se);
% opI = ones(100,100);
% opI = im2bw(opI);
figure,imshow(opI);
[row col] = size(opI);
count = 0;
ricearr = zeros(row*col,1);
visited = zeros(size(opI));
% 调用计算连通域函数进行数米粒和计算米粒的面积
for i = 1:row
for j = 1:col
if opI(i,j)&&visited(i,j) == 0
count = count +1;
pt = [i; j];
[c ,domain] = finddomain(opI, pt);
ricearr(count) =  c;
for m = 1:c
visited(domain(1,m), domain(2, m)) = 1;
end
end
end
end
disp('米粒的个数为');
disp(count);
disp('每个米粒的面积为');
disp(ricearr(1:count));


%  求一个点所在连通域的算法
function [c, domain] = finddomain(input, pt)
%     输入一幅图像,及图像中的一个点,得到图像中该点所在的连通域和连通域中像素的个数并输出。
%  输入一个白点,将该点周围领域的白点入队列,对队列中的点继续进行查找
[row col] = size(input);
iplus = [-1 -1 0 1 1 1 0 -1];
jplus = [0 1 1 1 0 -1 -1 -1];
visited = zeros(size(input));
stack = zeros(2, row*col);
domain = zeros(2, row*col);
stack(:, 1) = pt;
domain(:, 1) = pt;
visited(pt(1), pt(2)) = 1;
count = 1;
eos = 1;
sos = 1;
while sos ~= eos + 1
m = stack(1, sos);
n = stack(2, sos);
for i = 1: 8 %  寻找邻域中的白点,如果是白点入队列,并标明已访问过。
if m+ iplus(i) > 0 && m + iplus(i) <= row && n + jplus(i) >0 && n + jplus(i) <= col
if input(m + iplus(i), n+ jplus(i)) == 1 && visited(m + iplus(i), n+ jplus(i)) == 0
eos = eos + 1;
stack(:, eos) = [m + iplus(i); n+ jplus(i)];
visited(m + iplus(i), n+ jplus(i)) = 1;
count = count + 1;
domain(:, count) = [m + iplus(i); n + jplus(i)];
end
end
end
sos = sos + 1; % 当邻域内的点都被访问过后,该点出队列,对应指针加1.
end
c = count;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐