![](/img/trans.png)
[英]Most efficient way to generate Histograms of Oriented Optical Flow (HOOF) in python
[英]Efficiently calculate optical flow parameters - MATLAB
我正在从Horn&Schunck论文中实现光流的偏导数方程。 然而,即使对于相对较小的图像(320x568),也需要令人沮丧的长时间(~30-40秒)才能完成。 我假设这是由于320 x 568 = 181760循环迭代,但我无法找到一种更有效的方法来做到这一点(缺少MEX文件)。
有没有办法将其转化为更高效的MATLAB操作(也许是卷积)? 我可以弄清楚如何做它作为It
的卷积而不是Ix
和Iy
。 我也考虑过矩阵移位,但这只适用于It
,据我所知。
有没有其他人遇到这个问题并找到了解决方案?
我的代码如下:
function [Ix, Iy, It] = getFlowParams(img1, img2)
% Make sure image dimensions match up
assert(size(img1, 1) == size(img2, 1) && size(img1, 2) == size(img2, 2), ...
'Images must be the same size');
assert(size(img1, 3) == 1, 'Images must be grayscale');
% Dimensions of original image
[rows, cols] = size(img1);
Ix = zeros(numel(img1), 1);
Iy = zeros(numel(img1), 1);
It = zeros(numel(img1), 1);
% Pad images to handle edge cases
img1 = padarray(img1, [1,1], 'post');
img2 = padarray(img2, [1,1], 'post');
% Concatenate i-th image with i-th + 1 image
imgs = cat(3, img1, img2);
% Calculate energy for each pixel
for i = 1 : rows
for j = 1 : cols
cube = imgs(i:i+1, j:j+1, :);
Ix(sub2ind([rows, cols], i, j)) = mean(mean(cube(:, 2, :) - cube(:, 1, :)));
Iy(sub2ind([rows, cols], i, j)) = mean(mean(cube(2, :, :) - cube(1, :, :)));
It(sub2ind([rows, cols], i, j)) = mean(mean(cube(:, :, 2) - cube(:, :, 1)));
end
end
2D convolution
是这里的方式,也可以在问题中预测,以取代那些重mean/average
计算。 此外,这些迭代差异可以用MATLAB的diff
代替。 因此,结合所有这些,矢量化实施将是 -
%// Pad images to handle edge cases
img1 = padarray(img1, [1,1], 'post');
img2 = padarray(img2, [1,1], 'post');
%// Store size parameters for later usage
[m,n] = size(img1);
%// Differentiation along dim-2 on input imgs for Ix calculations
df1 = diff(img1,[],2)
df2 = diff(img2,[],2)
%// 2D Convolution to simulate average calculations & reshape to col vector
Ixvals = (conv2(df1,ones(2,1),'same') + conv2(df2,ones(2,1),'same'))./4;
Ixout = reshape(Ixvals(1:m-1,:),[],1);
%// Differentiation along dim-1 on input imgs for Iy calculations
df1 = diff(img1,[],1)
df2 = diff(img2,[],1)
%// 2D Convolution to simulate average calculations & reshape to col vector
Iyvals = (conv2(df1,ones(1,2),'same') + conv2(df2,ones(1,2),'same'))./4
Iyout = reshape(Iyvals(:,1:n-1),[],1);
%// It just needs elementwise diffentiation between input imgs.
%// 2D convolution to simulate mean calculations & reshape to col vector
Itvals = conv2(img2-img1,ones(2,2),'same')./4
Itout = reshape(Itvals(1:m-1,1:n-1),[],1)
这种矢量化实现的好处是:
更快的方法,结果改善(在我观察到的情况下)如下:
function [Ix, Iy, It] = getFlowParams(imNew,imPrev)
gg = [0.2163, 0.5674, 0.2163];
f = imNew + imPrev;
Ix = f(:,[2:end end]) - f(:,[1 1:(end-1)]);
Ix = conv2(Ix,gg','same');
Iy = f([2:end end],:) - f([1 1:(end-1)],:);
Iy = conv2(Iy,gg ,'same');
It = 2*conv2(gg,gg,imNew - imPrev,'same');
这样可以优雅地处理边界情况。
我将其作为光流工具箱的一部分 ,您可以在其中轻松实时查看H&S,Lucas Kanade等。 在工具箱中,该函数称为grad3D.m。 您可能还想在同一工具箱中查看grad3Drec.m,这会增加简单的时间模糊。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.