zoukankan      html  css  js  c++  java
  • 运动物体检测——光流法(摄像机固定)

    前面的一篇文章谈了高斯背景模型在运动物体检测中的应用。本文主要讨论另一种方法——光流法。与高斯背景模型的方法不同,光流法可以用于摄像机固定和摄像机运动的情形,但本文只就摄像机固定的情况进行讨论,即不涉及摄像机运动预测问题。

    光流法的介绍

    在空间中,运动可以用运动场描述。而在一个图像平面上,物体的运动往往是通过图像序列中不同图象灰度分布的不同体现的。从而,空间中的运动场转移到图像上就表示为光流场,光流场反映了图像上每一点灰度的变化趋势。

    光流可以看作带有灰度的像素点在图像平面运动产生的瞬时速度场。下面我们推导光流方程:

    假设E(x,y,t)为(x,y)点在时刻t的灰度(照度)。设t+dt时刻该点运动到(x+dx,y+dy)点,他的照度为E(x+dx,y+dy,t+dt)。我们认为,由于对应同一个点,所以

    E(x,y,t) = E(x+dx,y+dy,t+dt)   —— 光流约束方程

    将上式右边做泰勒展开,并令dt->0,则得到:Exu+Eyv+Et = 0,其中:

    Ex = dE/dx   Ey = dE/dy   Et = dE/dt   u = dx/dt   v = dy/dt

    上面的Ex,Ey,Et的计算都很简单,用离散的差分代替导数就可以了。光流法的主要任务就是通过求解光流约束方程求出u,v。但是由于只有一个方程,所以这是个病态问题。所以人们提出了各种其他的约束方程以联立求解。但是由于我们用于摄像机固定的这一特定情况,所以问题可以大大简化。

    摄像机固定的情形

    在摄像机固定的情形下,运动物体的检测其实就是分离前景和背景的问题。我们知道对于背景,理想情况下,其光流应当为0,只有前景才有光流。所以我们并不要求通过求解光流约束方程求出u,v。我么只要求出亮度梯度方向的速率就可以了,即求出sqrt(u*u+v*v)。

    而由光流约束方程可以很容易求到梯度方向的光流速率为 V = abs(Et/sqrt(Ex*Ex+Ey*Ey))。这样我们设定一个阈值T。

    V(x,y) > T 则(x,y)是前景 ,反之是背景

    C++实现

    在实现摄像机固定情况的光流法时,需要有两帧连续的图像,下面的算法针对RGB24格式的图像计算光流:

    void calculate(unsigned char* buf)
     {
      int Ex,Ey,Et;
      int gray1,gray2;
      int u;
      int i,j;
      memset(opticalflow,0,width*height*sizeof(int));
      memset(output,255,size);
      for(i=2;i<height-2;i++){
       for(j=2;j<width-2;j++){
        gray1 = int(((int)(buf[(i*width+j)*3])
         +(int)(buf[(i*width+j)*3+1])
         +(int)(buf[(i*width+j)*3+2]))*1.0/3);
        gray2 = int(((int)(prevframe[(i*width+j)*3])
         +(int)(prevframe[(i*width+j)*3+1])
         +(int)(prevframe[(i*width+j)*3+2]))*1.0/3);
        Et = gray1 - gray2;
        gray2 = int(((int)(buf[(i*width+j+1)*3])
         +(int)(buf[(i*width+j+1)*3+1])
         +(int)(buf[(i*width+j+1)*3+2]))*1.0/3);
        Ex = gray2 - gray1;
        gray2 = int(((int)(buf[((i+1)*width+j)*3])
         +(int)(buf[((i+1)*width+j)*3+1])
         +(int)(buf[((i+1)*width+j)*3+2]))*1.0/3);
        Ey = gray2 - gray1;
        Ex = ((int)(Ex/10))*10;
        Ey = ((int)(Ey/10))*10;
        Et = ((int)(Et/10))*10;
        u = (int)((Et*10.0)/(sqrt((Ex*Ex+Ey*Ey)*1.0))+0.1);
        opticalflow[i*width+j] = u;
        if(abs(u)>10){
         output[(i*width+j)*3] = 0;
         output[(i*width+j)*3+1] = 0;
         output[(i*width+j)*3+2] = 0;
        }
       }
      }
      memcpy(prevframe,buf,size);
     }

  • 相关阅读:
    print 参数
    note
    action标签的属性说明
    Cannot load JDBC driver class 'oracle.jdbc.driver.OracleDriver'
    润乾报表
    javax.naming.NameNotFoundException: Name ZKING is not bound in this Context 的问题
    Myeclipse2013安装svn插件
    Myeclipse2013的优化设置
    Myeclipse解析.classpath文件
    Struts
  • 原文地址:https://www.cnblogs.com/ywsoftware/p/4434075.html
Copyright © 2011-2022 走看看