打印本文 打印本文 关闭窗口 关闭窗口
实现Lucas-Kanade光流计算的Delphi类
作者:武汉SEO闵涛  文章来源:敏韬网  点击数2311  更新时间:2009/4/23 18:26:16  文章录入:mintao  责任编辑:mintao
1 + Images[0, jj - 1, k - 1] shl 1 + Images[0, jj + 1, k - 1] shl 1 +
        Images[0, jj - 1, k - 1] + Images[1, jj - 1, k - 1] + Images[0, jj + 1, k - 1] + Images[1, jj + 1, k - 1]) shr 4;
      Images[nWidth - 1, j, k] := (Images[oWidth - 1, jj, k - 1] shl 2 +
        Images[oWidth - 2, jj, k - 1] shl 1 + Images[oWidth - 1, jj, k - 1] shl 1 + Images[oWidth - 1, jj - 1, k - 1] shl 1 + Images[oWidth - 1, jj + 1, k - 1] shl 1 +
        Images[oWidth - 2, jj - 1, k - 1] + Images[oWidth - 1, jj - 1, k - 1] + Images[oWidth - 2, jj + 1, k - 1] + Images[oWidth - 1, jj + 1, k - 1]) shr 4;
    end;
    {处理左右边}
    Images[0, 0, k] := (Images[0, 0, k - 1] shl 2 +
      Images[0, 0, k - 1] shl 1 + Images[1, 0, k - 1] shl 1 + Images[0, 0, k - 1] shl 1 + Images[0, 1, k - 1] shl 1 +
      Images[0, 0, k - 1] + Images[1, 0, k - 1] + Images[0, 1, k - 1] + Images[1, 1, k - 1]) shr 4;
    {处理左上点}
    Images[0, nHeight - 1, k] := (Images[0, oHeight - 1, k - 1] shl 2 +
      Images[0, oHeight - 1, k - 1] shl 1 + Images[1, oHeight - 1, k - 1] shl 1 + Images[0, oHeight - 2, k - 1] shl 1 + Images[0, oHeight - 1, k - 1] shl 1 +
      Images[0, oHeight - 2, k - 1] + Images[1, oHeight - 2, k - 1] + Images[0, oHeight - 1, k - 1] + Images[1, oHeight - 1, k - 1]) shr 4;
    {处理左下点}
    Images[nWidth - 1, 0, k] := (Images[oWidth - 1, 0, k - 1] shl 2 +
      Images[oWidth - 2, oHeight - 1, k - 1] shl 1 + Images[oWidth - 1, oHeight - 1, k - 1] shl 1 + Images[oWidth - 1, oHeight - 1, k - 1] shl 1 + Images[oWidth - 1, oHeight - 1, k - 1] shl 1 +
      Images[oWidth - 2, oHeight - 1, k - 1] + Images[oWidth - 1, oHeight - 1, k - 1] + Images[oWidth - 2, oHeight - 1, k - 1] + Images[oWidth - 1, oHeight - 1, k - 1]) shr 4;
    {处理右上点}
    Images[nWidth - 1, nHeight - 1, k] := (Images[oWidth - 1, oHeight - 1, k - 1] shl 2 +
      Images[oWidth - 2, oHeight - 1, k - 1] shl 1 + Images[oWidth - 1, oHeight - 1, k - 1] shl 1 + Images[oWidth - 1, oHeight - 2, k - 1] shl 1 + Images[oWidth - 1, oHeight - 1, k - 1] shl 1 +
      Images[oWidth - 2, oHeight - 2, k - 1] + Images[oWidth - 1, oHeight - 2, k - 1] + Images[oWidth - 2, oHeight - 1, k - 1] + Images[oWidth - 1, oHeight - 1, k - 1]) shr 4;
    {处理右下点}
  end;
end;

procedure TOpticalFlowLK.InitFeatures(Frames: TBitmap);
var
  i, j: longint;
  Line: pRGBTriple;
begin
  SetStretchBltMode(Frame.Canvas.Handle, Stretch_Halftone);
  StretchBlt(Frame.Canvas.Handle, 0, 0, Width, Height, Frames.Canvas.Handle, 0, 0, Frames.Width, Frames.Height, SrcCopy);
  for i := 0 to Height - 1 do begin
    Line := Frame.ScanLine[i];
    for j := 0 to Width - 1 do begin
      ImageOld[j, i, 0] := (Line^.rgbtBlue * 11 + Line^.rgbtGreen * 59 + Line^.rgbtRed * 30) div 100;
      ImageGray[j, i] := ImageOld[j, i, 0];
      Inc(Line);
    end;
  end;
  {初始化金字塔图像第一层ImageOld[x,y,0]}
  MakePyramid(ImageOld, Width, Height, L);
  {生成金字塔图像}
  CornerDetect(Width, Height, 0.01);
  {进行强角点检测}
end;

procedure TOpticalFlowLK.CalOpticalFlowLK(Frames: TBitmap);
var
  i, j, fi, fj, k, ll, m, dx, dy, gx, gy, px, py, kx, ky, ed, edc, nWidth, nHeight: longint;
  nx, ny, vx, vy, A, B, C, D, E, F, Ik: extended;
  Ix, Iy: TDoubleExtendedArray;
  Line: pRGBTriple;
  Change: boolean;
begin
  SetStretchBltMode(Frame.Canvas.Handle, Stretch_Halftone);
  StretchBlt(Frame.Canvas.Handle, 0, 0, Width, Height, Frames.Canvas.Handle, 0, 0, Frames.Width, Frames.Height, SrcCopy);
  for i := 0 to Height - 1 do begin
    Line := Frame.ScanLine[i];
    for j := 0 to Width - 1 do begin
      ImageNew[j, i, 0] := (Line^.rgbtBlue * 11 + Line^.rgbtGreen * 59 + Line^.rgbtRed * 30) div 100;
      Inc(Line);
    end;
  end;
  {初始化金字塔图像第一层ImageNew[x,y,0]}
  MakePyramid(ImageNew, Width, Height, L);
  {生成金字塔图像}
  setlength(Ix, 15, 15); setlength(Iy, 15, 15);
  {申请差分图像临时数组}
  for m := 0 to FeatureCount - 1 do begin
    {算法细节见:
    Jean-Yves Bouguet "Pyramidal Implementation of the Lucas Kanade Feature Tracker Description of the algorithm"}
    gx := 0; gy := 0;
    for ll := L - 1 downto 0 do begin
      px := Features[m].Info.X shr ll;
      py := Features[m].Info.Y shr ll;
      {对应当前金字塔图像的u点:u[L]:=u/2^L}
      nWidth := Width shr ll; nHeight := Height shr ll;
      A := 0; B := 0; C := 0;
      for i := max(px - 7, 1) to min(px + 7, nWidth - 2) do
        for j := max(py - 7, 1) to min(py + 7, nHeight - 2) do begin
          fi := i - px + 7; fj := j - py + 7;
          Ix[fi, fj] := (ImageOld[i + 1, j, ll] - ImageOld[i - 1, j, ll]) / 2;
          Iy[fi, fj] := (ImageOld[i, j + 1, ll] - ImageOld[i, j - 1, ll]) / 2;
          A := A + Ix[fi, fj] * Ix[fi, fj]; B := B + Ix[fi, fj] * Iy[fi, fj];
          C := C + Iy[fi, fj] * Iy[fi, fj];
        end;
      {计算2阶矩阵G:
        |Ix(x,y)*Ix(x,y)  Ix(x,y)*Iy(x,y)|
      ∑|Ix(x,y)*Iy(x,y)  Iy(x,y)*Iy(x,y)|}
      D := A * C - B * B;
      vx := 0; vy := 0; dx := 0; dy := 0;
      if abs(D) > 1E-8 then begin
        for k := 1 to 10 do begin
          E := 0; F := 0;
          for i := max(px - 7, 1) to min(px + 7, nWidth - 2) do
            for j := max(py - 7, 1) to min(py + 7, nHeight - 2) do begin
              fi := i - px + 7; fj := j - py + 7;
              kx := i + gx + dx; ky := j + gy + dy;
              if kx < 0 then kx := 0; if kx > nWidth - 1 then kx := nWidth - 1;
              if ky < 0 then ky := 0; if ky > nHeight - 1 then ky := nHeight - 1;
              Ik := ImageOld[i, j, ll] - ImageNew[kx, ky, ll];
              E := E + Ik * Ix[fi, fj];
              F := F + Ik * Iy[fi, fj];
            end;
          {计算2x1阶矩阵b:
            |Ik(x,y)*Ix(x,y)|
          ∑|Ik(x,y)*Iy(x,y)|}
          nx := (C * E - B * F) / D;
          ny := (B * E - A * F) / (-D);
          {计算η=G^-1*b}
          vx := vx + nx; vy := vy + ny;
          dx := trunc(vx); dy := trunc(vy);
          {得到相对运动向量d}
        end;
      end;
      gx := (gx + dx) shl 1; gy := (gy + dy) shl 1;
      {得到下一层的预测运动向量g}
    end;
    gx := gx div 2; gy := gy div 2;
    px := px + gx; py := py + gy;
    Features[m].Info.X := px;
    Features[m].Info.Y := py;
    Features[m].Vector.X := gx;
    Features[m].Vector.Y := gy;
    if (px > Width - 1) or (px < 0) or (py > Height - 1) or (py < 0) then Features[m].Index := 1;
    {失去特征点处理}
  end;

  for k := 0 to L - 1 do begin
    nWidth := Width shr k; nHeight := Height shr k;
    for i := 0 to nWidth - 1 do
      for j := 0 to nHeight - 1 do
        ImageOld[i, j, k] := ImageNew[i, j, k];
  end;
  {复制J到I}
  repeat
 &nbs

上一页  [1] [2] [3]  下一页

打印本文 打印本文 关闭窗口 关闭窗口