大致思路为将灰度图rice.png通过imbinarize函数转换为二进制图像,然后将米粒部分转换为白色像素255
创建一个数组临时充当队列,从矩阵(1,1)元素开始遍历矩阵,当碰到白色像素点时,将该像素点入队列,然后编号,
判断队列是否为空,不为空时,取出队首元素,判断该元素8个临近区域,如果也为白色像素点,则将该元素的值转换为米粒编号,并将该元素入队列
————————————————
版权声明:本文为优快云博主「蜡笔大旺」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qq_33564523/article/details/80921312
% clear;
% close all;
a=input('Enter the picture address:','s');%例如rice.png
b=input('Enter 4 or 8:'); %4连通,8连通
c=input('Is a RGB image:','s'); %y,n
I = imread(a);
connect_type=b;
if(c=='y')
I=rgb2gray(I);
end
% I = imread('rice.png');
[height,width] = size(I);
L=imbinarize(I);
[labeled_4,numObjects_4]=bwlabel(L,4);
[labeled_8,numObjects_8]=bwlabel(L,8); %调用bwlabel查看正确结果
figure,imshow(L);
L = uint8(L);%把L由logic类型转化为uint8类型
for i = 1:height
for j = 1:width
if L(i,j) == 1
L(i,j) = 255;%把白色像素点像素值赋值为255
end
end
end
MAXSIZE = 999999;
Q = zeros(MAXSIZE,2);%用数组模拟队列,存储像素点坐标
front = 1;%指明队头的位置
rear = 1;%指明队尾的下一个位置;front=rear表示队空
flag = 0;%米粒的标号
for i = 1:height
for j = 1:width
if L(i,j) == 255%白色像素点入队列
if front == rear%队列空,找到新米粒,米粒标号加一
flag = flag+1;
end
L(i,j) = flag;%给白色像素赋值为米粒的标号
Q(rear,1) = i;
Q(rear,2) = j;
rear = rear+1;%队尾后移
while front ~= rear
%队头出队
temp_i = Q(front,1);
temp_j = Q(front,2);
front = front + 1;
%把队头位置像素点8连通邻域中未作标记的白色像素点入队,并加上米粒标号
if(connect_type==8)
if(((temp_i - 1)>0)&&((temp_j - 1)>0))
%左上角的像素点
if L(temp_i - 1,temp_j - 1) == 255
L(temp_i - 1,temp_j - 1) = flag;
Q(rear,1) = temp_i - 1;
Q(rear,2) = temp_j - 1;
rear = rear + 1;
end
end
if(((temp_i - 1)>0)&&((temp_j + 1)<=width))
%右上方的像素点
if L(temp_i - 1,temp_j + 1) == 255
L(temp_i - 1,temp_j + 1) = flag;
Q(rear,1) = temp_i - 1;
Q(rear,2) = temp_j + 1;
rear = rear + 1;
end
end
if(((temp_i + 1)<=height)&&((temp_j - 1)>0))
%左下方的像素点
if L(temp_i + 1,temp_j - 1) == 255
L(temp_i + 1,temp_j - 1) = flag;
Q(rear,1) = temp_i + 1;
Q(rear,2) = temp_j - 1;
rear = rear + 1;
end
end
if(((temp_i + 1)<=height)&&((temp_j + 1)<=width))
%右下方的像素点
if L(temp_i + 1,temp_j + 1) == 255
L(temp_i + 1,temp_j + 1) = flag;
Q(rear,1) = temp_i + 1;
Q(rear,2) = temp_j + 1;
rear = rear + 1;
end
end
end
if(((temp_i - 1)>0)&&((temp_j )>0))
%正上方的像素点
if L(temp_i - 1,temp_j) == 255
L(temp_i - 1,temp_j) = flag;
Q(rear,1) = temp_i - 1;
Q(rear,2) = temp_j;
rear = rear + 1;
end
end
if(((temp_i )>0)&&((temp_j - 1)>0))
%正左方的像素点
if L(temp_i,temp_j - 1) == 255
L(temp_i,temp_j - 1) = flag;
Q(rear,1) = temp_i;
Q(rear,2) = temp_j - 1;
rear = rear + 1;
end
end
if(((temp_i )>0)&&((temp_j + 1)<=width))
%正右方的像素点
if L(temp_i,temp_j + 1) == 255
L(temp_i,temp_j + 1) = flag;
Q(rear,1) = temp_i;
Q(rear,2) = temp_j + 1;
rear = rear + 1;
end
end
if(((temp_i + 1)<=height)&&((temp_j )>0))
%正下方的像素点
if L(temp_i + 1,temp_j) == 255
L(temp_i + 1,temp_j) = flag;
Q(rear,1) = temp_i + 1;
Q(rear,2) = temp_j;
rear = rear + 1;
end
end
end
end
end
end
figure,imshow(L);
RiceNumber = flag;%记录米粒的总个数
fprintf('%d连通米粒的总个数:' ,connect_type )
RiceNumber %输出算法结果