zoukankan      html  css  js  c++  java
  • 一种采用匹配滤波器进行静脉图像分割方法的matlab实现

    图像分割(segmentation)是一种非常常用的技术,这种技术能够把你想要研究的东西和不相关的东西给分离开来,比如我们经常用photoshop把照片的人取出来然后换个背景或者其他ps一下,这个就是图像分割,但是这个领域研究的都是自动图像分割技术,不需要人工去分。现在已经提出的自动图像分割方法有很多种,但是只能解决一部分的问题,有些图像还必须人工去分,所以挑战依旧存在,新的方法依旧不断被提出。

    出于一些医疗上的目的,经常需要对一些医疗成像的血管图像进行分割,提取出血管部分,来进行进一步的研究,所以血管分割作为图像分割中的一类,有很多关专门解决这个问题的算法被提出。而本文将要介绍的方法就属于所有血管分割方法中的一种,这种方法基于一种叫做匹配滤波器(matched filter)的东西。这种方法早在1989年就已经被提出[1],本文其实也是对这个论文的总结和实现,有很多基于这篇论文的改进算法。

    这个方法的灵感来自与信号处理中的匹配滤波器。按照百度百科中将的,匹配滤波器的性能与信号的特性取得某种一致,能够使滤波器输出端的信号瞬时功率与噪声平均功率的比值最大,即当信号与噪声同时进入滤波器时,它使信号成分在某一瞬间出现尖峰值,而噪声成分受到抑制。要想设计匹配滤波器,信号的波形必须是已知的。如果将血管图像看做一个信号,虽然这个信号的具体情况不得而知,但是血管的特点是已知的,基于这点先验知识可以针对血管设计匹配滤波器,那么按照匹配滤波器的原理,当血管部分输入时会出现较大值,而当背景区域输入时将出现较小值,从而将静脉与血管分开。

    根据以上的分析,我们需要研究血管的特点。血管有以下特点:血管的宽度只在较小的范围内变动,血管壁的两条线是平行的,血管有方向,而跟深入的分析血管图像,还可以发现血管横切线上的灰度曲线是一个下面这个样子的:

    根据以上血管的特点,文章[1]中提出了一种匹配滤波器的设计方法。先将血管想象成一小段一小段的平行区域的组合,设定长度为L,宽度为2sigma,然后用一个倒过来的高斯曲线来模拟上面血管横切线灰度曲线, 从而得到匹配滤波器如下:

    因为血管是有方向的,所以在此滤波器的基础上进行没15度旋转一次,得到一个从0度到180度的12个匹配滤波器,然后分别进行卷积,每个像素的值为响应最大的那个滤波器得到的值。滤波之后,在采用一个全局的阈值进行过滤,大小各分一边,得到一个二值化的血管图像。

    上面是只是简单的进行了介绍,还有很多细节没有提出,具体的方法参照论文。

    下面是matlab代码:

    function [g,bg]=matchedFilter2(f)
    
    f=double(f);
    % mean filter
    f=medfilt2(f,[5,5]);
    f=medfilt2(f,[21 1]);
    f=medfilt2(f,[1,7]);
    
    % 参数
    os=12;  % 角度的个数
    sigma=10;
    tim=4;
    L=9;
    t=70; % threshhold
    
    thetas=0:(os-1);
    thetas=thetas.*(180/os);
    N1=-tim*sigma:tim*sigma;
    N1=-exp(-(N1.^2)/(2*sigma*sigma));
    N=repmat(N1,[2*floor(L/2)+1,1]);
    r2=floor(L/2);
    c2=floor(tim*sigma);
    [m,n]=size(f);
    RNs=cell(1,os);  % rotated kernals
    MFRs=cell(1,os); % filtered images
    g1=f;
    
    % matched filter
    for i=1:os
        theta=thetas(i);
        RN=imrotate(N,theta);
        %去掉多余的0行和零列
        RN=RN(:,any(RN));
        RN=RN(any(RN'),:);
        meanN=mean2(RN);
        RN=RN-meanN;
        RNs{1,i}=RN;
        MFRs{1,i}=imfilter(f,RN,'conv','symmetric');
    end
    
    % get the max response
    g=MFRs{1,1};
    for j=2:os
        g=max(g,MFRs{1,j});
    end
    bg=g<t;
    
    end
    

    里面三个参数sigma,L,T的选择需要针对不同的应用去尝试,如果与论文中一样分割的是视网膜血管图像,参数可以不变即2,9,3。而我做的是对手部静脉的分割,所以参数是上面代码所显示。至于全局阈值t的选择,最粗犷最常用的方法就是试几次找最好的,当然也有其他找这个阈值的方法。至于这个方法的性能,我觉得还是不错的。但是,为了取得好的结果预处理和后续处理也是必不可少的。

     [1] S. Chaudhuri, S. Chatterjee, N. Katz, M. Nelson, M. Goldbaum, Detection of blood vessels in retinal images using two dimensional matched filters, IEEE Trans. Med. Imaging 8 (3) (1989) 263–269.

  • 相关阅读:
    《作业二》总结
    《作业一》总结
    团队项目-需求分析报告
    团队项目-选题报告
    第一次结对编程作业
    第一次个人编程作业
    第一次博客作业
    第12组 团队项目-需求分析报告
    团队项目-选题报告
    第二次结对编程作业
  • 原文地址:https://www.cnblogs.com/naniJser/p/2810551.html
Copyright © 2011-2022 走看看