精华内容
下载资源
问答
  • 超像素分割算法

    2016-10-31 21:16:04
    超像素分割算法
  • 超像素分割算法,亲测可用,内含数据图片,不用mex,直接matlab运行
  • 超像素能够捕获图像冗余信息,降低后续处理任务复杂度,已受到了国内外研究者的...在此基础上,就目前常用的超像素分割算法进行了实验对比,分析各自的优势和不足。最后, 对超像素分割技术的最新应用进行了介绍和展望
  • 超像素能够捕获图像冗余信息,降低后续处理任务复杂度,已受到了国内外研究者的...在此基础上,就目前常用的超像素分割算法进行了实验对比,分析各自的优势和不足。最后,对超像素分割技术的最新应用进行了介绍和展望。
  • SNIC超像素分割算法

    2019-10-11 21:50:52
    超像素分割为图像分割,图像处理的基础,文件为MATLAB和C混编的代码,demo为主程序,运行demo主程序进行超像素分割
  • SLIC超像素分割算法的C++代码,代码来源于该算法创始人Radhakrishna Achanta网站,这里我们给出了对应的OpenCV Mat接口,代码在VS2012和OpenCV2.4.9版本下测试验证可行,其中附上SLIC的相关说明。
  • 超像素分割算法SLIC的matlab实现

    千次阅读 多人点赞 2020-08-20 16:59:05
    SLIC是一种基于网格化KMeans聚类的超像素分割算法,其计算复杂度为O(N),其中N为像素点个数。SLIC的原理比较简单精致,具体的原理我这里就不介绍了,推荐大家自己去读原始论文加深理解。SLIC的算法流程如下: 如...

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

    如所有其他聚类算法一样,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<dis(i,j)
                        dis(i,j)=d;
                        Label(i,j)=k;
                    end
                end
            end
        end
        
        %显示聚类结果
        temp=mod(Label,20)+1;
        figure;
        imagesc(label2rgb(temp-1,'jet','w','shuffle')) ;
        axis image ; axis off ;
            % 录制gif
        F=getframe(gcf);
        I=frame2im(F);
        [I,map]=rgb2ind(I,256);
        if iter == 1
            imwrite(I,map,'test.gif','gif','Loopcount',inf,'DelayTime',0.2);
        else
            imwrite(I,map,'test.gif','gif','WriteMode','append','DelayTime',0.2);
        end
        iter=iter+1;
        
        % 更新聚类中心
        colorC=zeros(h,w,size(img,3));
        for k=1:h*w
            num=0;
            sumColor=zeros(1,size(img,3));    
            sumR=0;
            sumC=0;
            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);
            
            for row=rowStart:rowEnd
                for col=colStart:colEnd
                    if Label(row,col)==k
                        num=num+1;
                        sumR=sumR+row;
                        sumC=sumC+col;
                        color=reshape(img(row,col,:),1,size(img,3));
                        sumColor=sumColor+color;
                    end
                end
            end
            colorC(r,c,:)=sumColor/num;
            rowC(r,c)=round(sumR/num);
            colC(r,c)=round(sumC/num);
        end
        uniMat=cat(3,colorC,rowC,colC);
        uniMat=reshape(uniMat,h*w,size(img,3)+2);
        diff=uniMat-uniMat_old;
        diff(:,1:2)=sqrt(wDs)*diff(:,1:2)/s;
        err=norm(diff)/sqrt(h*w);
        if err<errTh %残差低于阈值,结束迭代
            break;
        end
    end
    
    %% 后处理, 按照边界接触点数最多原则分配小连通域的标签
    for k=1:h*w
        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);
        szlabel=max(label(:)); %标签个数
        bh=rowEnd-rowStart+1;
        bw=colEnd-colStart+1;  %block的宽高
        
        if szlabel<2  %无伴生连通域,略过
            continue;
        end
        
        labelC=label(rowCidx-rowStart+1,colCidx-colStart+1); %主连通域的标记值
        top=max(1,rowStart-1);
        bottom=min(m,rowEnd+1);
        left=max(1,colStart-1);
        right=min(n,colEnd+1);
        for i=1:szlabel %遍历连通域
            if i==labelC %主连通域不处理
                continue;
            end
            marker=zeros(bottom-top+1,right-left+1); %生成一个外扩一圈的marker,标记哪些点已经被统计过接触情况
            bw=label;
            bw(bw~=i)=0;
            bw(bw==i)=1; %当前连通域标记图
            contourBW=bwperim(bw); %求取外轮廓
            %             figure,imshow(contourBW);
            idxArr=find(double(contourBW)==1);
            labelArr=zeros(4*length(idxArr),1);  %记录轮廓点的4邻域点标记值的向量
            num=0;
            for idx=1:size(idxArr) %遍历轮廓点,统计其4邻域点的标记值
                bc=floor((idxArr(idx)-1)/bh)+1;
                br=idxArr(idx)-bh*(bc-1); %轮廓点在block中的行列信息
                row=br+rowStart-1;
                col=bc+colStart-1; %轮廓点在大图中的行列信息
                rc=[row-1,col;...
                    row+1,col;...
                    row,col-1;...
                    row,col+1];
                for p=1:4
                    row=rc(p,1);
                    col=rc(p,2);
                    
                    if ~(row>=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这一算法超像素分割这类low-level vision问题已经在CVPR,ICCV这种顶级会议上逐渐销声匿迹,越来越流行的learning method渐渐占据了这些顶级会议90%的...

    简介:最近项目使用到了超像素分割,因此顺道研究了以下SLIC这一算法。超像素分割这类low-level vision问题已经在CVPR,ICCV这种顶级会议上逐渐销声匿迹,越来越流行的learning method渐渐占据了这些顶级会议90%的篇幅。本文讲解的SLIC是2010年提出的一种十分简单的超分辨分割算法,原理简单、便于实现。

    在这里插入图片描述在这里插入图片描述

    一.SLIC(simple linear iterative clustering)原理分析

    1. 初始化种子点(聚类中心):按照设定的超像素个数,在图像内均匀的分配种子点。假设图片总共有 N 个像素点,预分割为 K 个相同尺寸的超像素,那么每个超像素的大小为N/ K ,则相邻种子点的距离(步长)近似为S=sqrt(N/K)。

    2. 在种子点的n*n邻域内重新选择种子点(一般取n=3)。具体方法为:计算该邻域内所有像素点的梯度值,将种子点移到该邻域内梯度最小的地方。这样做的目的是为了避免种子点落在梯度较大的轮廓边界上,以免影响后续聚类效果。

    3. 在每个种子点周围的邻域内为每个像素点分配类标签(即属于哪个聚类中心)。和标准的k-means在整张图中搜索不同,SLIC的搜索范围限制为2S2S,可以加速算法收敛,如下图。在此注意一点:期望的超像素尺寸为SS,但是搜索的范围是2S*2S。
      在这里插入图片描述

    4. 距离度量。包括颜色距离和空间距离。对于每个搜索到的像素点,分别计算它和该种子点的距离。距离计算方法如下:

    在这里插入图片描述
    其中,dc代表颜色距离,ds代表空间距离,Ns是类内最大空间距离,定义为Ns=S=sqrt(N/K),适用于每个聚类。最大的颜色距离Nc既随图片不同而不同,也随聚类不同而不同,所以我们取一个固定常数m(取值范围[1,40],一般取10)代替。最终的距离度量D’如下:

    在这里插入图片描述

    由于每个像素点都会被多个种子点搜索到,所以每个像素点都会有一个与周围种子点的距离,取最小值对应的种子点作为该像素点的聚类中心。

    1. 迭代优化。理论上上述步骤不断迭代直到误差收敛(可以理解为每个像素点聚类中心不再发生变化为止),实践发现10次迭代对绝大部分图片都可以得到较理想效果,所以一般迭代次数取10。

    2. 增强连通性。经过上述迭代优化可能出现以下瑕疵:出现多连通情况、超像素尺寸过小,单个超像素被切割成多个不连续超像素等,这些情况可以通过增强连通性解决。主要思路是:新建一张标记表,表内元素均为-1,按照“Z”型走向(从左到右,从上到下顺序)将不连续的超像素、尺寸过小超像素重新分配给邻近的超像素,遍历过的像素点分配给相应的标签,直到所有点遍历完毕为止。

    二.伪算法描述

    /∗ Initialization ∗/
    Initialize cluster centers Ck = [lk , ak , bk , xk , yk ]T by sampling pixels at regular grid steps S.
    Move cluster centers to the lowest gradient position in a 3 × 3 neighborhood.
    Set label l(i) =1 for each pixel i. Set distance d(i) =for each pixel i.
     
    repeat
    /∗ Assignment ∗/
    for each cluster center Ck do
        for each pixel i in a 2S × 2S region around Ck do 
            Compute the distance D between Ck and i.
            if D < d(i) then
                set d(i) = D
                set l(i) = k 
            end if
        end for 
    end for
     
    /∗ Update ∗/
    Compute new cluster centers. Compute residual error E.
    until E ≤ threshold
    

    三.参考博文

    1.https://github.com/laixintao/slic-python-implementation
    2.https://blog.csdn.net/zhj_matlab/article/details/52986700
    3.https://blog.csdn.net/electech6/article/details/45509779

    展开全文
  • SLIC超像素分割算法

    万次阅读 多人点赞 2017-09-22 18:17:13
    超像素概念是2003年Xiaofeng Ren提出和发展起来的图像分割技术,是指具有相似纹理、颜色、亮度等特征的相邻像素构成的有一定视觉意义的不规则像素块。它利用像素之间特征的相似性将像素分组...几种常见的超像素分割方法

    超像素概念是2003年Xiaofeng Ren提出和发展起来的图像分割技术,是指具有相似纹理、颜色、亮度等特征的相邻像素构成的有一定视觉意义的不规则像素块。它利用像素之间特征的相似性将像素分组,用少量的超像素代替大量的像素来表达图片特征,很大程度上降低了图像后处理的复杂度,所以通常作为分割算法的预处理步骤。已经广泛用于图像分割、姿势估计、目标跟踪、目标识别等计算机视觉应用。几种常见的超像素分割方法及其效果对比如下:


       Graph-based           NCut            Turbopixel          Quick-shift        Graph-cut a        Graph-cut b         SLIC

    这里主要介绍的是SLIC(simple linear iterativeclustering),即简单的线性迭代聚类。它是2010年提出的一种思想简单、实现方便的算法,将彩色图像转化为CIELAB颜色空间和XY坐标下的5维特征向量,然后对5维特征向量构造距离度量标准,对图像像素进行局部聚类的过程。SLIC算法能生成紧凑、近似均匀的超像素,在运算速度,物体轮廓保持、超像素形状方面具有较高的综合评价,比较符合人们期望的分割效果。

    SLIC主要优点总结如下:1)生成的超像素如同细胞一般紧凑整齐,邻域特征比较容易表达。这样基于像素的方法可以比较容易的改造为基于超像素的方法。2)不仅可以分割彩色图,也可以兼容分割灰度图。3)需要设置的参数非常少,默认情况下只需要设置一个预分割的超像素的数量。4)相比其他的超像素分割方法,SLIC在运行速度、生成超像素的紧凑度、轮廓保持方面都比较理想。

    在介绍SLIC之前,插播一下Lab颜色空间的介绍。Lab色彩模型是由亮度(L)和有关色彩的a, b三个要素组成。L表示亮度(Luminosity),L的值域由0(黑色)到100(白色)。a表示从洋红色至绿色的范围(a为负值指示绿色而正值指示品红),b表示从黄色至蓝色的范围(b为负值指示蓝色而正值指示黄色)。Lab颜色空间的优点:1)不像RGBCMYK色彩空间,Lab 颜色被设计来接近人类生理视觉。它致力于感知均匀性,它的 L 分量密切匹配人类亮度感知。因此可以被用来通过修改 a 和 b 分量的输出色阶来做精确的颜色平衡,或使用 L 分量来调整亮度对比。这些变换在 RGB 或 CMYK 中是困难或不可能的。2)因为 Lab 描述的是颜色的显示方式,而不是设备(如显示器、打印机或数码相机)生成颜色所需的特定色料的数量,所以 Lab 被视为与设备无关的颜色模型。3)色域宽阔。它不仅包含了RGB,CMYK的所有色域,还能表现它们不能表现的色彩。人的肉眼能感知的色彩,都能通过Lab模型表现出来。另外,Lab色彩模型的绝妙之处还在于它弥补了RGB色彩模型色彩分布不均的不足,因为RGB模型在蓝色到绿色之间的过渡色彩过多,而在绿色到红色之间又缺少黄色和其他色彩。如果我们想在数字图形的处理中保留尽量宽阔的色域和丰富的色彩,最好选择Lab。

    下面描述一下SLIC具体实现的步骤:

    1.  初始化种子点(聚类中心):按照设定的超像素个数,在图像内均匀的分配种子点。假设图片总共有 N 个像素点,预分割为 K 个相同尺寸的超像素,那么每个超像素的大小为N/ K ,则相邻种子点的距离(步长)近似为S=sqrt(N/K)

    2.  在种子点的n*n邻域内重新选择种子点(一般取n=3)。具体方法为:计算该邻域内所有像素点的梯度值,将种子点移到该邻域内梯度最小的地方。这样做的目的是为了避免种子点落在梯度较大的轮廓边界上,以免影响后续聚类效果。

    3.  在每个种子点周围的邻域内为每个像素点分配类标签(即属于哪个聚类中心)。和标准的k-means在整张图中搜索不同,SLIC的搜索范围限制为2S*2S,可以加速算法收敛,如下图。在此注意一点:期望的超像素尺寸为S*S,但是搜索的范围是2S*2S。


    4.  距离度量。包括颜色距离和空间距离。对于每个搜索到的像素点,分别计算它和该种子点的距离。距离计算方法如下:


    其中,dc代表颜色距离,ds代表空间距离,Ns是类内最大空间距离,定义为Ns=S=sqrt(N/K),适用于每个聚类。最大的颜色距离Nc既随图片不同而不同,也随聚类不同而不同,所以我们取一个固定常数m(取值范围[1,40],一般取10)代替。最终的距离度量D'如下:


    由于每个像素点都会被多个种子点搜索到,所以每个像素点都会有一个与周围种子点的距离,取最小值对应的种子点作为该像素点的聚类中心。

    5.  迭代优化。理论上上述步骤不断迭代直到误差收敛(可以理解为每个像素点聚类中心不再发生变化为止),实践发现10次迭代对绝大部分图片都可以得到较理想效果,所以一般迭代次数取10。

    6.  增强连通性。经过上述迭代优化可能出现以下瑕疵:出现多连通情况、超像素尺寸过小,单个超像素被切割成多个不连续超像素等,这些情况可以通过增强连通性解决。主要思路是:新建一张标记表,表内元素均为-1,按照“Z”型走向(从左到右,从上到下顺序)将不连续的超像素、尺寸过小超像素重新分配给邻近的超像素,遍历过的像素点分配给相应的标签,直到所有点遍历完毕为止。


    解析:

    1、设定期望分割的超像素数目,打开图片。将彩色RGB图片转换为LAB空间及x、y像素坐标共5维空间。

    2、DetectLabEdges。求图片中所有点的梯度=dx+dy.其中

    dx=(l(x-1)-l(x+1))*(l(x-1)-l(x+1))+(a(x-1)-a(x+1))*(a(x-1)-a(x+1))+(b(x-1)-b(x+1))*(b(x-1)-b(x+1));

    dy=(l(y-1)-l(y+1))*(l(y-1)-l(y+1))+(a(y-1)-a(y+1))*(a(y-1)-a(y+1))+(b(y-1)-b(y+1))*(b(y-1)-b(y+1));

    3、GetLABXYSeeds_ForGivenK。给定了要分割的超像素总数K,根据LABXY信息获得种子点。

    1)   超像素的种子点间步长Step=sqrt(N/K)。初始化种子点。按照步长均匀播撒种子点,初始化后种子点是均匀分布的(图1中的红色点)。

    2)   PerturbSeeds。扰乱种子点。在每个种子点的3*3邻域内,计算该种子点的8个邻域内像素点的Lab颜色梯度(同上述步骤2),分别与初始种子点梯度进行比较,取梯度值最小(最“平坦”)的点,并记录其LABXY信息作为新的种子点(图1中绿色点为扰乱后的新种子点)。

    图1:扰乱种子点图示

    4、超像素的步长Step=sqrt(N/K)+2。加了一个小偏置2是为了避免Step太小,造成超像素太密集的情况。

    5、PerformSuperpixelSegmentation_VariableSandM。对于每个超像素,最大的颜色距离M取值范围[1,40],一般取10。最大空间距离取步长为Step。

    1)   搜索范围2step* 2step,即设置offset=step。 在步长较短时(step<10)可以扩展offset=step*1.5作为搜索范围。

    2)  初始化distlab、distxy、distvec为无穷大。maxlab初始化为10*10,maxxy初始化为step*step。distlab代表某点与种子点的lab颜色空间距离,计算如下:distlab(i)=(l-kseedsl(n))*(l-kseedsl(n))+(a-kseedsa(n))*(a-kseedsa(n))+(b-kseedsb(n))*(b-kseedsb(n));distxy代表某点与种子点的空间坐标距离,计算如下:distxy(i)=(x-kseedsx(n))*(x-kseedsx(n))+(y-kseedsy(n))*(y-kseedsy(n));dist代表某点与种子点的综合距离(归一化的颜色距离+空间距离),计算如下:dist=distlab/( maxlab)+ distxy/(maxxy);在此提醒一下:如果将C++程序转为matlab代码时特别要注意数据类型。uint16类型变量减去double类型变量的结果是uint16类型,所以如果后者值大于前者,结果就为0。此处容易出错,需要强制类型转换。

    3)   计算搜索区域内每个点离种子点的距离dist,并将搜索区域内每个点离种子点的距离保存在distvec中。因为某点可能位于多个种子点的搜索区域,所以最后保存的是离相邻种子点最近的距离,并将该像素标号为最近种子点相同的标号。同一个超像素内所有像素的标号相同

    4)   计算每个新超像素内所有像素的labxy均值和坐标重心。将坐标重心作为该超像素的新种子点位置。

    5)   上述步骤2)到4)重复迭代10次。

    6、EnforceLabelConnectivity。该函数主要有几个作用:保证同一个超像素都是单连通区域;去掉尺寸过小的超像素;避免单个超像素被切割的情况。

    1)   先计算超像素理想面积大小:SUPSZ = sz/K = N/K;

    2)   有两种标号向量:上一步骤中得到的旧标号向量labels(即步骤5中得到的klabels),但其存在多连通,过小超像素等问题,需要优化。新标号向量nlabels,初始化值全为-1。

    3)   首先选择每个超像素的起始点(左上角的第一个点),起始点判断条件:a) 按照从左到右,从上到下的“Z”型顺序查找。b)该点在新标号向量nlabels中未被标记过(值为-1)。将其坐标保存在xvec[0],yvec[0]中。

    4)   记录前一个相邻超像素的标号值adjlabel。判断条件:a)在步骤3中起始点的四邻域。b)在新标号向量nlabels中被标记过(标号大于0)。记录adjlabel的目的是:如果当前超像素尺寸过小,将当前超像素标号全部用adjlabel代替。即合并到前一个相邻超像素,参考下面步骤6)。

    5)   扩展当前超像素。首先选择起始点作为当前操作的中心点,然后对其四邻域进行判断是否属于该超像素成员。判断条件:a) 该点在新标号向量nlabels中未被标记过(值为-1);b)该点n和当前操作中心点c在旧标号向量中标号一致,即labels(n)= labels(c),可以理解为原先就是属于同一个超像素的成员。如果判断是超像素的新成员,那么把该新成员作为新的操作中心点,循环直到找不到新成员为止。

    6)   如果新超像素大小小于理想超像素大小的一半(可以根据需要自己定义),将该超像素标号用前一个相邻超像素的标号值adjlabel代替,并且不递增标号值。

    7)   迭代上述步骤3)到6)直到整张图片遍历结束。

    7、绘制分割结果,退出窗口。

    图2:SLIC超像素分割结果,蓝色的点表示最终超像素的种子点。

     



    转自:http://blog.csdn.net/electech6/article/details/45509779



    另外一篇也很好:http://www.cnblogs.com/Imageshop/p/6193433.html


    展开全文
  • 亲测可用的SRM分割算法,可用于图像分割(超像素分割
  • 完整的 notebook 请看这里:slic-adj​data.kaizhao.net最近有个 idea 想以超像素为单位做一些 graph 的操作,需要输入 SLIC 分割之后的邻接矩阵。这本来应该挺简单的,但是 scipy 系列的文档实在是太分散了,查了好...

    c629e6680edb78e4877395e0409a814e.png

    完整的 notebook 请看这里:

    slic-adjdata.kaizhao.net
    fdb82898caedca8fa2c759b577dc55d0.png

    最近有个 idea 想以超像素为单位做一些 graph 的操作,需要输入 SLIC 分割之后的邻接矩阵。

    这本来应该挺简单的,但是 scipy 系列的文档实在是太分散了,查了好几个 package 的文档才找到,这里 mark 一下。

    需求是“计算 slic 分割中超像素之间的邻接矩阵”。

    不多说,上代码:

    import numpy as np
    from skimage.io import imread
    from skimage import segmentation
    from skimage.util import img_as_float
    from skimage.future import graph
    from networkx.linalg import adj_matrix
    import matplotlib
    %matplotlib inline
    import matplotlib.pyplot as plt
    
    img = imread("dog.jpg")
    img = img_as_float(img)
    # SLIC 分割
    labels = segmentation.slic(img, compactness=30, n_segments=400)
    # labels 转 graph
    g = graph.RAG(labels)
    # 算邻接矩阵
    adj = adj_matrix(g).todense()
    
    img_with_boundaries = segmentation.mark_boundaries(img, labels, color=[1,0,0])
    plt.imshow(img_with_boundaries)

    3fbb0373d70397f1388ea9d634f9e04f.png
    SLIC 分割结果

    是输入图片,
    是 SLIC 分割后的结果。每个 label 值对应分割中的一块区域,每块分割区域内的label值相同:
    fig,axes = plt.subplots(2,4,figsize=(8,4))
    for idx, ax in enumerate(axes.flatten()):
        ax.set_xticks([])
        ax.set_yticks([])
        ax.set_title("labels=%d"%(idx*40))
        ax.imshow(labels==(idx*40),cmap=cm.Greys_r)
    plt.tight_layout(pad=0)

    687ffbd76e921ae87b8aea8499aa6552.png

    最后算出的邻接矩阵 adj 为

    的矩阵(这里一共分割成了 390 个区域),

    adj[i,j]=1 表示区域 i 和区域 j 相邻:

    fig,axes = plt.subplots(2,2,figsize=(4,4))
    for idx, ax in enumerate(axes.flatten()):
        ax.set_xticks([])
        ax.set_yticks([])
    axes[0,0].imshow(np.logical_or(labels==25, labels==23), cmap=cm.Greys_r)
    axes[0,0].set_title("adj[%d,%d]=%d"%(25,23,adj[25,23]))
    
    axes[0,1].imshow(np.logical_or(labels==151, labels==128), cmap=cm.Greys_r)
    axes[0,1].set_title("adj[%d,%d]=%d"%(151,128,adj[151,128]))
    
    axes[1,0].imshow(np.logical_or(labels==251, labels==350), cmap=cm.Greys_r)
    axes[1,0].set_title("adj[%d,%d]=%d"%(251,350,adj[251,350]))
    
    axes[1,1].imshow(np.logical_or(labels==388, labels==373), cmap=cm.Greys_r)
    axes[1,1].set_title("adj[%d,%d]=%d"%(388,373,adj[388,373]))

    ff6cd1100106c11ae69a5928d3326238.png

    完整的 notebook 请看这里:http://data.kaizhao.net/notebooks/slic-adj.html

    展开全文
  • 介绍SLIC超像素分割算法,给出其与openCV的接口,代码用VS2012和openCV2.4.9测试可运行。
  • 写完这篇,图像分割的传统方法就快全了,传统图像分割大体有基于阈值的,这类就没啥算法可以写,所以直接略过了;...最后就是超像素分割了,超像素分割有k-means算法的影子,所以可以先看看k-means算法的代码实现过程.
  • 超像素分割算法比较 本例比较了四种常用的低阶图像分割方法。由于很难获得良好的分割,“良好”的定义往往取决于应用,这些方法通常用于获得过度分割,也称为超像素。然后,这些超像素作为更复杂的算法(如条件随机...
  • superpixels-segmentation-gui-opencv:带有QT和OpenCV超像素分割算法,带有漂亮的GUI可以使单元着色
  • 本代码是论文: Liu M Y, Tuzel O, Ramalingam S, et al. Entropy rate superpixel segmentation[C]// Computer Vision and Pattern Recognition. IEEE, 2011:2097-2104. 的实现代码,网络上的原始链接均已失效,分享...
  • 概念理解超像素利用像素之间某些特征的相似性将像素分组(每个子区域内部之间某个特征具有很强的一致性),用少量的超像素代替大量的像素来表达图片特征,即我们把图像分割成很多小块,把这一整个块当成一个像素来处.....
  • 问题或建议,请公众号留言;如果你觉得文章对你有帮助,欢迎转发支持在计算机视觉中,图像分割是个非常重要且基础的研究方向。简单来说,图像分割...图像分割中的一些常见的术语有:superpixels(超像素)、Semantic...
  • SILC算法详解一、原理介绍SLIC算法是simple linear iterative cluster的简称,该算法用来生成超像素(superpixel)算法步骤:已知一副图像大小M*N,可以从RGB空间转换为LAB空间,LAB颜色空间表现的颜色更全面假如预定义...
  • OpenCV3中超像素分割算法SEEDS,SLIC, LSC算法在Contrib包里,需要使用Cmake编译使用。为了方便起见,我将三种算法的源码文件从contrib包里拎了出来,可以直接使用,顺便比较一下算法的效果。  三种算法的源码...
  • SLIC图像超像素分割算法解析

    千次阅读 2017-04-03 16:42:09
    1 概述 SLIC 即simple linear ...分簇的依据是像素之间的颜色相似性与邻近性。其中颜色相 似性的度量因子是lab 颜色空间的L1 范数,颜色邻近性的度量因子是图像二维坐标空间xy。因而综合的度量因子 是[labxy]五维空
  • SLIC算法是simple linear iterative cluster的简称,该算法用来生成超像素(superpixel) 算法步骤: 已知一副图像大小M*N,可以从RGB空间转换为LAB空间,LAB颜色空间表现的颜色更全面 假如预定义参数K...
  • 【OpenCv3】 VS C++ (五):SLIC超像素分割算法

    千次阅读 热门讨论 2019-10-25 21:49:55
    题目如下: 简单解法(HSV 直方图阈值)如下: ...这一节先讲SLIC超像素算法,下一节讲在超像素基础上用Kmeans分类进行分割,参考博客如下: https://www.jianshu.com/p/d0ef931b3ddf https://blog.csdn.net/duyue...
  • 有空来补理 import math from skimage import io, color import numpy as np from tqdm import trange import cv2 class Cluster(object): cluster_index = 1 ... def __init__(self, h, w, l=0, a=0, b=0): ...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 286
精华内容 114
关键字:

超像素分割算法