数字图像处理实验04——图像分割

数字图像处理实验04

图像分割

针对测试图像,运用区域增长法进行分割,通过调整criterion的值,分析分割结果的差异和好坏

主函数
input=imread('cameraman.jpg');
[row,col]=size(input);
seg=reshape(1:row*col,row,col);
criterion=2/4/6/8/10;
connectivity=8/4;
[seg,seg_arr,reg_info]=region_grow1(input,seg,criterion,connectivity);
seg=uint16(seg);
imshow(histeq(seg));
get8ngb函数
function ngb = get8ngb(rows,cols,x,y)
  % 用来获取矩阵中一个元素的8-连通相邻元素的坐标,结果存放在ngb中。
  % 如果(x,y)是矩阵边界或顶角元素,获取的将是实际的相邻元素的坐标。如边界
% 像素有5个相邻元素,而顶角元素有3个。
if ((x ==  1) & (y == 1))       % 处理左上角
    ngb(1:2,1:1) = [2 1]';
    ngb(1:2,2:2) = [2 2]';
    ngb(1:2,2:2) = [1 2]';
  elseif ((x == rows) & (y == 1))   % 处理左下角
    ngb(1:2,1:1) = [rows 2]';
ngb(1:2,2:2) = [(rows - 1) 2]';
    ngb(1:2,2:2) = [(rows - 1) 1]';
  elseif (y == 1)                   % 处理左边界
    ngb(1:2,1:1) = [(x+1) 1]';
    ngb(1:2,2:2) = [(x+1) 2]';
    ngb(1:2,2:2) = [x 2]';
    ngb(1:2,4:4) = [(x-1) 2]';
    ngb(1:2,3:3) = [(x-1) 1]';
  elseif ((x == 1) & (y == cols))       % 处理右上角
    ngb(1:2,1:1) = [1 (cols-1)]';
    ngb(1:2,2:2) = [2 (cols-1)]';
    ngb(1:2,2:2) = [2 cols]';
  elseif ((x == rows) & (y == cols))    % 处理右下角
    ngb(1:2,1:1) = [rows (cols-1)]';
    ngb(1:2,2:2) = [(rows-1) (cols-1)]';
    ngb(1:2,2:2) = [(rows-1) cols]';
  elseif (y == cols)                 % 处理右边界
    ngb(1:2,1:1) = [(x+1) cols]';
    ngb(1:2,2:2) = [(x+1) (cols-1)]';
    ngb(1:2,3:3) = [x (cols-1)]';
    ngb(1:2,4:4) = [(x-1) (cols-1)]';
    ngb(1:2,5:5) = [(x-1) cols]';
  elseif (x == 1)                   % 处理上边界
    ngb(1:2,1:1) = [1 (y-1)]';
    ngb(1:2,2:2) = [2 (y-1)]';
    ngb(1:2,3:3) = [2 y]';
    ngb(1:2,4:4) = [2 (y+1)]';
    ngb(1:2,5:5) = [1 (y+1)]';
  elseif (x == rows)                % 处理下边界
    ngb(1:2,1:1) = [rows (y-1)]';
    ngb(1:2,2:2) = [(rows-1) (y-1)]';
    ngb(1:2,3:3) = [(rows-1) y]';
    ngb(1:2,4:4) = [(rows-1) (y+1)]';
    ngb(1:2,5:5) = [rows (y+1)]';
  else                          %其他
    ngb(1:2,1:1) = [(x-1) y]';
    ngb(1:2,2:2) = [(x-1) (y-1)]';
    ngb(1:2,3:3) = [x (y-1)]';
    ngb(1:2,4:4) = [(x+1) (y-1)]';
    ngb(1:2,5:5) = [(x+1) y]';
    ngb(1:2,6:6) = [(x+1) (y+1)]';
    ngb(1:2,7:7) = [x (y+1)]';
    ngb(1:2,8:8) = [(x-1) (y+1)]';
  end
region_grow1函数
function [seg,seg_arr,reg_info]=region_grow1(im,seg,criterion,connectivity)
%输入参数:
% im: 用于分区的图像
% seg: 图像初始标签矩阵,与im大小相同。通常它的每个像素都有不同的标签值
% criterion: 判断区域合并与否的条件值
% connectivity: 邻域连通的大小,取4或8
% 输出参数:
% seg: 分割后的图像
% seg_arr:  每次循环处理的图像分割的结果,是中间图像
% reg_info: 记录各个分割区域的信息的结构

rows=size(im,1); %计算图像大小
cols=size(im,2);
reg_info=repmat(struct('size',0,'crt',0,'row_coord',[],'col_coord',[]),1,rows*cols);        %记录区域列坐标
%从初始划分中收集已有区域的信息
for m=1:rows
  for n=1:cols
    c_lab=seg(m,n);
    reg_info(c_lab).size = reg_info(c_lab).size+1;
    %计算每一个区域的均值
    reg_info(c_lab).crt =double((reg_info(c_lab).size-1)*reg_info(c_lab).crt+im(m,n)/reg_info(c_lab).size);

    reg_info(c_lab).row_coord = [reg_info(c_lab).row_coord m];
    reg_info(c_lab).col_coord = [reg_info(c_lab).col_coord n];
  end
end
changed=1;  %假设第一次循环区域划分会发生变化
iter=0;     %记录循环次数
%图像发生变化时,按照规则继续分割图像
while(changed)
    disp(['Currently in iteration: ' num2str(iter+1)]);
    changed=0;
    for m=1:rows
        for n=1:cols
            c_lab=seg(m,n); %获得当前像素的标签值
            %获取当前像素的4-连通或8-连通邻域的像素坐标
            if (connectivity==4)
                ngb=get4ngb(rows,cols,m,n);
            end
            if (connectivity==8)
                ngb=get8ngb(rows,cols,m,n);
            end
            %检查所有邻域像素的标签值,按照规则依次判断是否与当前像素同区
            for k=1:size(ngb,2)
                n_lab=seg(ngb(1,k),ngb(2,k));
                if(n_lab~=c_lab)
                    if(abs(reg_info(n_lab).crt-reg_info(c_lab).crt)0)
        tmp_reg_info(index)=reg_info(m);
        index=index+1;
    end
end
reg_info=tmp_reg_info;
get4ngb函数
function ngb = get4ngb(rows,cols,x,y)
  % 用来获取矩阵中一个元素的4-连通相邻元素的坐标,结果存放在ngb中。
  % 如果(x,y)是矩阵边界或顶角元素,获取的将是实际的相邻元素的坐标。如边界
% 像素有3个相邻元素,而顶角元素有2个。
if ((x ==  1) & (y == 1))       % 处理左上角
    ngb(1:2,1:1) = [2 1]';
    ngb(1:2,2:2) = [1 2]';
  elseif ((x == rows) & (y == 1))   % 处理左下角
    ngb(1:2,1:1) = [rows 2]';
    ngb(1:2,2:2) = [(rows - 1) 1]';
  elseif (y == 1)                   % 处理左边界
    ngb(1:2,1:1) = [(x+1) 1]';
    ngb(1:2,2:2) = [x 2]';
    ngb(1:2,3:3) = [(x-1) 1]';
  elseif ((x == 1) & (y == cols))       % 处理右上角
    ngb(1:2,1:1) = [1 (cols-1)]';
    ngb(1:2,2:2) = [2 cols]';
  elseif ((x == rows) & (y == cols))    % 处理右下角
    ngb(1:2,1:1) = [rows (cols-1)]';
    ngb(1:2,2:2) = [(rows-1) cols]';
  elseif (y == cols)                 % 处理右边界
    ngb(1:2,1:1) = [(x+1) cols]';
    ngb(1:2,2:2) = [x (cols-1)]';
    ngb(1:2,3:3) = [(x-1) cols]';
  elseif (x == 1)                   % 处理上边界
    ngb(1:2,1:1) = [1 (y-1)]';
    ngb(1:2,2:2) = [2 y]';
    ngb(1:2,3:3) = [1 (y+1)]';
  elseif (x == rows)                % 处理下边界
    ngb(1:2,1:1) = [rows (y-1)]';
    ngb(1:2,2:2) = [(rows-1) y]';
    ngb(1:2,3:3) = [rows (y+1)]';
  else                          %其他
    ngb(1:2,1:1) = [(x-1) y]';
    ngb(1:2,2:2) = [x (y-1)]';
    ngb(1:2,3:3) = [(x+1) y]';
    ngb(1:2,4:4) = [x (y+1)]';
  end
分析

对比上述六幅图像,可以发现,在Connectivity相同时,随着criterion的增大,图像分割的效果逐渐增强,criterion=2时,基本没有将人与背景区分开,criterion=10/12两个附近时,能够达到比较理想的分割效果。

针对rice.jpg这幅图像,运用大津法进行分割,并自动统计大米的数量。请展示Matlab程序,和分割后的图像

数字图像处理实验04——图像分割
; 分割代码
rice =imread('rice.jpg');
level =graythresh(rice);
rice_d = imbinarize(rice ,level);
subplot(121),imshow(rice);title('rice原图像');
subplot(122),imshow(rice_d);title('大津法分割后图像');
分割&计数代码
rice=imread('rice.jpg');
rt=imopen(rice,strel('disk',10));
rice_t=imsubtract(rice,rt);
level=graythresh(rice_t);
rice_d=imbinarize(rice_t,level);
[labeled,num]=bwlabel(rice_d,4);
[m,n]=size(labeled);
A=zeros(num,1);
结果

数字图像处理实验04——图像分割
分割后统计出的大米数量为100

代码文件可以从主页发布里面找

万水千山都是情,路过点个赞行不行!
希望看见的都可以帮忙点个赞!拜托了!
觉得还可以的动动手指帮忙点个赞!呜呜~

Original: https://blog.csdn.net/weixin_52434230/article/details/123749132
Author: 能睡就睡
Title: 数字图像处理实验04——图像分割

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/645305/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球