You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不完全重构代码时避免多尺度检测中的重复计算

问题分析与优化方案

你当前的核心问题是:在MultiscaleDetector遍历不同空间尺度sigma时,每次调用GaborDetector都会重复计算仅依赖时间参数tau的Gabor时间滤波器(h_ev和h_od),而之前尝试的lambda包装、内部函数加lru_cache都没起到有效优化作用——前者只是参数包装,根本没减少重复计算;后者因为内部函数每次调用GaborDetector都会被重新定义,导致缓存无法跨调用共享,等于没生效。

以下是两种无需大规模重构代码的优化方案:


方案一:将tau相关计算抽为独立的缓存函数

把仅依赖tau的滤波器计算逻辑移到GaborDetector外部,作为带lru_cache的独立函数,这样所有GaborDetector调用都会共享同一个缓存池,同一个tau值只会计算一次。

from functools import lru_cache
import numpy as np
import scipy.signal as scp

# 独立的缓存函数,所有GaborDetector调用共享缓存
@lru_cache(maxsize=None)
def compute_gabor_time_filters(tau):
    time = np.linspace(-2*tau, 2*tau, int(4*tau+1))
    omega = 4/tau
    h_ev = np.exp(-time**2/(2*tau**2)) * np.cos(2*np.pi*omega*time)
    h_od = np.exp(-time**2/(2*tau**2)) * np.sin(2*np.pi*omega*time)
    h_ev /= np.linalg.norm(h_ev, ord=1)
    h_od /= np.linalg.norm(h_od, ord=1)
    return h_ev, h_od

def GaborDetector(v, sigma, tau, threshold, num_points):
    """
    Gabor Detector
    
    Keyword arguments:
    video -- input video (y_len, x_len, frames)
    sigma -- Gaussian kernel space standard deviation
    tau -- Gaussian kernel time standard deviation
    threshold -- Gabor response threshold
    """
    # setup video
    video = v.copy()
    video = video.astype(float)/video.max()
    video = video_smoothen_space(video, sigma)
    
    # 直接调用缓存好的滤波器,避免重复计算
    h_ev, h_od = compute_gabor_time_filters(tau)
    
    # compute the response
    response = (scp.convolve1d(video, h_ev, axis=2) ** 2) + (scp.convolve1d(video, h_od, axis=2) ** 2)
    points = interest_points(response, num=num_points, threshold=threshold, scale=sigma)
    return points

方案二:在MultiscaleDetector中预计算tau相关结果并传入

如果不想修改GaborDetector的核心逻辑结构,可以给它加一个可选参数,允许传入预先计算好的滤波器,然后在MultiscaleDetector中仅计算一次tau相关的滤波器,再在循环中复用。

修改后的GaborDetector

def GaborDetector(v, sigma, tau, threshold, num_points, precomputed_filters=None):
    """
    Gabor Detector
    
    Keyword arguments:
    video -- input video (y_len, x_len, frames)
    sigma -- Gaussian kernel space standard deviation
    tau -- Gaussian kernel time standard deviation
    threshold -- Gabor response threshold
    precomputed_filters -- tuple of (h_ev, h_od), 若传入则跳过滤波器计算
    """
    # setup video
    video = v.copy()
    video = video.astype(float)/video.max()
    video = video_smoothen_space(video, sigma)
    
    # 优先使用预计算的滤波器
    if precomputed_filters is not None:
        h_ev, h_od = precomputed_filters
    else:
        # 原有的滤波器计算逻辑,兼容未传参的场景
        time = np.linspace(-2*tau, 2*tau, int(4*tau+1))
        omega = 4/tau
        h_ev = np.exp(-time**2/(2*tau**2)) * np.cos(2*np.pi*omega*time)
        h_od = np.exp(-time**2/(2*tau**2)) * np.sin(2*np.pi*omega*time)
        h_ev /= np.linalg.norm(h_ev, ord=1)
        h_od /= np.linalg.norm(h_od, ord=1)
    
    # compute the response
    response = (scp.convolve1d(video, h_ev, axis=2) ** 2) + (scp.convolve1d(video, h_od, axis=2) ** 2)
    points = interest_points(response, num=num_points, threshold=threshold, scale=sigma)
    return points

修改后的MultiscaleDetector

def MultiscaleDetector(detector, video, sigmas, tau, num_points, threshold):
    """
    Multiscale Detector

    Executes a detector at multiple scales. Detector has to be a function that
    takes a video as input, along with other parameters, and returns a list of interest points.

    
    Keyword arguments:
    detector -- function that returns interest points
    video -- input video (y_len, x_len, frames)
    sigmas -- list of scales
    """
    # 预先计算一次tau相关的滤波器,循环中复用
    time = np.linspace(-2*tau, 2*tau, int(4*tau+1))
    omega = 4/tau
    h_ev = np.exp(-time**2/(2*tau**2)) * np.cos(2*np.pi*omega*time)
    h_od = np.exp(-time**2/(2*tau**2)) * np.sin(2*np.pi*omega*time)
    h_ev /= np.linalg.norm(h_ev, ord=1)
    h_od /= np.linalg.norm(h_od, ord=1)
    precomputed_filters = (h_ev, h_od)
    
    # 遍历尺度,传入预计算的滤波器
    points = []
    for sigm in sigmas:
        found = detector(video, sigm, tau, threshold, num_points, precomputed_filters=precomputed_filters)
        points.append(found)

    # filter the points, currently irrelevant
    return points

内容的提问来源于stack exchange,提问作者Stefanos Anagnostou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 02:27:06