如何将Gabor小波应用于图像?
image
image-processing
matlab
5
0

如何在图像上应用这些Gabor滤波器小波?

在此处输入图片说明

close all;
clear all;
clc;

% Parameter Setting
R = 128;
C = 128;
Kmax = pi / 2;
f = sqrt( 2 );
Delt = 2 * pi;
Delt2 = Delt * Delt;

% Show the Gabor Wavelets
for v = 0 : 4
    for u = 1 : 8
        GW = GaborWavelet ( R, C, Kmax, f, u, v, Delt2 ); % Create the Gabor wavelets
          figure( 2 );
     subplot( 5, 8, v * 8 + u ),imshow ( real( GW ) ,[]); % Show the real part of Gabor wavelets

    end

    figure ( 3 );
     subplot( 1, 5, v + 1 ),imshow ( abs( GW ),[]); % Show the magnitude of Gabor wavelets

end



function GW = GaborWavelet (R, C, Kmax, f, u, v, Delt2)


k = ( Kmax / ( f ^ v ) ) * exp( 1i * u * pi / 8 );% Wave Vector

kn2 = ( abs( k ) ) ^ 2;

GW = zeros ( R , C );

for m = -R/2 + 1 : R/2

    for n = -C/2 + 1 : C/2

        GW(m+R/2,n+C/2) = ( kn2 / Delt2 ) * exp( -0.5 * kn2 * ( m ^ 2 + n ^ 2 ) / Delt2) * ( exp( 1i * ( real( k ) * m + imag ( k ) * n ) ) - exp ( -0.5 * Delt2 ) );

    end

end

编辑:这是我图像的尺寸

在此处输入图片说明

参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

Gabor滤波器的典型用途是计算在几个方向的每个方向上的滤波器响应,例如用于边缘检测。

通过使用卷积定理 ,可以对图像进行卷积处理 ,方法是对图像和过滤器进行傅里叶变换,然后对元素进行乘积的逆傅里叶变换。这是基本公式:

%# Our image needs to be 2D (grayscale)
if ndims(img) > 2;
    img = rgb2gray(img);
end
%# It is also best if the image has double precision
img = im2double(img);

[m,n] = size(img);
[mf,nf] = size(GW);
GW = padarray(GW,[n-nf m-mf]/2);
GW = ifftshift(GW);
imgf = ifft2( fft2(img) .* GW );

通常,对于大于20的内核,FFT卷积是更好的。有关详细信息,我建议使用C语言的数值食谱 ,该食谱对方法及其注意事项有很好的语言不可知的描述。

您的内核已经很大,但是使用FFT方法,它们可以与图像一样大,因为无论如何它们都会被填充为该大小。由于FFT的周期性,所以该方法执行循环卷积。这意味着滤镜将环绕图像边界,因此我们也必须填充图像本身以消除这种边缘效果。最后,由于我们希望对所有滤波器进行总响应(至少在典型的实现中如此),因此我们需要依次将每个滤波器应用于图像,并对响应求和。通常一个方向只使用3到6个方向,但是通常也要在几个尺度(不同的内核大小)下进行过滤,因此在这种情况下,会使用大量的过滤器。

您可以使用以下代码完成整个操作:

img = im2double(rgb2gray(img)); %# 
[m,n] = size(img); %# Store the original size.

%# It is best if the filter size is odd, so it has a discrete center.
R = 127; C = 127;

%# The minimum amount of padding is just "one side" of the filter.
%# We add 1 if the image size is odd.
%# This assumes the filter size is odd.
pR = (R-1)/2;
pC = (C-1)/2;
if rem(m,2) ~= 0; pR = pR + 1; end;
if rem(n,2) ~= 0; pC = pC + 1; end;
img = padarray(img,[pR pC],'pre'); %# Pad image to handle circular convolution.

GW = {}; %# First, construct the filter bank.
for v = 0 : 4
    for u = 1 : 8
        GW =  [GW {GaborWavelet(R, C, Kmax, f, u, v, Delt2)}];
    end
end

%# Pad all the filters to size of padded image.
%# We made sure padsize will only be even, so we can divide by 2.
padsize = size(img) - [R C];
GW = cellfun( ...
        @(x) padarray(x,padsize/2), ...
        GW, ...
        'UniformOutput',false);

imgFFT = fft2(img); %# Pre-calculate image FFT.

for i=1:length(GW)
    filter = fft2( ifftshift( GW{i} ) ); %# See Numerical Recipes.
    imgfilt{i} = ifft2( imgFFT .* filter ); %# Apply Convolution Theorem.
end

%# Sum the responses to each filter. Do it in the above loop to save some space.
imgS = zeros(m,n);
for i=1:length(imgfilt)
    imgS = imgS + imgfilt{i}(pR+1:end,pC+1:end); %# Just use the valid part.
end

%# Look at the result.
imagesc(abs(imgS));

请记住,这实际上是最低限度的实现。您可以选择填充边框的副本,而不是填充零,对图像应用开窗功能或增大填充大小以获取频率分辨率。这些都是我上面概述的技术的标准扩充,对于通过GoogleWikipedia进行的研究来说应该是微不足道的。还要注意,我还没有添加任何基本的MATLAB优化,例如预分配等。

最后一点,如果您的过滤器总是比图像小很多,您可能希望跳过图像填充(即,使用第一个代码示例)。这是因为,将零添加到图像会在填充开始处创建人工边缘特征。如果过滤器很小,则圆卷积的环绕不会引起问题,因为仅涉及过滤器填充中的零。但是,只要过滤器足够大,环绕效果就会变得很严重。如果必须使用大型滤镜,则可能必须使用更复杂的填充方案,或者裁切图像的边缘。

收藏
评论

要将小波“应用”到图像,通常需要获取小波和图像的内积,以得到一个数字,该数字的大小表示该小波与图像的相关程度。如果对于128行和128列的图像,具有完整的小波集(称为“正交基”),则将具有128 * 128 = 16,384个不同的小波。您这里只有40个,但是您可以使用自己的东西工作。

要获得小波系数,您可以拍摄一张图像,说一幅:

t = linspace(-6*pi,6*pi,128);
myImg = sin(t)'*cos(t) + sin(t/3)'*cos(t/3);

并取这个和基向量GW之一的内积,如下所示:

myCoef = GW(:)'*myImg(:);

我喜欢将所有小波堆叠到一个矩阵GW_ALL中,其中每一行都是您拥有的32个GW(:)'小波之一,然后通过写一次计算所有小波系数

waveletCoefficients = GW_ALL*myImg(:);

如果使用stem(abs(waveletCoefficients))绘制这些图,您会发现其中一些大于其他。大值是与图像匹配的值。

最后,假设您的小波是正交的(实际上它们不是,但是在这里并不是很重要),您可以尝试使用小波重现图像,但是请记住,您只有32种可能性,它们全都在图像的中心...所以当我们写

newImage = real(GW_ALL'*waveletCoefficients);

我们在中心处得到的图像与原始图像相似,但在外部却没有。

我添加到您的代码中(如下)以获得以下结果: 在此处输入图片说明

修改内容如下:

% function gaborTest()

close all;
clear all;
clc;

% Parameter Setting
R = 128;
C = 128;
Kmax = pi / 2;
f = sqrt( 2 );
Delt = 2 * pi;
Delt2 = Delt * Delt;

% GW_ALL = nan(32, C*R);

% Show the Gabor Wavelets
for v = 0 : 4
    for u = 1 : 8
        GW = GaborWavelet ( R, C, Kmax, f, u, v, Delt2 ); % Create the Gabor wavelets
          figure( 2 );
         subplot( 5, 8, v * 8 + u ),imshow ( real( GW ) ,[]); % Show the real part of Gabor wavelets

         GW_ALL( v*8+u, :) = GW(:);

    end

    figure ( 3 );
     subplot( 1, 5, v + 1 ),imshow ( abs( GW ),[]); % Show the magnitude of Gabor wavelets

end

%% Create an Image:
t = linspace(-6*pi,6*pi,128);
myImg = sin(t)'*cos(t) + sin(t/3)'*cos(t/3);
figure(3333);
clf
subplot(1,3,1);
imagesc(myImg);
title('My Image');
axis image

%% Get the coefficients of the wavelets and plot:
waveletCoefficients = GW_ALL*myImg(:);

subplot(1,3,2);
stem(abs(waveletCoefficients));
title('Wavelet Coefficients')

%% Try and recreate the image from just a few wavelets.
% (we would need C*R wavelets to recreate perfectly)

subplot(1,3,3);
imagesc(reshape(real(GW_ALL'*waveletCoefficients),128,128))
title('My Image Reproduced from Wavelets');
axis image

这种方法构成了提取小波系数和再现图像的基础。 Gabor小波(如上所述)不是正交的( 参考 ),并且更有可能用于通过reve_etrange描述的卷积进行特征提取。在这种情况下,您可以考虑将其添加到内部循环中:

 figure(34);
 subplot(5,8, v * 8 + u );
 imagesc(abs(ifft2((fft2(GW).*fft2(myImg)))));
 axis off
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号