在读研期间,由于导师与水环研究生水生物有项目交叉,我主要研究视频跟踪技术。用来提取鱼类的轨迹以及鱼类的微动作。其中鱼类的轨迹提取我已做了两部分工作,二维视频跟踪,提取鱼类的轨迹;另一部分工作是重建三维鱼类游动轨迹。鱼类微特征提取还没有动工(惭愧)。----------
Two-dimensional video tracking
在做这项工作之前我们花费了很大的力气去获取实验数据。购买了三个汉邦高科的摄像头,水箱,摄像头支架等。搭建好实验装置。(由于主要说视频跟踪,具体与鱼相关的就带过)注意:1、摄像头要固定住,这样拍摄的视频帧才有固定的摄像机坐标,最后才好转换成统一的现实坐标。2、获取的视频尽量减少运动背景的干扰,熟悉前景检测的人都应该知道。3、注意光线,不要太暗了,也不要太刺眼,有光圈亮点。
Foreground tracking algorithm Process
首先都是查看文献来着,大概看了20多篇文献资料。其实起指导作用的文献还是只有那么几篇。我就列出来:[1].Zhang Z.A flexible new technique for camera calibration[J].Transactions on Pattern Analysis and Machine Intelligence,2000(11):1330-1334.[2]Olivier Barnich, Marc Van Droogenbroeck. ViBe: A universal background subtraction algorithm for video sequences[J]. IEEE Transactions on Image Processing, 20(6):1709-1724, June 2011.[3]Robust Fragments-based Tracking using the Integral Histogram.还有很多文献,就不一一列出来了。对我用C++来实现这些算法的启蒙文献应该是文献[3]:第[3]篇文献:是一种改进的模板匹配方法,把模板和目标都分成多个字块,然后分别匹配,这样可以避免部分被遮挡就丢失目标的情况。(有源码可以查看)文献[1]很经典,我是直接用的,用来消除摄像头的扭曲形变。文献[2]是我们方法的基础,我直接将它的源码移植过来了。也许你们会问我做了什么,都是别人的东西,确实,是这样的。
My job.
1、主要是从前景检测的结果中用一种更优的方法找出鱼类所在的位置。能够更加精确、实时的提取鱼类轨迹。2、将轨迹做平滑处理,使用了基于平方的方法,效果很不错。3、开发二维轨迹跟踪软件,确实只是小软件,我只用了3个星期不到的时间做完,当然还有很多需要完善的地方。其实也有之前做三维鱼类轨迹跟踪系统的基础。很多复用了之前的代码。
Two-dimensional estimation tracking algorithm:
Original frame, de-distortion->vibe-> local search, two-dimensional trajectory
Vibe algorithm is not my original, is already very mature algorithm, so not detailed description. Paste out its source bar, I hope you can learn directly from learning.
Vibe.hxx after two packages:
#ifndef _vibe_hxx_#define _VIBE_HXX_classVIBE { Public: VIBE (); ~vibe ();voidInitialize ();voidUpdate ();inline voidSetcurrentframe (unsigned Char* i) {_image = i;}inline voidSetsegmentmap (unsigned Char* i) {_segmap = i;}inline voidSetframewidth (intW) {_framewidth = W;}inline voidSetframeheight (inth) {_frameheight = h;}inline voidSetframewidthstrip (ints) {_framewidthstrip = s;}inline BOOLIsinitilized () {return_samples; }Private:intGetrandomsample ();intGetrandomsubsample ();intGetrandomneightxcoordinate (intx);intGetrandomneightycoordinate (inty);Private:int_framewidth;int_frameheight;int_framewidthstrip;int_sphereradius;int_pixelsamples;int_backgroundthreshold;int_subsampling;int_borderwidth;unsigned Char* _IMAGE;unsigned Char* _SEGMAP;unsigned Char* * _samples;};#endif
#include "stdafx.h"#include <assert.h>#include <stdlib.h>#include <time.h>#include <math.h>#include "vibe.hxx"#define N#define R#define ZMIN 3#define PHIVibe::vibe () {_framewidth =0; _frameheight =0; _framewidthstrip =0; _sphereradius = R; _pixelsamples = N; _backgroundthreshold = Zmin; _subsampling = PHI; _image =0; _segmap =0; _samples =0; _borderwidth =0;} Vibe::~vibe () {if(_samples) { for(inti =0; i < _pixelsamples; i + +)if(_samples[i]) {Delete[] _samples[i]; _samples[I] =0; }Delete[] _samples; _samples =0; }}void vibe::initialize () {Assert (_framewidth <1|| _frameheight <1|| _framewidthstrip <1) ||"Please set frame info for initialize...\n");Srand((int) Time(0)); _samples = new unsigned char*[_pixelsamples]; for(inti =0; i < _pixelsamples; i + +) _samples[i] = new unsigned char[_frameheight * _framewidthstrip];intTQ = Sqrtf (_pixelsamples); _borderwidth = TQ/2; for(int y= _borderwidth;y< _frameheight-_borderwidth;y++ ) { for(int x= _borderwidth;x< _framewidth-_borderwidth;x++ ) {intc =0; for(inti =-_borderwidth; I <= _borderwidth && c < _pixelsamples; i + +) { for(intj =-_borderwidth; J <= _borderwidth && C < _pixelsamples; J + +)if(C < _pixelsamples-_backgroundthreshold)*(_samples[C + +] +y* _framewidthstrip +x) =*(_image + (y+ i) * _framewidthstrip + (x+ j));Else *(_samples[C + +] +y* _framewidthstrip +x) =*(_image +y* _framewidthstrip +x); }}}}void Vibe::update () { for(int x=0;x< _framewidth;x++ ) { for(int y=0;y< _frameheight;y++ ) {intCount =0,Index=0, dist =0;if(y< _borderwidth | |x< _borderwidth | |x>= _framewidth-_borderwidth | |y>= _frameheight-_borderwidth) {*(_segmap +y* _framewidthstrip +x) =0;Continue; } while(Count < _backgroundthreshold &&Index< _pixelsamples) {dist =ABS(*(_image +y* _framewidthstrip +x) -*(_samples[Index] +y* _framewidthstrip +x) );if(Dist < _sphereradius) count + +;Index++; }if(Count >= _backgroundthreshold) {*(_segmap +y* _framewidthstrip +x) =0;int Rand= Getrandomsubsample ();//if(Rand==0)if(Rand<6) {Rand= Getrandomsample ();*(_samples[Rand] +y* _framewidthstrip +x) =*(_image +y* _framewidthstrip +x); }Rand= Getrandomsubsample ();//if(Rand==0)if(Rand<6) {intXG, YG; XG = Getrandomneightxcoordinate (x); YG = Getrandomneightycoordinate (y);Rand= Getrandomsample ();*(_samples[Rand] + YG * _framewidthstrip + xg) =*(_image +y* _framewidthstrip +x); } }Else{*(_segmap +y* _framewidthstrip +x) =255; } } }}intVibe::getrandomsample () {intval = _pixelsamples *1.0*Rand()/Rand_max;if(val = = _pixelsamples)returnVal-1;Else returnVal;}intVibe::getrandomsubsample () {intval = _subsampling *1.0*Rand()/Rand_max;if(val = = _subsampling)returnVal-1;Else returnVal;}intVibe::getrandomneightxcoordinate (int x){intval =4*1.0*Rand()/Rand_max-2;if(x+ val >= _framewidth | |x+ Val <0)return x;Else return x+ val;}intVibe::getrandomneightycoordinate (int y){intval =4*1.0*Rand()/Rand_max-2;if(y+ val >= _framewidth | |y+ Val <0)return y;Else return y+ val;}
Call this vibe method of this class:
VIBE VIBE;Vibe. Setframewidth(Image->width);Vibe. Setframeheight(Image->height);Vibe. Setframewidthstrip(Segimage->widthstep);Vibe. Setsegmentmap((unsigned char*) (segimage->imagedata));Vibe. Setcurrentframe((unsigned char*) grayimage->imagedata);Vibe. Initialize();...//update vibe. Setcurrentframe((unsigned char*) grayimage->imagedata);Vibe. Update();
Do not use more to look at the source of the class. "More Toss", my mentor's exact words.
Local Search and smooth processing
Set K to the number of frames, R is the search radius, and P (x, y) is the pixel value at (x, y). Set the frame to the coordinates (XK,YK), you can get the position of frame k+1:
Smoothing Processes:
Set the width of the smoothing window to W1, and the weight of each frame in the window is:
The principle is the square of the current position distance of each bureau, the farthest is 1^2, ..., the current maximum 2^k
Smoothing Results:
Effect Show:
Vibe results:
Local Search:
Trace results:
If you have any questions, you can contact me.
After the employment of my thesis, we will discuss the three-dimensional trajectory tracking method in depth.
Trajectory tracking-two-dimensional trajectory tracking