一种快速求解高斯拉普拉斯函数的方法 [英] A faster approach to Laplacian of Gaussian

查看:21
本文介绍了一种快速求解高斯拉普拉斯函数的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在优化我的代码,以提高图像处理的效率。我的第一个问题是由于vision.VideoFileReaderstep需要很长时间才能打开每个帧。我通过将我的灰度图像压缩成1 RGB帧中的3帧来加速我的代码。这样,我可以使用vid.step()加载1个RGB帧,并有3个导入的帧准备好进行处理。

现在,我的代码在高斯(Log)的拉普拉斯过滤上运行速度很慢。我读到使用函数imfilter可用于执行日志,但它似乎是下一个速率限制步骤。

进一步阅读,似乎imfilter不是速度的最佳选择。表面上,MATLAB引入了LoG function,但它是在R2016b中引入的,不幸的是我正在使用R2016a。

是否有方法可以提高imfilter的速度,或者是否有更好的函数可用于执行日志筛选?

我是否应该调用python以加快进程?

编码:

Hei = gh.Video.reader.info.VideoSize(2);
Wid = gh.Video.reader.info.VideoSize(1);

Log_filter = fspecial('log', filterdot, thresh); % fspecial creat predefined filter.Return a filter.
    % 25X25 Gaussian filter with SD =25 is created.

tic
ii = 1;

bkgd = zeros(Hei,Wid,3);
bkgd(:,:,1) = gh.Bkgd;
bkgd(:,:,2) = gh.Bkgd;
bkgd(:,:,3) = gh.Bkgd;

bkgdmod = reshape(bkgd,720,[]);

while ~isDone(gh.Video.reader)
    frame = gh.readFrame();
    img_temp = double(frame);

    img_temp2 = reshape(img_temp,720,[]);
    subbk = img_temp2 - bkgdmod;

    img_LOG = imfilter(subbk, Log_filter, 'symmetric', 'conv');

    img_LOG =  imbinarize(img_LOG,.002);
    [~, centroids, ~] = gh.Video.blobAnalyser.step(img_LOG);

    toc
end

推荐答案

高斯的拉普拉斯不能直接分成两个一维核。所以imfilter会做完全卷积,成本比较高。但我们可以手动将其分离到更简单的过滤器中。


高斯的拉普拉斯定义为高斯函数的两个二阶导数之和:

LoG = d²/dx² G + d²/dy² G

高斯本身及其导数are separable。因此,可以使用4个1D卷积来计算上述内容,这比单个2D卷积便宜得多,除非内核非常小(例如,如果内核是7x7,那么对于2D内核,我们需要每像素49次乘法和加法,或者对于4 1D内核,每像素需要4*7=28次乘法和加法;这种差异随着内核变大而增大)。计算结果为:

sigma = 3;
cutoff = ceil(3*sigma);
G = fspecial('gaussian',[1,2*cutoff+1],sigma);
d2G = G .* ((-cutoff:cutoff).^2 - sigma^2)/ (sigma^4);
dxx = conv2(d2G,G,img,'same');
dyy = conv2(G,d2G,img,'same');
LoG = dxx + dyy;

如果您确实时间紧张,并且不关心精度,您可以将cutoff设置为2*sigma(对于较小的内核),但这并不理想。


另一种不太精确的方法是以不同方式分隔操作:

LoG * f = ( d²/dx² G + d²/dy² G ) * f
        = ( d²/dx² 𝛿 * G + d²/dy² 𝛿 * G ) * f
        = ( d²/dx^2 𝛿 + d²/dy² 𝛿 ) * G * f

(其中*表示卷积,𝛿表示狄拉克三角洲,卷积相当于乘以1)。d²/dx² 𝛿 + d²/dy² 𝛿运算符并不真正存在于离散世界中,但是您可以采用有限差分近似,这将导致著名的3x3Laplace内核:

[ 1  1  1             [ 0  1  0
  1 -8  1       or:     1 -4  1
  1  1  1 ]             0  1  0 ]

现在我们得到了一个更粗糙的近似,但计算速度更快(2个1D卷积,以及一个普通3x3核的卷积):

sigma = 3;
cutoff = ceil(3*sigma);
G = fspecial('gaussian',[1,2*cutoff+1],sigma);
tmp = conv2(G,G,img,'same');
h = fspecial('laplacian',0);
LoG = conv2(tmp,h,'same'); % or use imfilter

这篇关于一种快速求解高斯拉普拉斯函数的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆