草庐IT

python - 实现 log Gabor 滤波器组

coder 2023-08-21 原文

我正在阅读这篇论文 "Self-Invertible 2D Log-Gabor Wavelets"它这样定义 2D log gabor 过滤器:

论文还指出,滤波器仅覆盖频率空间的一侧,并在此图像中显示

在我尝试实现过滤器时,我得到的结果与论文中所说的不符。让我从我的实现开始,然后我将说明问题。

实现:

  1. 我创建了一个包含滤波器的二维数组并转换了每个索引,以便频域的原点位于数组的中心,正 x 轴向右,正 y 轴向上。

    number_scales = 5         # scale resolution
    number_orientations = 9   # orientation resolution
    N = constantDim           # image dimensions
    
    def getLogGaborKernal(scale, angle, logfun=math.log2, norm = True):
        # setup up filter configuration
        center_scale = logfun(N) - scale          
        center_angle = ((np.pi/number_orientations) * angle) if (scale % 2) \
                    else ((np.pi/number_orientations) * (angle+0.5))
        scale_bandwidth =  0.996 * math.sqrt(2/3)
        angle_bandwidth =  0.996 * (1/math.sqrt(2)) * (np.pi/number_orientations)
    
        # 2d array that will hold the filter
        kernel = np.zeros((N, N))
        # get the center of the 2d array so we can shift origin
        middle = math.ceil((N/2)+0.1)-1
    
        # calculate the filter
        for x in range(0,constantDim):
            for y in range(0,constantDim):
                # get the transformed x and y where origin is at center
                # and positive x-axis goes right while positive y-axis goes up
                x_t, y_t = (x-middle),-(y-middle)
                # calculate the filter value at given index
                kernel[y,x] = logGaborValue(x_t,y_t,center_scale,center_angle,
            scale_bandwidth, angle_bandwidth,logfun)
    
        # normalize the filter energy
        if norm:
            Kernel = kernel / np.sum(kernel**2)
        return kernel
    
  2. 为了计算每个索引处的过滤器值,在我们转到对数极坐标空间的地方进行另一个转换

    def logGaborValue(x,y,center_scale,center_angle,scale_bandwidth,
                  angle_bandwidth, logfun):
        # transform to polar coordinates
        raw, theta = getPolar(x,y)
        # if we are at the center, return 0 as in the log space
        # zero is not defined
        if raw == 0:
            return 0
    
        # go to log polar coordinates
        raw = logfun(raw)
    
        # calculate (theta-center_theta), we calculate cos(theta-center_theta) 
        # and sin(theta-center_theta) then use atan to get the required value,
        # this way we can eliminate the angular distance wrap around problem
        costheta, sintheta = math.cos(theta), math.sin(theta)
        ds = sintheta * math.cos(center_angle) - costheta * math.sin(center_angle)    
        dc = costheta * math.cos(center_angle) + sintheta * math.sin(center_angle)  
        dtheta = math.atan2(ds,dc)
    
        # final value, multiply the radial component by the angular one
        return math.exp(-0.5 * ((raw-center_scale) / scale_bandwidth)**2) * \
                math.exp(-0.5 * (dtheta/angle_bandwidth)**2)
    

问题:

  1. 角度:论文指出,索引 1->8 的角度会很好地覆盖方向,但在我的实现中,1->n 的角度不覆盖除了半方向。甚至垂直方向也没有被正确覆盖。这可以在这个图中显示,其中包含比例为 3 和方向范围为 1->8 的滤波器组:

  2. 覆盖范围:从上面的过滤器可以清楚地看出,过滤器覆盖了空间的两侧,这不是论文所说的。这可以通过使用范围从 -4 -> 4 的 9 个方向变得更加明确。下图包含一张图像中的所有过滤器,以显示它如何覆盖光谱的两侧(该图像是通过在每个位置取最大值创建的来自所有过滤器):

  3. Middle Column (orientation $\pi/2$): 在第一个图中从 3 -> 8 的方向可以看出过滤器在方向 $\pi/处消失2 美元。这是正常的吗?当我将所有过滤器(所有 5 个尺度和 9 个方向)组合到一张图像中时,也可以看到这一点:

更新: 在空间域中添加滤波器的脉冲响应,如您所见,-4 和 4 方向有明显的失真:

最佳答案

经过大量的代码分析,我发现我的实现是正确的,但是 getPolar 函数被搞砸了,所以上面的代码应该可以正常工作。如果有人在寻找它,这是没有 getPolar 函数的新代码:

number_scales = 5          # scale resolution
number_orientations = 8    # orientation resolution
N = 128                    # image dimensions
def getFilter(f_0, theta_0):
    # filter configuration
    scale_bandwidth =  0.996 * math.sqrt(2/3)
    angle_bandwidth =  0.996 * (1/math.sqrt(2)) * (np.pi/number_orientations)

    # x,y grid
    extent = np.arange(-N/2, N/2 + N%2)
    x, y = np.meshgrid(extent,extent)

    mid = int(N/2)
    ## orientation component ##
    theta = np.arctan2(y,x)
    center_angle = ((np.pi/number_orientations) * theta_0) if (f_0 % 2) \
                else ((np.pi/number_orientations) * (theta_0+0.5))

    # calculate (theta-center_theta), we calculate cos(theta-center_theta) 
    # and sin(theta-center_theta) then use atan to get the required value,
    # this way we can eliminate the angular distance wrap around problem
    costheta = np.cos(theta)
    sintheta = np.sin(theta)
    ds = sintheta * math.cos(center_angle) - costheta * math.sin(center_angle)    
    dc = costheta * math.cos(center_angle) + sintheta * math.sin(center_angle)  
    dtheta = np.arctan2(ds,dc)

    orientation_component =  np.exp(-0.5 * (dtheta/angle_bandwidth)**2)

    ## frequency componenet ##
    # go to polar space
    raw = np.sqrt(x**2+y**2)
    # set origin to 1 as in the log space zero is not defined
    raw[mid,mid] = 1
    # go to log space
    raw = np.log2(raw)

    center_scale = math.log2(N) - f_0
    draw = raw-center_scale
    frequency_component = np.exp(-0.5 * (draw/ scale_bandwidth)**2)

    # reset origin to zero (not needed as it is already 0?)
    frequency_component[mid,mid] = 0

    return frequency_component * orientation_component

关于python - 实现 log Gabor 滤波器组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31774071/

有关python - 实现 log Gabor 滤波器组的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  3. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  5. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  6. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  9. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  10. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

随机推荐