matlab練習程序(meanshift圖像聚類)


  關於這個meanshift,一來可以用來作為目標跟蹤,二來可以用來進行圖像聚類。我這里只實現了圖像聚類,當然,是按自己的理解編寫的程序。至於目標跟蹤將來一定也是要實現的,因為我最初看這個算法的原因就是想用他來跟蹤目標的。

  meanshift的基本原理我就不介紹了,比起我的介紹,網上有不少牛人們比我解釋的好,最后我會列出我參考的文章。我這里說一下我是怎么理解meanshift圖像聚類的。這里的聚類也像過去的濾波一樣,需要一個模板矩陣,不過這個模板不是事先設置好的矩陣,而是在當前處理的像素周圍提取一個r*r的矩陣,然后把這個矩陣化為一維向量,再對這個向量進行meanshift,最終迭代到的值再賦值給當前處理的像素。所以可以這樣理解,把圖像經過meanshift迭代到相同值的像素聚為一類。

  我這里使用的是灰度圖像,至於彩色圖像,我看到一篇博客上把rgb域轉換到luv域上再去做處理,這個我就不太清楚了,不過我看他的代碼其中有一部分很像均值濾波。雖然我沒有和他用一樣的方法,不過他的代碼也可以參考一下。傳送門在此

  下面是代碼(這都是我自己的理解,不能保證都正確,不過至少可以為你的編碼提供一些思路):

main.m

clear all;
close all;
clc;

r=2;        %濾波半徑
img=imread('lena.jpg');
imshow(img);
img=double(img);
[m n]=size(img);

imgn=zeros(m+2*r+1,n+2*r+1);

imgn(r+1:m+r,r+1:n+r)=img;
imgn(1:r,r+1:n+r)=img(1:r,1:n); 
imgn(1:m+r,n+r+1:n+2*r+1)=imgn(1:m+r,n:n+r);
imgn(m+r+1:m+2*r+1,r+1:n+2*r+1)=imgn(m:m+r,r+1:n+2*r+1);
imgn(1:m+2*r+1,1:r)=imgn(1:m+2*r+1,r+1:2*r);
imshow(mat2gray(imgn))

for i=1+r:m+r
    for j=1+r:n+r
        ser=imgn(i-r:i+r,j-r:j+r);
        ser=reshape(ser,[1 (2*r+1)^2]);         %將二維模板變為一維
        imgn(i,j)=mean_shift(ser,2*r^2+2*r+1);   %取模板最中間的那個值作為迭代初值
    
    end    
end

figure;
imgn=imgn(r+1:m+r,r+1:n+r);
imshow(mat2gray(imgn));

meanshift.m

function   re= mean_shift( ser,p)
    [m n]=size(ser);
    tmp=double(ser);

    pre_w=tmp(p);
    point=p;
    while 1
        ser=tmp-pre_w;

        for i=1:m*n
            if i ~= point
                ser(i)=ser(i)/(i-point);            %i-point是距離,就是各種公式里的h
            end
        end

        ser=ser.^2;
        K=(1/sqrt(2*pi))*exp(-0.5*ser);         %傳說中的核函數
        w=sum(tmp.*(K))/sum(K);

        if abs(w-pre_w)<0.01
            break;
        end
        pre_w=w; 
    end
 %   tmp1=abs(tmp-w);
 %   [i point]=min(tmp1);
    re=w;
 %   if max(tmp)-w<0.01
 %       point=0;
 %   end
 %   point=w;
end

處理的效果:

原圖

半徑為2處理的效果

——————————下面是2013.5.30添加————————————

上一部分的meanshift圖像聚類還需修改,下面實現最簡單的meanshift算法,完全按照原理來。

最后的參考文獻都是很好的總結,不過這次我是參考的《圖像處理、分析與機器視覺(第3版)》這本書。

下面是通常所見的迭代效果:

程序如下:

clear all; close all; clc;

%測試數據
mu=[0 0];  %均值
S=[30 0;0 35];  %協方差
data=mvnrnd(mu,S,300);   %產生300個高斯分布數據
plot(data(:,1),data(:,2),'o');

h=3;    %核的大小
x=[data(1,1) data(1,2)];    %以第一個數據為迭代初值
pre_x=[0 0];

hold on
while norm(pre_x-x)>0.01;
    
    pre_x=x;
    plot(x(1),x(2),'r+');
    u=0;        %分子累加項
    d=0;        %分母累加項
    for i=1:300
        %最關鍵的兩步,均值位移公式實現
        k=norm((x-data(i,:))/h).^2;        
        g=(1/sqrt(2*pi))*exp(-0.5*k);
        
        u=data(i,:)*g+u;
        d=g+d;
    end
    M=u/d;      %迭代后的坐標位置
    x=M;
 
end

 

參考:

1.http://en.wikipedia.org/wiki/Mean-shift wiki百科,介紹的簡介明了。

2.http://www.cnblogs.com/liqizhou/archive/2012/05/12/2497220.html 非常詳細的理解。

3.http://emuch.net/bbs/viewthread.php?tid=4626864 小木蟲上一個同學的理解。

4.http://en.wikipedia.org/wiki/Kernel_(statistics) 介紹核函數的。

5.http://wenku.baidu.com/view/11b6a7de6f1aff00bed51eac.html 提出meanshift算法的論文,雖然我沒怎么看,不過想對算法徹底理解的還是看這篇好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM