转载请注明原作者t1234xy4:http://blog.csdn.net/t1234xy4/article/details/51241032

在读研期间,由于导师与水环研究生水生物有项目交叉,我主要研究视频跟踪技术。用来提取鱼类的轨迹以及鱼类的微动作。其中鱼类的轨迹提取我已做了两部分工作,二维视频跟踪,提取鱼类的轨迹;另一部分工作是重建三维鱼类游动轨迹。鱼类微特征提取还没有动工(惭愧)。
----------

二维的视频跟踪

在做这项工作之前我们花费了很大的力气去获取实验数据。购买了三个汉邦高科的摄像头,水箱,摄像头支架等。搭建好实验装置。(由于主要说视频跟踪,具体与鱼相关的就带过)
注意:
1、摄像头要固定住,这样拍摄的视频帧才有固定的摄像机坐标,最后才好转换成统一的现实坐标。
2、获取的视频尽量减少运动背景的干扰,熟悉前景检测的人都应该知道。
3、注意光线,不要太暗了,也不要太刺眼,有光圈亮点。

前景跟踪算法过程

首先都是查看文献来着,大概看了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]是我们方法的基础,我直接将它的源码移植过来了。

我的工作

1、主要是从前景检测的结果中用一种更优的方法找出鱼类所在的位置。能够更加精确、实时的提取鱼类轨迹。
2、将轨迹做平滑处理,使用了基于平方的方法,效果很不错。
3、开发二维轨迹跟踪软件,确实只是小软件,我只用了3个星期不到的时间做完,当然还有很多需要完善的地方。其实也有之前做三维鱼类轨迹跟踪系统的基础。很多复用了之前的代码。

二维估计跟踪算法:
原始帧->去失真->vibe->局部搜索->二维轨迹
vibe算法不是我的原创,是已经很成熟的算法,故不详细说明。贴出它的源码吧,希望大家可以直接借鉴学习。
二次封装之后的vibe.hxx:

#ifndef _VIBE_HXX_
#define _VIBE_HXX_
class VIBE
{
public:VIBE();~VIBE();void initialize();void update();inline void setCurrentFrame( unsigned char* i ) { _image = i; }inline void setSegmentMap( unsigned char* i ) { _segMap = i; }inline void setFrameWidth( int w ) { _frameWidth = w; }inline void setFrameHeight( int h ) { _frameHeight = h; }inline void setFrameWidthStrip( int s ) { _frameWidthStrip = s; }inline bool isInitilized() { return _samples; }private:int getRandomSample();int getRandomSubSample();int getRandomNeightXCoordinate( int x );int getRandomNeightYCoordinate( int y );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 25
#define R 15
#define ZMIN    3
#define PHI     16VIBE::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( int i = 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( int i = 0; i < _pixelSamples; i ++ )_samples[ i ] = new unsigned char[ _frameHeight * _frameWidthStrip ];int tq = sqrtf( _pixelSamples );_borderWidth = tq / 2;for( int y = _borderWidth; y < _frameHeight - _borderWidth; y ++ ){for( int x = _borderWidth; x < _frameWidth - _borderWidth; x ++ ){int c = 0; for( int i = -_borderWidth; i <= _borderWidth && c < _pixelSamples ; i ++ ){for( int j = -_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 ++ ){int count = 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 ){int xg, yg;xg = getRandomNeightXCoordinate(x);yg = getRandomNeightYCoordinate(y);rand = getRandomSample();*(_samples[ rand ] + yg * _frameWidthStrip + xg ) = *( _image + y * _frameWidthStrip + x );}}else{*(_segMap  + y * _frameWidthStrip + x ) = 255;}}}
}int VIBE::getRandomSample()
{int val = _pixelSamples * 1.0 * rand() / RAND_MAX;if( val == _pixelSamples )return val - 1;elsereturn val;}int VIBE::getRandomSubSample()
{int val = _subSampling * 1.0 * rand() / RAND_MAX;if( val == _subSampling )return val - 1;elsereturn val;}int VIBE::getRandomNeightXCoordinate( int x )
{int val = 4 * 1.0 * rand() / RAND_MAX - 2;if( x + val >= _frameWidth || x + val < 0 )return x;elsereturn x + val;
}int VIBE::getRandomNeightYCoordinate( int y )
{int val = 4 * 1.0 * rand() / RAND_MAX - 2;if( y + val >= _frameWidth || y + val < 0 )return y;elsereturn y + val;
}

调用这个VIBE这个类的方法:

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();……//更新
vibe.setCurrentFrame( (unsigned char*)grayImage->imageData );
vibe.update();

不会用多看看类的源码吧。“不要怕难,多折腾!”,我导师的名言。

局部搜索以及平滑处理
设k为帧数,R为搜索半径,P(x,y)为在 (x,y)处的像素值。设第 帧的坐标为(xk,yk) ,可以得到第k+1 帧的位置为 :

平滑处理过程:
设平滑窗口的宽度为W1,窗口中每一帧的权重为:
原理为每一位局当前位置距离的平方,最远处为1^2,……,当前最大2^k

平滑结果:

效果展示:
VIBE结果:

局部搜索:

跟踪结果:

如有疑问,可以联系我。
等我的论文录用后,再深入讨论三维轨迹跟踪方法。

轨迹跟踪——二维轨迹跟踪相关推荐

  1. 机动目标跟踪——匀加速运动CA模型(二维)

    机动目标跟踪--匀加速运动CA模型(二维) 原创不易,路过的各位大佬请点个赞 WX: ZB823618313 机动目标跟踪--目标模型概述 机动目标跟踪--匀加速运动CA模型(二维) 1. 对机动目标 ...

  2. 风靡全球的社交媒体二维码在国内正式上线啦!

    你还在为国内互联网平台之间互相屏蔽的问题而烦恼不已吗? 现在,只需要一个社交媒体二维码,就可以轻松将国内16个主流社交媒体渠道汇集在一个页面.让粉丝增长.获客引流变得更加高效和轻松. 扫描二维码之后, ...

  3. OpenCV基础(22)使用OpenCV生成及读取二维码以及与Zbar比较

    二维码(QR码)是一种矩阵条形码,是一种机器可读的光学标签,其中包含有关其所附着物品的信息.实际上,二维码(QR码)码通常包含指向网站或应用程序的定位器,标识符或跟踪器的数据. 最近,OpenCV 4 ...

  4. C++Builder下利用TImage制作二维条码PDF417打印控件(一)

    PDF417二维条码的应用 现代社会,由于条码的使用,极大地提高了数据采集和信息处理的速度,提高了工作效率,为管理的科学化和现代化作出了很大贡献. 受信息容量的限制,一维条码必须依赖于后台的数据库才能 ...

  5. 在Matlab下编程实现二维与三维的航迹跟踪控制、路径跟踪控制和轨迹跟踪控制,实现编队集群控制与避障控制

    在Matlab下编程实现二维与三维的航迹跟踪控制.路径跟踪控制和轨迹跟踪控制,实现编队集群控制与避障控制. 研究对象有空中无人机.地面机器人.水面无人艇.水下机器人以及多智能体等. ID:321006 ...

  6. 使用OpenCV+Tensorflow跟踪排球的轨迹

    介绍 本文将带领大家如何把人工智能技术带到体育项目中. 运动中的人工智能是一个很新的东西,以下是一些有趣的作品: 篮球 https://dev.to/stephan007/open-source-sp ...

  7. 基于核函数加权直方图的Mean Shift目标跟踪 (二维颜色直方图)

    前面有几篇博文介绍了在单张图像上的Mean Shift 迭代收敛过程,接下来将要为大家分享的是基于摄像头获取视频的视频目标跟踪,希望对大家有帮助!\(^o^)/~ 基于核函数加权直方图的Mean Sh ...

  8. python画车辆轨迹图_如何利用 Python 绘制酷炫的 车辆轨迹 — 速度时空图?三维数据用二维图像呈现...

    说明:本文系交通攻城狮原创文章,如需转载请私信联系,侵权必究. 2020,第 30 期,编程笔记 建议直接阅读精编版:如何利用 Python 绘制酷炫的 车辆轨迹 - 速度时空图?三维数据用二维图像呈 ...

  9. opencv 二维图像 特征检测 特征描述 特征匹配 平面物体识别跟踪

    github代码 一.Harris角点 cornerHarris() R = det(M) - k*(trace(M))^2  算法基本思想是使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与 ...

  10. 基于横向轨迹误差法(Cross-track Error)P 导航二维控制 实现无人机水平面导航控制

    基于横向轨迹误差法(Cross-track Error)P 导航二维控制 实现无人机水平面导航控制 算法核心思想 算法实现方法 实现无人机水平面导航控制 算法优化方向 算法核心思想 首先我们的目的是控 ...

最新文章

  1. 机器学习中算法的性能评估
  2. (C++)1020 月饼 简单贪心
  3. 获取上层调用函数地址的代码
  4. 关于椭圆的积分变量替换
  5. 学历是铜牌,能力是银牌,人脉是金牌,思维是王牌——有感
  6. Atitit.atiJsBridge 新特性v7q329
  7. 【数据库系统概论】考研第四部分重点分析【4.1】
  8. redis api-set
  9. 【算法】Floyd-Warshall算法(任意两点间的最短路问题)(判断负圈)
  10. [C++STL]vector容器用法介绍
  11. 双向tvs和单向tvs_TVS的完整形式是什么?
  12. sublime用cmd窗口调试python_Sublime Text设置程序输出窗口为dos窗口
  13. 图片夹_电竞游戏鼠标好伴侣,鼠标线夹,让你桌面不凌乱
  14. 类支付宝微信密码输入框
  15. python读写ini文件的库支持unicode_Python读写unicode文件的方法
  16. Spring Cloud与微服务学习总结(10)——Spring Cloud 常见优化项的总结
  17. 前端 JavaScript 之『节流』的简单代码实现
  18. 10+年程序员告诉你职场误区,如何快速提升自己?
  19. 一起学Windows phone7开发(五.一个时钟的例子)
  20. 只知道三角形三条边长不知道高是多少,用Python如何求三角形周长和面积,海伦公式帮你解决这个难题

热门文章

  1. 难道真的是RPWT-LFS日记1
  2. 关闭Cadence Orcad Capture CIS原理图弹出startpage页面的方法
  3. matlab 音乐 豆腐汤,40岁健康家常菜pdf
  4. 轻量级深度神经网络推理引擎——阿里巴巴的 MNN
  5. podman加速器配置Harbor
  6. 微信app用户及市场调研
  7. 离线地图三维立体建筑物实现
  8. 2018年的好书基本都在这了,你一共读过几本?
  9. python 分割线_用Python打印分割线练习
  10. 【图像压缩】多层超先验模型 《Coarse-to-Fine Hyper-Prior Modeling for Learned Image Compression》