本章主要具体解释的是compressive tracking框架中的第一部分:样本的採集和扩充部分。

在開始代码学习的前面,你须要知道的理论知识參见论文:Real-time Compressive Tracking。理论理解能够參见我的博客:http://blog.csdn.net/ikerpeng/article/details/19826409 。

这个模块中你须要知道一个主要的概念:代码里面几个变量指的是什么。上一张图:

或许你如今还不知道他们是什么,直接贴代码了。

相信有我的凝视你一定会懂的。

头文件 sampleRect.h

#pragma once
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std; class sampleRect
{
public:
sampleRect(void);//构造函数,初始化以下的rOuterpositive
~sampleRect(void); private:
int rOuterpositive;//这个设定的是正负样本的边界。在这个边界里面的就是正样本,外面的就是负样本。 void sampleRect0(Mat& _image, Rect& _objectPatch, float _rInner, float _rOuter, int _maxSampleNum, vector<Rect>& _sampleRect );
//这个函数最重要,它是用来扩充正负样本的。 他通过设定_rInner,_rOuter两个边界,选出的样本是_rInner里面的,_rOuter外面的。 也就是说_rInner>_rOuter.
//在进行正样本扩充的时候_rOuter=0._rInner=上面那个边界rOuterpositive;产生负样本的时候_rOuter=rOuterpositive。里面的參数在实现的时候说明
void sampleRect1(Mat& _image, Rect& _objectPatch, float _srw, vector<Rect>& _sampleRect );//这个函数是要扩充待检測的样本的 };
#include "sampleRect.h"
#include <math.h>
#include<iostream> sampleRect::sampleRect()
{
int rOuterpositive=4;//这里我们都是以矩形框的左上角的点为參照的,若是要扩充的样本的这个点离目标位置的这个点的距离在4个像素以内则定义为正样本。否则为负。
}
sampleRect::~sampleRect()
{ }
void sampleRect::sampleRect0(Mat& _image, Rect& _objectPatch, float _rInner, float _rOuter, int _maxSampleNum, vector<Rect>& _sampleRect )
{
/*
Arguments:
-_image: processing frame
-_objectBox: recent object position
-_rInner: inner sampling radius
-_rOuter: Outer sampling radius
-_maxSampleNum: maximal number of sampled images
-_sampleRect: Storing the rectangle coordinates of the sampled images.
*/
int rowsz=_image.rows-_objectPatch.height-1;//y方向上取值的最大范围
int colsz= _image.cols- _objectPatch.width-1;
float rInnerSq=_rInner*_rInner;//这个相当于是外圆的距离的平方,为的是和后面的dist作比較的。小于这个值就在圆里面
float rOuterSq=_rOuter*_rOuter;//同上,大于这个值就在选择的范围里面了。详细參见示意图1。
int dist;
RNG rng; //以下这个是为了要确定选出来的patch快的范围(事实上是左上角点的坐标的范围)
int minrow = max(0,(int)_objectPatch.y-(int)_rInner);//计算出的结果是y坐标的最小取值。相当于一个圆外接矩形的最上面的那个点。详细參见示意图1
int maxrow = min(rowsz-1, (int)_objectPatch.y+(int)_rInner);//计算出的结果是y坐标的最大取值,相当于一个圆外接矩形的最以下的那个点。 int mincol = max(0,(int)_objectPatch.x-(int)_rInner);//计算出的结果是x坐标的最小取值,相当于一个圆外接矩形的最左边的那个点。
int maxcol = min(colsz,(int)_objectPatch.x+(int)_rInner);//计算出的结果是x坐标的最大取值,相当于一个圆外接矩形的最右边的那个点。 float prob=_maxSampleNum/(maxrow-minrow+1)/(maxcol-mincol+1);//这个值的设定是为了将扩充正负样本的函数统一到一个函数里面
// 由于负样本的扩充时设定的最外面的边界_rInner是比較大的。 那就非常产生非常多的样本,这个时候我们就通过这个值的推断随机的选择一些
//_maxSampleNum设置是非常大的。上面的式子是相当于除以后面两个的乘积啦。 int r,c; //横纵坐标
int i=0; //记住vector的尺寸
_sampleRect.clear();// 非常重要。開始的时候一定清空样本存储的地方
Rect rect(0,0,0,0); //用来记录每个被选到的样本块 for ( r=minrow; r<=maxrow; r++)
{
for( c=mincol; c<=maxcol; c++)
{
dist=(_objectPatch.y-r)*(_objectPatch.y-r)+(_objectPatch.x-c)*(_objectPatch.x-c);//到目标点的距离
if((rng.uniform(0., 1.)<prob)&&(dist<=rInnerSq)&&(dist>=rOuterSq))
//这里就是将正负样本的扩充统一起来了。对于正样本,由于满足的范围小,prob一定>1。所以满足条件的都要。
//对于负样本来说,rng.uniform(0., 1.)<prob)就不一定成立,所以是随机的保存所产生的满足要求的负样本。 //(附加说明一点,_maxSampleNum这里设置的是10000.一般一个图像至少320*240,所以prob=1/6左右。也就是保存了所有负样本的1/6左右)
{
rect.x=c;//满足上面的条件以后就採集样本并存储到_sampleRect中
rect.y=r;
rect.height=_objectPatch.height;
rect.width=_objectPatch.width;
_sampleRect.push_back(rect);
i++;
} }
}
_sampleRect.resize(i);//这个操作是要确定这个vector的尺寸。 由于vector给你分配的空间往往是大于你所要的。 } //以下的操作基本上是一样的了,其作用是在上一帧的位置附近生成一些待检測的样本。这被觉得是可能的目标出现的位置。
void sampleRect::sampleRect1(Mat& _image, Rect& _objectPatch, float _srw, vector<Rect>& _sampleRect )
{
int rowsz=_image.rows-_objectPatch.height-1;
int colsz =_image.cols -_objectPatch.width-1;
int radSq= _srw*_srw; int dist;
Rect rect; int minrow=max(0,(int)_objectPatch.y-(int)_srw);
int maxrow=min(rowsz,(int)_objectPatch.y+(int)_srw);
int mincol =max(0,(int)_objectPatch.x-(int)_srw);
int maxcol =max(colsz,(int)_objectPatch.x+(int)_srw); int r,c;
int i=0; for( r=minrow; r<=maxrow;r++)
{
for ( c=mincol; c<=maxcol; c++)
{
dist=(_objectPatch.y-r)*(_objectPatch.y-r)+(_objectPatch.x-c)*(_objectPatch.x-c);
if(dist<=radSq )//不在须要prob来限制量了,以下都是一样的了。 {
rect.x=c;
rect.y=r;
rect.height=_objectPatch.height;
rect.width=_objectPatch.width;
_sampleRect.push_back(rect);
i++; } }
}
_sampleRect.resize(i);
}
//本节搞定。

我是实实在在的刚開始学习的人,发现问题请指正啊!谢谢!

最新文章

  1. android ListView 属性
  2. 又一种XML的解析方法
  3. -bash: wget: command not found的两种解决方法
  4. vector data() [c++11]
  5. stuts-security.xml
  6. iOS 键盘回收实现步骤
  7. 2013国内IT行业薪资对照表【技术岗】
  8. shiro内置过滤器研究
  9. 一步一步学python(四) - 字典
  10. spring开发基础
  11. 最短路径算法专题2----Dijkstra
  12. IP协议详解
  13. 基于Kafka Connect框架DataPipeline可以更好地解决哪些企业数据集成难题?
  14. codeforces 1151 A
  15. 一种快速过VMP3.x调试器虚拟机检测的方法
  16. MySQL常用日期时间函数
  17. Delphi基础必记-快捷键
  18. Java读写avro例子
  19. 从sqlserver数据库中提取年月日并截取出来
  20. 招新系统(jsp+servlet,实现简略前端网页注册登录+后台增删改查,分学生和管理员,Java语言,mysql数据库连接,tomcat服务器)

热门文章

  1. ThinkPHP3.2多域名 Virtual .htaccess 匹配 RewriteCond %{HTTP_HOST}
  2. &ldquo;图片+标签&rdquo;的社交玩法已经被验证?nice 宣布获得新一轮3600万美元融资【转载+整理】
  3. .geodatabase与gdb的相互转换
  4. CMUSphinx Learn - Basic concepts of speech
  5. Intellij IDEA连接Spark集群
  6. MongoDB副本集配置系列五:副本集的在线迁移
  7. Java同步机制之Monitor监视器与syncrhoized实现原理
  8. Java多线程之创建线程的三种方式比较
  9. Nginx配置站点适配PC和手机
  10. 【shell】分别提取文件名中的基本名与扩展名