实现Lucas-Kanade光流计算的Delphi类

2008-04-09 04:20:43来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

{
作者:刘留
参考文献为:
Jean-Yves Bouguet "Pyramidal Implementation of the Lucas Kanade Feature Tracker Description of the algorithm"
http://www.aivisoft.net/
Geo.Cra[at]gmail[dot]com
}
unit OpticalFlowLK;

interface

uses
Math, Windows, SysUtils, Variants, Classes, Graphics, unitypes, ColorConv;

type

TOpticalFlowLK = class
private
ImageOld, ImageNew: TTripleLongintArray;
ImageGray, dx, dy, dxy: TDoubleLongintArray;
Eigenvalues: TDoubleExtendedArray;
WBPoint: TDoubleBooleanArray;
Height, Width, L, RadioX, RadioY: longint;
procedure CornerDetect(sWidth, sHeight: longint; Quality: extended);
procedure MakePyramid(var Images: TTripleLongintArray; sWidth, sHeight, sL: longint);
public
Frame: TBitmap;
Features: TSinglePointInfoArray;
FeatureCount, SupportCount: longint;
Speed, Radio: extended;
procedure Init(sWidth, sHeight, sL: longint);
procedure InitFeatures(Frames: TBitmap);
procedure CalOpticalFlowLK(Frames: TBitmap);
destructor Destroy; override;
end;

implementation

procedure TOpticalFlowLK.CornerDetect(sWidth, sHeight: longint; Quality: extended);
var
i, j, fi, fj: longint;
a, b, c, sum, MinAccept, MaxEigenvalue: extended;
begin
FeatureCount := 0;
{
下面采用Good Feature To Track介绍的方法
J. Shi and C. Tomasi "Good Features to Track", CVPR 94
}
for i := 1 to sWidth - 2 do
for j := 1 to sHeight - 2 do begin
dx[i, j] := ImageGray[i - 1, j - 1] 2 * ImageGray[i - 1, j] ImageGray[i - 1, j 1]
- (ImageGray[i 1, j - 1] 2 * ImageGray[i 1, j] ImageGray[i 1, j 1]);
dy[i, j] := ImageGray[i - 1, j 1] 2 * ImageGray[i, j 1] ImageGray[i 1, j 1]
- (ImageGray[i - 1, j - 1] 2 * ImageGray[i, j - 1] ImageGray[i 1, j - 1]);
dxy[i, j] := ImageGray[i 1, j - 1] ImageGray[i - 1, j 1]
- (ImageGray[i - 1, j - 1] ImageGray[i 1, j 1]);
end;
{求取Sobel算子的Dx, Dy, Dxy
Dx:
|1 0 -1|
|2 0 -2|
|1 0 -1|
Dy:
|-1 -2 -1|
| 0 0 0|
| 1 2 1|
Dxy
|-1 0 1|
| 0 0 0|
| 1 0 -1|}
MaxEigenvalue := 0;
for i := 2 to sWidth - 3 do
for j := 2 to sHeight - 3 do begin
a := 0; b := 0; c := 0;
for fi := i - 1 to i 1 do
for fj := j - 1 to j 1 do begin
a := a sqr(dx[fi, fj]);
b := b dxy[fi, fj];
c := c sqr(dy[fi, fj]);
end;
a := a / 2; c := c / 2;
Eigenvalues[i, j] := (a c - sqrt((a - c) * (a - c) b * b));
if Eigenvalues[i, j] > MaxEigenvalue then MaxEigenvalue := Eigenvalues[i, j];
end;
{求取矩阵
|∑Dx*Dx ∑Dxy|
M=| |
|∑Dxy ∑Dy*Dy|
的特征值
λ= ∑Dx*Dx ∑Dy*Dy - ((∑Dx*Dx ∑Dy*Dy)^2-4*(∑Dx*Dx * ∑Dy*Dy - ∑Dxy * ∑Dxy))^1/2}
MinAccept := MaxEigenvalue * Quality;
{设置最小允许阀值}

for i := 8 to sWidth - 9 do
for j := 8 to sHeight - 9 do
if Eigenvalues[i, j] > MinAccept then begin
WBPoint[i, j] := true;
Inc(FeatureCount);
end else
WBPoint[i, j] := false;

for i := 8 to sWidth - 9 do
for j := 8 to sHeight - 9 do
if WBPoint[i, j] then begin
sum := Eigenvalues[i, j];
for fi := i - 8 to i 8 do begin
for fj := j - 8 to j 8 do
if sqr(fi - i) sqr(fj - j) <= 64 then
if (Eigenvalues[fi, fj] >= sum) and ((fi <> i) or (fj <> j)) and (WBPoint[fi, fj]) then begin
WBPoint[i, j] := false;
Dec(FeatureCount);
break;
end;
if not WBPoint[i, j] then break;
end;
end;
{用非最大化抑制来抑制假角点}

setlength(Features, FeatureCount); fi := 0;
for i := 8 to sWidth - 9 do
for j := 8 to sHeight - 9 do
if WBPoint[i, j] then begin
Features[fi].Info.X := i;
Features[fi].Info.Y := j;
Features[fi].Index := 0;
Inc(fi);
end;
{输出最终的点序列}
end;

procedure TOpticalFlowLK.Init(sWidth, sHeight, sL: longint);
begin
Width := sWidth; Height := sHeight; L := sL;
setlength(ImageOld, Width, Height, L);
setlength(ImageNew, Width, Height, L);
Frame := TBitmap.Create;
Frame.Width := Width; Frame.Height := Height;
Frame.PixelFormat := pf24bit;
setlength(ImageGray, Width, Height);
setlength(Eigenvalues, Width, Height);
setlength(dx, Width, Height);
setlength(dy, Width, Height);

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:如何知道函数或类型是在哪里定义的

下一篇:NUnit学习笔记之Delphi 2005篇