超像素分割算法SLIC的matlab实现

超像素分割算法SLIC的matlab实现SLIC 是一种基于网格化 KMeans 聚类的超像素分割算法 其计算复杂度为 O N 其中 N 为像素点个数 SLIC 的原理比较简单精致 具体的原理我这里就不介绍了 推荐大家自己去读原始论文加深理解 SLIC 的算法流程如下 如所有其他聚类算法一样 SLIC 不能保证连通性 所以需要后处理将旁生的连通域合并到邻近的主连通域上 但是论文中并未给出具体的后处理方法 我给出的方法是按照轮廓接触点个数最多原则合并连通域 由于每个聚类都有自己的 势力范围 即每个标签覆盖的区域不会超过聚类时限定的范围 一般是 2S 2S 大

SLIC是一种基于网格化KMeans聚类的超像素分割算法,其计算复杂度为O(N),其中N为像素点个数。SLIC的原理比较简单精致,具体的原理我这里就不介绍了,推荐大家自己去读原始论文加深理解(但我以为看下面这个算法流程图就足够理解原理了)。SLIC的算法流程如下:

超像素分割算法SLIC的matlab实现

如所有其他聚类算法一样,SLIC不能保证连通性,所以需要后处理将旁生的连通域合并到邻近的主连通域上,但是论文中并未给出具体的后处理方法。我给出的方法是按照轮廓接触点个数最多原则合并连通域。由于每个聚类都有自己的“势力范围”,即每个标签覆盖的区域不会超过聚类时限定的范围(一般是2S*2S大小,边缘栅格的聚类例外),所以合并处理时只需要在该范围内操作即可。

 下面给出本人实现的SLIC算法程序(控制色域与空域权重比例的系数wDs应设为函数形参,这里就不改了。注意!迭代中限定聚类的栅格是不变的!!!):

function Label=SLIC(img,s,errTh,wDs) % 基于KMeans的超像素分割 % img为输入图像,维度不限,最大值为255 % s x s为超像素尺寸 % errTh为控制迭代结束的联合向量残差上限 m=size(img,1); n=size(img,2); %% 计算栅格顶点与中心的坐标 h=floor(m/s); w=floor(n/s); rowR=floor((m-h*s)/2); %多余部分首尾均分 colR=floor((n-w*s)/2); rowStart=(rowR+1):s:(m-s+1); rowStart(1)=1; rowEnd=rowStart+s; rowEnd(1)=rowR+s; rowEnd(end)=m; colStart=(colR+1):s:(n-s+1); colStart(1)=1; colEnd=colStart+s; colEnd(1)=colR+s; colEnd(end)=n; rowC=floor((rowStart+rowEnd-1)/2); colC=floor((colStart+colEnd-1)/2); % 显示划分结果 temp=zeros(m,n); temp(rowStart,:)=1; temp(:,colStart)=1; for i=1:h for j=1:w temp(rowC(i),colC(j))=1; end end figure,imshow(temp); imwrite(temp,'栅格.bmp'); %% 计算梯度图像,使用sobel算子和欧式距离 img=double(img)/255; r=img(:,:,1); g=img(:,:,2); b=img(:,:,3); Y=0.299 * r + 0.587 * g + 0.114 * b; f1=fspecial('sobel'); f2=f1'; gx=imfilter(Y,f1); gy=imfilter(Y,f2); G=sqrt(gx.^2+gy.^2); %% 选择栅格中心点3*3邻域中梯度最小点作为起始点 rowC_std=repmat(rowC',[1,w]); colC_std=repmat(colC,[h,1]); rowC=rowC_std; colC=colC_std; for i=1:h for j=1:w block=G(rowC(i,j)-1:rowC(i,j)+1,colC(i,j)-1:colC(i,j)+1); [minVal,idxArr]=min(block(:)); jOffset=floor((idxArr(1)+2)/3); iOffset=idxArr(1)-3*(jOffset-1); rowC(i,j)=rowC(i,j)+iOffset; colC(i,j)=colC(i,j)+jOffset; end end %% KMeans超像素分割 Label=zeros(m,n)-1; dis=Inf*ones(m,n); M=reshape(img,m*n,size(img,3)); %像素值重排 % 联合色域值和空域值 colorC=zeros(h,w,size(img,3)); for i=1:h for j=1:w colorC(i,j,:)=img(rowC(i),colC(j),:); end end uniMat=cat(3,colorC,rowC,colC); uniMat=reshape(uniMat,h*w,size(img,3)+2); iter=1; while(1) uniMat_old=uniMat; % rowC_old=rowC; % colC_old=colC; for k=1:h*w c=floor((k-1)/h)+1; r=k-h*(c-1); rowCidx=rowC(r,c); colCidx=colC(r,c); %聚类中心坐标 %聚类限定的栅格(中心点始终是原s x s栅格的中心点) rowStart=max(1,rowC_std(r,c)-s); rowEnd=min(m,rowC_std(r,c)+s-1); colStart=max(1,colC_std(r,c)-s); colEnd=min(n,colC_std(r,c)+s); % colorC=uniMat(k,1:size(img,3)); colorC=M((colCidx-1)*m+rowCidx,:); for i=rowStart:rowEnd for j=colStart:colEnd colorCur=M((j-1)*m+i,:); dc=norm(colorC-colorCur); ds=norm([i-rowCidx,j-colCidx]); d=dc^2+wDs*(ds/s)^2; if d 
  
    =1 && row<=m && col>=1 && col<=n && Label(row,col)~=k) continue; end if marker(row-top+1,col-left+1)==0 %未被统计过 marker(row-top+1,col-left+1)=1; num=num+1; labelArr(num)=Label(row,col); end end end labelArr(find(labelArr==0))=[]; %去除零元素 uniqueLabel=unique(labelArr); numArr=zeros(length(uniqueLabel),1); for p=1:length(uniqueLabel) idx=find(labelArr==uniqueLabel(p)); numArr(p)=length(idx); end idx=find(numArr==max(numArr)); maxnumLabel=uniqueLabel(idx(1)); %接触最多的标签 for row=rowStart:rowEnd for col=colStart:colEnd if bw(row-rowStart+1,col-colStart+1)==0 continue; end Label(row,col)=maxnumLabel; end end end end % 显示连通域处理后聚类结果 temp=mod(Label,20)+1; figure; imagesc(label2rgb(temp-1,'jet','w','shuffle')) ; axis image ; axis off ; 
  

脚本文件:

close all;clc; I=imread('1.jpg'); figure,imshow(I); s=15; errTh=10^-2; wDs=0.5^2; Label=SLIC(I,s,errTh,wDs); %% 显示轮廓 marker=zeros(size(Label)); [m,n]=size(Label); for i=1:m for j=1:n top=Label(max(1,i-1),j); bottom=Label(min(m,i+1),j); left=Label(i,max(1,j-1)); right=Label(i,min(n,j+1)); if ~(top==bottom && bottom==left && left==right) marker(i,j)=1; end end end figure,imshow(marker); I2=I; for i=1:m for j=1:n if marker(i,j)==1 I2(i,j,:)=0; end end end figure,imshow(I2);

测试图像:

超像素分割算法SLIC的matlab实现

栅格划分结果:

超像素分割算法SLIC的matlab实现

聚类过程:

超像素分割算法SLIC的matlab实现

 聚类最终结果:

超像素分割算法SLIC的matlab实现

连通域合并后的结果:

超像素分割算法SLIC的matlab实现

原图+轮廓线:

超像素分割算法SLIC的matlab实现

 

具体的我就不解释了,自觉程序写得还是很有条理的,读者自己跟踪程序运行进行理解吧。 

 

 

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223869.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午1:15
下一篇 2026年3月17日 下午1:15


相关推荐

  • Java代码接入讯飞星火

    Java代码接入讯飞星火

    2026年3月14日
    2
  • C6000系列DSP的中断系统

    C6000系列DSP的中断系统C6000系列DSP的中断系统上一篇介绍了C6455的GPIO系统,最后把GPIO4配置成了中断/事件模式,本文将介绍C6455的中断系统,介绍完基本概念后,给出把GPIO4映射到INT4的代码。完成了GPIO和中断的配置,我们就可以开始着手DSP与FPGA之间的通讯了。废话不多说,下面开始介绍C6455的中断系统。————————-

    2022年6月15日
    29
  • element修改table_csstablecell支持

    element修改table_csstablecell支持ElementUI-table-td添加省略号提示:这里简述项目相关背景:解决方案:<div> <table> <tdsrtle=”overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block”></td> </table></div>…

    2025年9月24日
    7
  • Java socket详解,看这一篇就够了

    Java socket详解,看这一篇就够了刚给大家讲解 Javasocket 通信后 好多童鞋私信我 有好多地方不理解 看不明白 特抽时间整理一下 详细讲述 Javasocket 通信原理和实现案例 整个过程楼主都是通过先简单明了的示例让大家了解整个基本原理 后慢慢接近生产实用示例 先概况后脉络给大家梳理出来的 所有涉及示例都可以直接拷贝运行 楼主才疏学浅 如有部分原理错误请大家及时指正 整理和总结了一下大家常遇到的问题 1 客户端 socket 发送消息后 为什么服务端 socket 没有收到

    2026年3月18日
    2
  • 豆包大模型定制小众旅行路线攻略

    豆包大模型定制小众旅行路线攻略

    2026年3月16日
    3
  • 工作流优化新方案

    工作流优化新方案

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号