meanshift的基本原理这里就不介绍了,详情可参考我的博客。

 

       meanshift图像聚类的。这里的聚类也像过去的滤波一样,需要一个矩阵模板,不过这个模板就是当前处理的像素周围提取一个r*r的矩阵,然后把这个矩阵化为一维向量,再对这个向量进行meanshift,最终迭代到的值再赋值给当前处理的像素。所以可以这样理解,把图像经过meanshift迭代到相同值的像素聚为一类。(这段理解出自)实现代码方法可参见该博主的博客。


        这里说一下我对该博主代码的理解,不对的话,欢迎大家在评论区批评指正。

把这个矩阵化为一维向量,再对这个向量进行meanshift”???

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

 从mean_shift函数中的循环内:

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

    ser(i)代表中心像素与邻域像素的灰度差,ser(i)/(i-point)是为了根据邻域点到中心点的距离,设置不同的权重。比如一个5*5的邻域应该用ser(i)除以对应的(距离中心点的距离),而不应该简单的用(i-point)作为邻域点到中心点的距离吧。

    权重矩阵应该定义为:

                                               

均值漂移聚类算法python实现 均值漂移聚类matlab_权重

下面放上我修改后的代码。(那位博主的代码也能实现均值飘移,且效果良好。而我的这个版本,就处理效果而言,都差不多)

main.m:

clear all;
close all;
clc;

r=2;        %滤波半径
k=2;        %权重矩阵的指数,k越大,最终图像的飘移程度越高
img=imread('lena.jpg');      %灰度图像
weight=matrix_weight(r,k);   %求权重矩阵
weight=reshape(weight,[1 (2*r+1)^2]);
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);


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));

matrix_weight.m:

function weight=matrix_weight(r,k)
%k:对距离进行k次幂计算作为最终的权值
weight=zeros(2*r+1,2*r+1);
for i=1:2*r+1
for j=
weight(i,j)=(norm([i,j]-[r+1,j+1]))^k;
end
end
end