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

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

【问题讨论】:

    标签: computer-vision opticalflow


    【解决方案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
      

      【讨论】:

        猜你喜欢
        • 2022-06-26
        • 1970-01-01
        • 2023-04-03
        • 2018-05-06
        • 1970-01-01
        • 2021-09-26
        • 1970-01-01
        • 2012-06-17
        • 2021-07-27
        相关资源
        最近更新 更多