基于Matlab的SLIC超像素分割算法分析
SLIC超像素分割算法分析
1:導(dǎo)入原始照片,初始化聚類中心,按照設(shè)定的超像素個數(shù),在圖像內(nèi)均勻的分配聚類中心。假設(shè)圖片總共有 N 個像素點,預(yù)分割為 s 個相同尺寸的超像素,那么每個超像素的大小為N/ s ,則相鄰種子點(聚類中心)的距離近似為S=sqrt(N/s)。
2:在種子點的n*n鄰域內(nèi)重新選擇聚類中心。計算該鄰域內(nèi)所有像素點的梯度值,將種子點移到該鄰域內(nèi)梯度最小的地方,可以避免種子點落在梯度較大的輪廓邊界上,以免影響后續(xù)聚類效果。
3:在每個種子點周圍的鄰域內(nèi)為每個像素點進行分類,和標準的k-means在整張圖中搜索不同,SLIC的期望的超像素尺寸為SS,但是搜索的范圍是2S*2S。
4:距離度量。包括顏色距離和空間距離。對于每個搜索到的像素點,分別計算它和該種子點的距離,本質(zhì)還是采用歐氏距離公式,計算方法如下:
其中,dc代表顏色距離,ds代表空間距離,Ns是類內(nèi)最大空間距離。最大的顏色距離Nc既隨圖片不同而不同,也隨聚類不同而不同,所以我們?nèi)∫粋€固定常數(shù)m(1<m<40),一般取10代替。最終的距離度量D’如下:
由于每個像素點都會被多個聚類中心搜索到并計算其距離,最后選取最小的距離值作為該像素點的聚類中心。
5:迭代優(yōu)化,一般達到迭代次數(shù)或者達到誤差收斂(即每個像素點聚類中心不再發(fā)生變化為止)。
6:增強連通性。經(jīng)過迭代優(yōu)化可能出現(xiàn)多連通情況、超像素尺寸過小,單個超像素被切割成多個不連續(xù)超像素等,這些情況可以通過進行增強連通性解決。
7:基于SLIC超像素分割完畢,顯示分割圖像。
運行軟件版本:MATLAB2014a(大于此版本即可)
運行方法:點擊main.m文件,然后選擇自己要超像素分割的照片即可。
MATLAB代碼如下:
main.m文件
%選擇要進行超像素分割圖像的路徑
close all;clc;
[filename, pathname, filterindex] = uigetfile(‘C:\Users\Hasee\Desktop\畢業(yè)設(shè)計\測試圖庫.jpg’, ‘選擇圖片’);
file = fullfile(pathname, filename);
%設(shè)置讀取的照片為全局變量
global I;
%讀取要選擇的照片
I= imread(file);
figure,imshow(I);
title(‘原始圖片’)
%利用SLIC函數(shù)處理待分割圖像:
%超像素尺寸s=15,errTh為控制迭代結(jié)束的聯(lián)合向量殘差上限為10-2即0.01,控制色域與空域權(quán)重比例的系數(shù)wDs為0.52即0.25
s=15;
errTh=10^-2;
wDs=0.5^2;
Label=SLIC(I,s,errTh,wDs);
%% 顯示輪廓
%矩陣初始化為矩陣
marker=zeros(size(Label));
%記錄大小為m*n
[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 ~(topbottom && bottomleft && left==right)
marker(i,j)=1;
end
end
end
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);
title(‘分割結(jié)果’)
SLIC.m文件
function Label=SLIC(img,s,errTh,wDs)
% 基于KMeans的超像素分割
% img為輸入圖像,維度不限,最大值為255
% s x s為超像素尺寸
% errTh為控制迭代結(jié)束的聯(lián)合向量殘差上限
m=size(img,1);
n=size(img,2);
%% 計算柵格頂點與中心的坐標
%圖像長度與超像素尺寸比值向下取整
h=floor(m/s);
%圖像寬度與超像素尺寸比值向下取整
w=floor(n/s);
rowR=floor((m-hs)/2); %多余部分首尾均分
colR=floor((n-ws)/2);
rowStart=(rowR+1)😒:(m-s+1);
rowStart(1)=1;
rowEnd=rowStart+s;
rowEnd(1)=rowR+s;
rowEnd(end)=m;
colStart=(colR+1)😒:(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);
% 顯示劃分柵格結(jié)果
%先初始化temp為m*n的零矩陣
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);
title(‘柵格劃分結(jié)果’)
%保存柵格劃分結(jié)果為柵格.jpg文件
imwrite(temp,‘柵格.jpg’);
%% 利用sobel算子和歐式距離計算梯度圖像
img=double(img)/255;
%分別提取圖像的三通道信息
r=img(:,:,1);
g=img(:,:,2);
b=img(:,:,3);
%采用加權(quán)法進行灰度化處理,權(quán)值分別為0.299 , 0.587,0.114
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);
%% 選擇柵格中心點33鄰域中梯度最小點作為起始點
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=Infones(m,n);
M=reshape(img,mn,size(img,3)); %像素值重排
% 聯(lián)合色域值和空域值
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,hw,size(img,3)+2);
iter=1;
while(1)
uniMat_old=uniMat;
% rowC_old=rowC;
% colC_old=colC;
for k=1:hw
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=dc2+wDs*(ds/s)2;
if d<dis(i,j)
dis(i,j)=d;
Label(i,j)=k;
end
end
end
end
end
%% 按照邊界接觸點數(shù)最多原則分配小連通域的標簽
for k=1:hw
c=floor((k-1)/h)+1;
r=k-h(c-1);
rowCidx=rowC_std(r,c);
colCidx=colC_std(r,c);
rowStart=max(1,rowCidx-s);
rowEnd=min(m,rowCidx+s-1);
colStart=max(1,colCidx-s);
colEnd=min(n,colCidx+s);
block=Label(rowStart:rowEnd,colStart:colEnd);
block(block~=k)=0;
block(block==k)=1;
label=bwlabel(block);
%標簽個數(shù)最大值
szlabel=max(label(😃);
%block的高高
bh=rowEnd-rowStart+1;
%block的寬高
bw=colEnd-colStart+1;
end
% 顯示連通域處理后聚類結(jié)果
temp=mod(Label,20)+1;
figure;
imagesc(label2rgb(temp-1,‘jet’,‘w’,‘shuffle’)) ;
title(‘連通域處理后的聚類結(jié)果’)
axis image ; axis off ;
原始圖像:
柵格劃分結(jié)果:
聚類結(jié)果:
連通域處理后的聚類結(jié)果:
超像素分割結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的基于Matlab的SLIC超像素分割算法分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言入门篇:程序调试方法
- 下一篇: 电脑实用技术