【问题标题】:Feature extraction with Gabor filters使用 Gabor 滤波器进行特征提取
【发布时间】:2018-08-13 16:06:02
【问题描述】:

我目前正在使用 Matlab 中的 Gabor 过滤器开发特征提取系统。对于 Gabor 过滤器和图像卷积,我使用的是在此处找到的代码 https://www.mathworks.com/matlabcentral/fileexchange/44630-gabor-feature-extraction,为我自己的使用稍作调整。该系统的人脸来自 AT&T 人脸数据库http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html 我使用数据库中的 9 个主题。每个主题有 10 张属于他/她的图像。使用 Viola Jones 裁剪面部图像并将其调整为 128x128 像素。

此函数创建 Gabor 滤波器组。其中 u=5, v=8, m,n = 39。因此得到的 gaborArray 由 40 个不同的 Gabor 滤波器组成,这些滤波器具有 5 个尺度和 8 个方向。 我认为这 2 个功能按预期工作,因为它们来自经批准的外部来源。

function gaborArray = gaborFilterBank(u,v,m,n)
gaborArray = cell(u,v);
fmax = 0.25;
gama = sqrt(2);
eta = sqrt(2);

for i = 1:u    
    fu = fmax/((sqrt(2))^(i-1));
    alpha = fu/gama;
    beta = fu/eta;    
    for j = 1:v
        tetav = ((j-1)/v)*pi;
        gFilter = zeros(m,n);

        for x = 1:m
            for y = 1:n
                xprime = (x-((m+1)/2))*cos(tetav)+(y-((n+1)/2))*sin(tetav);
                yprime = -(x-((m+1)/2))*sin(tetav)+(y-((n+1)/2))*cos(tetav);
                gFilter(x,y) = (fu^2/(pi*gama*eta))*exp(-((alpha^2)*(xprime^2)+(beta^2)*(yprime^2)))*exp(1i*2*pi*fu*xprime);
            end
        end
        gaborArray{i,j} = gFilter;        
    end
end    

这是第二部分,我加载我的数据库并将每个图像与存储在 gaborArray 中的 Gabor Bank 进行卷积,这是从之前的函数中获得的。由于我使用 9 个主题 x 10 个图像 result 的单元格大小为 90 x gaborAbs + 1 类 (1-9)

function [result]  = feature(gaborArray)
faceDatabase = imageSet(database,'recursive');    %database = folder
numberOfFoldersOverall = size(faceDatabase,2);
numberOfPhotosPF = 10;
cellSize = numberOfFoldersOverall * numberOfPhotosPF;
allFeatures = cell(cellSize,1);

[u,v] = size(gaborArray);
gaborResult = cell(u,v);
d1 = 4;
d2 = 4;
count = 1;

for m=1:numberOfFoldersOverall
    for n=1:numberOfPhotosPF
        I= (read(faceDatabase(m), n));
        I = double(I);
        featureVector = [];

        for i = 1:u
            for j = 1:v
                gaborResult{i,j} = imfilter(I, gaborArray{i,j});
            end
        end
        for i = 1:u
            for j = 1:v
                gaborAbs = abs(gaborResult{i,j});
                gaborAbs = downsample(gaborAbs,d1); 
                gaborAbs = downsample(gaborAbs.',d2);
                gaborAbs = gaborAbs(:);

                gaborAbs = (gaborAbs-mean(gaborAbs))/std(gaborAbs,1);
                featureVector =  [featureVector; gaborAbs];                                
             end
         end
         featureVector = [featureVector; m];
         allFeatures{count} = featureVector;
         count = count + 1;
    end
end
result = allFeatures;     

这部分我可能在实现中犯了错误。在Gabor feature extraction 的帮助下,我对之前计算局部能量的函数做了一些更改

gaborAbs = gaborResult{i,j};     %no longer abs(gaborResult{i,j})
gaborAbs = downsample(gaborAbs,d1); 
gaborAbs = downsample(gaborAbs.',d2);
gaborAbs = gaborAbs(:);
gaborAbs = sum(gaborAbs).^2;    %sum of squared gaborAbs

并计算平均幅度

gaborAbs = abs(gaborResult{i,j});                         
gaborAbs = downsample(gaborAbs,d1);                       
gaborAbs = downsample(gaborAbs.',d2);
gaborAbs = gaborAbs(:);
gaborAbs = sum(gaborAbs);       % sum of abs gaborAbs

Local energy 和 Mean Amplitude 向量的长度均为 41,其中最后一个索引是主题类别。但是,当我在基于 Knn 的人脸识别系统中使用其中任何一种时,在某些情况下,我最终会得到 10% 的识别率。

我尝试在 matlab 中使用 andrewsplot 绘制局部能量特征向量,结果是这样。每条线代表 1 个主题,因此共有 90 条线,其中相同颜色的线属于同一类(图像上的同一个人)。正如我们所看到的,它们堆叠在一起,几乎没有区别

所以终于,我很抱歉我要求您进行如此冗长的描述。

  1. 我在计算局部能量或平均振幅时是否犯了错误?
  2. Andrewsplot 是否适合表示此类数据?
  3. 如果是,我是否可以很好地解释它,因为所有特征向量基本上几乎相同,因为图形几乎没有差异?(我假设属于同一个人的图像应该堆叠但与其他人不同。这里所有的东西都堆叠!)
  4. 或者这些特征是否根本不适合人脸识别? 提前感谢您提供任何提示或示例。向 Yondaru 致以最诚挚的问候。

【问题讨论】:

    标签: matlab feature-extraction feature-selection gabor-filter


    【解决方案1】:

    这是我的第一个想法。这不会是一个完整的答案,但也许你可以在这里采取形式。

    Gabor 滤波器结果的幅度给出了相当平滑的结果:它是局部邻域中存在的给定空间频率的数量。但是如果你分别看实部和虚部,你会看到一个高频信号(等于滤波器本身的频率)。我鼓励您将其中一些结果显示为图像以感受一下。

    对平滑幅度进行下采样是可以的。这很顺利,您将获得该社区的代表性结果。但是对实部和虚部进行下采样是危险的:您可能会看到混叠,或者充其量是一个无意义的量。当然,这两个分量加起来还是有一个有意义的量级,但是相位是没有意义的。

    在任何情况下,由于能量是范数的平方,因此您实际上并不需要下采样相位。只需对幅值图像进行平方和求和即可。

    最后,如果你无论如何都要求和,为什么要降采样?我看不出有什么优势。

    在编码方面:为什么要在gaborResult中保存所有过滤结果?您不妨对所有 u,v 循环一次,应用过滤器,然后直接计算该过滤器的总和幅度。

    【讨论】:

    • 感谢您的回复@CrisLuengo。我明白你在编码方面的观点,并将相应地调整它。同样通过下采样,我只是把它留在那里,就像它在原始代码中一样。但是正如您所说,在计算能量时拥有它是不必要的,甚至可能是不好的。关于计算这些特征向量……我应该使用实部还是虚部或幅度?尽管如此,当我显示它们时,我看到了不同之处,当谈到我应该计算我的特征向量的问题时,我有点迷失了。
    • @Yondaru:我认为这个阶段根本不相关。使用幅度。能量计算为sum(abs(signal).^2),或等效为sum(signal.*conj(signal))。
    猜你喜欢
    • 1970-01-01
    • 2018-12-19
    • 2013-11-27
    • 2011-04-13
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    相关资源
    最近更新 更多