• MATLAB meanshift图像聚类


      关于这个meanshift,一来可以用来作为目标跟踪,二来可以用来进行图像聚类。我这里只实现了图像聚类,当然,是按自己的理解编写的程序。至于目标跟踪将来一定也是要实现的,因为我最初看这个算法的原因就是想用他来跟踪目标的。

      meanshift的基本原理我就不介绍了,比起我的介绍,网上有不少牛人们比我解释的好,最后我会列出我参考的文章。我这里说一下我是怎么理解meanshift图像聚类的。这里的聚类也像过去的滤波一样,需要一个模板矩阵,不过这个模板不是事先设置好的矩阵,而是在当前处理的像素周围提取一个r*r的矩阵,然后把这个矩阵化为一维向量,再对这个向量进行meanshift,最终迭代到的值再赋值给当前处理的像素。所以可以这样理解,把图像经过meanshift迭代到相同值的像素聚为一类。

      我这里使用的是灰度图像,至于彩色图像,我看到一篇博客上把rgb域转换到luv域上再去做处理,这个我就不太清楚了,不过我看他的代码其中有一部分很像均值滤波。虽然我没有和他用一样的方法,不过他的代码也可以参考一下。

      下面是代码(这都是我自己的理解,不能保证都正确,不过至少可以为你的编码提供一些思路):

    main.m

     1 clear all;
     2 close all;
     3 clc;
     4 
     5 r=2;        %滤波半径
     6 img=imread('lena.jpg');
     7 imshow(img);
     8 img=double(img);
     9 [m n]=size(img);
    10 
    11 imgn=zeros(m+2*r+1,n+2*r+1);
    12 
    13 imgn(r+1:m+r,r+1:n+r)=img;
    14 imgn(1:r,r+1:n+r)=img(1:r,1:n); 
    15 imgn(1:m+r,n+r+1:n+2*r+1)=imgn(1:m+r,n:n+r);
    16 imgn(m+r+1:m+2*r+1,r+1:n+2*r+1)=imgn(m:m+r,r+1:n+2*r+1);
    17 imgn(1:m+2*r+1,1:r)=imgn(1:m+2*r+1,r+1:2*r);
    18 imshow(mat2gray(imgn))
    19 
    20 for i=1+r:m+r
    21     for j=1+r:n+r
    22         ser=imgn(i-r:i+r,j-r:j+r);
    23         ser=reshape(ser,[1 (2*r+1)^2]);         %将二维模板变为一维
    24         imgn(i,j)=mean_shift(ser,2*r^2+2*r+1);   %取模板最中间的那个值作为迭代初值
    25     
    26     end    
    27 end
    28 
    29 figure;
    30 imgn=imgn(r+1:m+r,r+1:n+r);
    31 imshow(mat2gray(imgn));

    meanshift.m

     1 function   re= mean_shift( ser,p)
     2     [m n]=size(ser);
     3     tmp=double(ser);
     4 
     5     pre_w=tmp(p);
     6     point=p;
     7     while 1
     8         ser=tmp-pre_w;
     9 
    10         for i=1:m*n
    11             if i ~= point
    12                 ser(i)=ser(i)/(i-point);            %i-point是距离,就是各种公式里的h
    13             end
    14         end
    15 
    16         ser=ser.^2;
    17         K=(1/sqrt(2*pi))*exp(-0.5*ser);         %传说中的核函数
    18         w=sum(tmp.*(K))/sum(K);
    19 
    20         if abs(w-pre_w)<0.01
    21             break;
    22         end
    23         pre_w=w; 
    24     end
    25  %   tmp1=abs(tmp-w);
    26  %   [i point]=min(tmp1);
    27     re=w;
    28  %   if max(tmp)-w<0.01
    29  %       point=0;
    30  %   end
    31  %   point=w;
    32 end

    处理的效果:

    原图

    半径为2处理的效果

    ——————————下面是后续添加————————————

    上一部分的meanshift图像聚类还需修改,下面实现最简单的meanshift算法,完全按照原理来。

    最后的参考文献都是很好的总结,不过这次我是参考的《图像处理、分析与机器视觉(第3版)》这本书。

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

    程序如下:

     1 clear all; close all; clc;
     2 
     3 %测试数据
     4 mu=[0 0];  %均值
     5 S=[30 0;0 35];  %协方差
     6 data=mvnrnd(mu,S,300);   %产生300个高斯分布数据
     7 plot(data(:,1),data(:,2),'o');
     8 
     9 h=3;    %核的大小
    10 x=[data(1,1) data(1,2)];    %以第一个数据为迭代初值
    11 pre_x=[0 0];
    12 
    13 hold on
    14 while norm(pre_x-x)>0.01;
    15     
    16     pre_x=x;
    17     plot(x(1),x(2),'r+');
    18     u=0;        %分子累加项
    19     d=0;        %分母累加项
    20     for i=1:300
    21         %最关键的两步,均值位移公式实现
    22         k=norm((x-data(i,:))/h).^2;        
    23         g=(1/sqrt(2*pi))*exp(-0.5*k);
    24         
    25         u=data(i,:)*g+u;
    26         d=g+d;
    27     end
    28     M=u/d;      %迭代后的坐标位置
    29     x=M;
    30  
    31 end
  • 相关阅读:
    最短路径之spfa
    最短路径之Bellman-Ford——解决负权边
    最短路径之Floyd-Warshall算法
    图上最短路径问题
    它们其实都是图(二分图)
    记忆化结果再利用 进一步探讨递推关系
    leetcode 376. 摆动序列 java
    leetcode 368. 最大整除子集 java
    leetcode 96. 不同的二叉搜索树 java
    leetcode 454. 四数相加 II java
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13646102.html
Copyright © 2020-2023  润新知