为啥光流方程定义不足?

Posted

技术标签:

【中文标题】为啥光流方程定义不足?【英文标题】:Why optical flow equation is under defined?为什么光流方程定义不足? 【发布时间】:2015-04-05 12:35:01 【问题描述】:

我是计算机视觉的新手,在阅读光流主题时,我有一个概念上的疑问。 为什么不能通过将两个连续帧中像素的 x 和 y 值之间的差值除以两帧之间的时间来计算光流? 例如,图像中的像素在 2 个连续帧中从 (0,0) 移动到 (1,1),这可以使用亮度恒定性假设进行匹配。通过知道帧速率,我们可以找出 u 和 v。

【问题讨论】:

【参考方案1】:

通过查看http://en.m.wikipedia.org/wiki/Optical_flow 中的 Estimation 部分,您可以在数学上看到它的约束不足

这被称为光圈问题。您可以在此 google 上进行更多讨论,或查看 http://en.m.wikipedia.org/wiki/Motion_perception#The_aperture_problem 以获取动画示例。

【讨论】:

【参考方案2】:

我用参考here 回答了这个问题,然后因为它只是一个链接而被删除。我分享这段代码的原因是因为它提供了一种交互式方式来获得关于光圈问题的直觉。我提供链接的原因是因为代码大小......但如果这是编辑想要它的方式,那么就这样吧,在这条消息的末尾找到整个函数。 Matlab中最简单的函数使用如下:

ApertureIllustration;

...我只想通过链接分享的完整代码:

% Author: Stefan Karlsson, Josef Bigun, 2014

function ApertureIllustration(type)
%interactive visualization of the aperture problem in optical flow
%estimation. This script animates a pattern of horizontal smooth bars within 
% the support of a large disk. The pattern is in a circular motion pattern.
% a smaller apperture is present in the middle of the image. The
% only view the user gets is through the aperture, except for a periodic
% reveal of the scene
% input "type":
% 'regular' , [default] circular aperture, single motion
% 'barber'  , rectangular aperture, barberpole illusion
% 'multiple', circular aperture, multiple motions
% 'color'   , circular aperture, multiple motions in seperate color channels
%%%%%%%%%%%%
% The script supports the following interface:
% MOUSE: 
% click to enable mouse move of aperture, mouse scroll to change aperture
% radius
% KEYBOARD:
% Arrow Keys: move the aperture around
% Q/A : Radius of the aperture
% W/S : the fuzziness of the boundary(higher values makes it Gaussian-like)
%%%%%%%
if nargin < 1
    type = 'regular';end
if ~isnumeric(type)
    switch lower(type)
        case 'regular'
            type = 1;
        case 'barber'
            type = 2;
        case 'multiple'
            type = 3;
        case 'color'
            type = 4;
    end
end
%widht and height of the image
w = 250;
h = 250;
innerRadius = 0.3; %initial radius of aperture
%initial position of aperture, x and y:
innerPx = 0;
innerPy = 0;
minFuz  = 0.01;
%initial fuzziness of aperture:
if type == 2
    innerFuz = minFuz;
else
    innerFuz = 1/10; 
end
fuz = 1/20;      %fuzziness of the moving pattern
%limits in the image are in [-1,+1] for both x and y:
xlims = linspace(-1,1,w);
ylims = linspace(-1,1,h);
[x,y] = meshgrid(xlims,ylims);
p  = linspace(0,2*pi,200);   %used for painting the red boundary of aperture

%When linesmoothing option is on, there is a small bug in the offset of the
%position of linesegments. Fix this with the following added values
bugXVal = (xlims(2)-xlims(1))/2;
bugYVal = (ylims(2)-ylims(1))/2;

%keep track of mouse clicked:
bHasClicked = 0;
%create figure, set up callback functions:
hFig = figure('WindowKeyPressFcn',@localKeyFunc,...
              'WindowButtonDownFcn', @localMousepress); 
hold on
%create the graphics objects, store handles
if type < 4
    hIm = imagesc(xlims, ylims,x,[0,1]);colormap gray(256);
else
    hIm = imagesc(xlims, ylims,zeros([size(x),3]));
end
if type ~= 2
    hCirc = plot(innerRadius*sin(p)-innerPx,innerRadius*cos(p)-innerPy,...
                 'color',[0.6 0.2 0.2],'LineSmoothing','on');
end

axis off;axis image;

t    = 0;  %simulation time
tInc = 0.1; %time increment, simulation
targetFramerate = 15; %target framerate, in real-world time

%as long as the user hasnt shut down the figure, loop:
while ishandle(hFig)
    tic;  %time every iteration to control framerate
    %screener will hold the "characterisitc function" of the aperture:
if type ~= 2
    screener = sig((innerRadius-0.01)-sqrt((x-innerPx).^2+(y-innerPy).^2),innerFuz);
else
    screener = sig(x-innerPx+innerRadius,innerFuz).*sig(-(x-innerPx-innerRadius),innerFuz).*...
               sig(y-innerPy+innerRadius*2  ,innerFuz).*sig(-(y-innerPy-innerRadius*2  ),innerFuz);
end
    t = t+ tInc;
    %the update equation: sigmoidal function for disk boundaries,
    %trigonometric tricks for slowly varying bars
    %centre of the moving pattern is at (cX,xY)
    if type <= 2
        cX = 0.15*cos(t);     
        cY = 0.15*sin(t);
    else % type > = 3
        cX = 0;
        cY = 0.15*sin(t);
    end
    if type < 4
        im = sig(0.84^2-(x-cX).^2-(y-cY).^2,fuz).*(cos(40*(sin(t/100)*(x-cX)+cos(t/100)*(y-cY)))+1)/2;
    else
        im(:,:,2) = sig(0.84^2-(x-cX).^2-(y-cY).^2,fuz).*(cos(40*(sin(t/100)*(x-cX)+cos(t/100)*(y-cY)))+1)/2;
    end
    if type > 2
        t2 = -t-100*pi/2;
%         t2 = t;
        cX = 0.15*cos(t);     
        cY = 0;
%         cX = 0.15*cos(t2);     %centre of the moving pattern is at (cX,xY)
%         cY = 0.15*sin(t2);
        if type ==3
%             newIm = (newIm + backWeight*(250-newIm).*(iix>0)); %apply the background, fixed with hard boundary
            im = (im + 0.7*ed(im).*(1-im).*...
             sig(0.84^2-(x-cX).^2-(y-cY).^2,fuz).*(cos(40*(sin(t2/100)*(x-cX)+cos(t2/100)*(y-cY)))+1)/2);

        else %type ==4
            im(:,:,3) = (1-im(:,:,2)).*...
             sig(0.84^2-(x-cX).^2-(y-cY).^2,fuz).*(cos(40*(sin(t2/100)*(x-cX)+cos(t2/100)*(y-cY)))+1)/2;
        end
    end

    %alpha is used for the periodical unveiling of the full motion pattern
    if type <=2
        alpha =  max(min(((-0.8- 1.55*sin(t*0.35))/2), 0.35),0);
    else % type >=3
        alpha =  max(min(((1.5- 1.55*sin((t+45*tInc)*0.25))/2), 0.35),0);
    end
    if type < 4
        if type == 2
            im = alpha*im + (1-alpha)*(screener.*im + (1 - screener)/2);
        else
            im = alpha*im + (1-alpha)*screener.*im;
        end
    else
        im = alpha*im + (1-alpha)*bsxfun(@times,screener,im);
    end
    %update graphics:
    set(hIm,'CData',im);
if type ~= 2    
    set(hCirc,'XData',(innerRadius-bugXVal)*sin(p)+innerPx+bugXVal, ...
              'YData',(innerRadius-bugYVal)*cos(p)+innerPy+bugYVal);
end
    %restrict frame rate:
    timeToSpare = (1/targetFramerate) - toc; 
    pause(  max(timeToSpare  , 1/100)  ); 
end

%%%%%% nested helper functions
% sigmoidal function for fuzzy rendering:
function out=sig(x,fuzziness)
if (fuzziness == 0)
    out = x > 0;
else
    out= (1+erf(x./fuzziness))/2;
end
end
%%% keyboard event handler, callback function
function localKeyFunc(~,evnt)
switch evnt.Key,
  case 'q', innerRadius = innerRadius +0.01;
  case 'a', innerRadius = max(innerRadius -0.01,0.06);
  case 'w', innerFuz = innerFuz +0.005;
  case 's', innerFuz = max(innerFuz -0.005,minFuz);
  case 'downarrow' , innerPy = max(-1,innerPy -0.02);
  case 'uparrow'   , innerPy = min(1,innerPy +0.02);
  case 'rightarrow', innerPx = min(1,innerPx +0.02);
  case 'leftarrow' , innerPx = max(-1,innerPx -0.02);
end
end

%%%mouse press event handler
function localMousepress(~,~)
mousePos=get(gca,'CurrentPoint');
if max(max(abs(mousePos(1,:))))<1.1
    innerPy = mousePos(1,2);
    innerPx = mousePos(1,1);
    if ~bHasClicked
        set (hFig, 'WindowButtonMotionFcn', @mouseMove,'WindowScrollWheelFcn',@mouseScroll);
        bHasClicked = 1;
    else
        set (hFig, 'WindowButtonMotionFcn', '','WindowScrollWheelFcn','');
        bHasClicked = 0;    
    end
end
end

%%%mouse scroll event handler, activated on click
function mouseScroll(~,callbackdata)
   innerRadius = max(innerRadius +0.02*callbackdata.VerticalScrollCount,0.06);
end 

%%%mouse move event handler, activated on click
function mouseMove (~, ~)
mousePos=get(gca,'CurrentPoint');
if max(max(abs(mousePos(1,:))))<1.1
    innerPy = mousePos(1,2);
    innerPx = mousePos(1,1);
end
end

% shadowing function for object partial occlusion. Based on the gradient 
% magnitude, not physically justified, just a visualization hack really.
function out = ed(f)
gg = [0.2163,   0.5674,   0.2163];
dx = f(:,[  2:end end ]  ) - f(:,[1 1:(end-1) ]  ) ;
dx = conv2(dx,gg' ,'same');

dy = f(  [  2:end end ],:) - f(  [1 1:(end-1) ],:);
dy = conv2(dy,gg,'same');

out = ((dx.^2 + dy.^2)/8+1).^(-25);
end
end

【讨论】:

以上是关于为啥光流方程定义不足?的主要内容,如果未能解决你的问题,请参考以下文章

梯度下降和正规方程没有给出相同的结果,为啥?

为啥TensorFlow要重新实现很多数学方程?

光流:时间导数到底是啥?

差分方程的零输入响应与零状态响应

目标跟踪之Lukas-Kanade光流法

为啥某些方程中的某些常数的符号在我们将其赋值为 1 时会被消除?