免规则采集器列表算法(算法代码主要在CMT这个类里面主要包含initialize和processFrame两个函数)
优采云 发布时间: 2021-12-06 09:18免规则采集器列表算法(算法代码主要在CMT这个类里面主要包含initialize和processFrame两个函数)
cmt 算法 cmt 算法
代码主要在CMT类中,主要包括initialize和processFrame函数的实现。它非常适合纸张。我会评论每个成员的所作所为。
点击打开代码下载链接
namespace cmt
{
class CMT
{
public:
CMT() : str_detector("FAST"), str_descriptor("BRISK") {} //默认的特征检测和描述子
void initialize(const Mat im_gray, const Rect rect); //rect是初始目标框
void processFrame(const Mat im_gray);
Fusion fusion;//跟踪点融合:融合跟踪和匹配的点 将两种点都放在一起,并且不重复
Matcher matcher; //DescriptorMatcher 用的knnMatch匹配
Tracker tracker; //光溜匹配跟踪 上一帧的特征点使用光流法跟踪得到这一帧的特征点的位置T
Consensus consensus;//包括scale和rotation angel的求取和对目标中心的投票
string str_detector;
string str_descriptor;
vector points_active; //public for visualization purposes
RotatedRect bb_rot;
private:
Ptr detector;
Ptr descriptor;
Size2f size_initial;
vector classes_active; //forgroud points -in target boundingboxs
float theta;
Mat im_prev;
};
} /* namespace CMT */
最重要的跟踪实施过程:
初始代码实现,添加注释:
void CMT::initialize(const Mat im_gray, const Rect rect)
{
//Remember initial size
size_initial = rect.size();
//Remember initial image
im_prev = im_gray;
//Compute center of rect
Point2f center = Point2f(rect.x + rect.width/2.0, rect.y + rect.height/2.0);
//Initialize rotated bounding box
bb_rot = RotatedRect(center, size_initial, 0.0);
//Initialize detector and descriptor
//FeatureDetector is OpenCVs feature detector,including "FAST","ORB","SIFT"
//"STAR",MSER","GFTT","HARRIS","Dense","SimpleBlob"
detector = FeatureDetector::create(str_detector);//FAST
descriptor = DescriptorExtractor::create(str_descriptor);//BRISK
//Get initial keypoints in whole image and compute their descriptors
vector keypoints;
detector->detect(im_gray, keypoints);
//Divide keypoints into foreground and background keypoints according to selection
//in target bounding box is foreground
vector keypoints_fg;
vector keypoints_bg;
for (size_t i = 0; i < keypoints.size(); i++)
{
KeyPoint k = keypoints[i];
Point2f pt = k.pt;
if (pt.x > rect.x && pt.y > rect.y && pt.x < rect.br().x && pt.y < rect.br().y)
{
keypoints_fg.push_back(k);
}
else
{
keypoints_bg.push_back(k);
}
}
//Create foreground classes
vector classes_fg;
classes_fg.reserve(keypoints_fg.size());
for (size_t i = 0; i < keypoints_fg.size(); i++)
{
classes_fg.push_back(i);
}
//Compute foreground/background features
Mat descs_fg;
Mat descs_bg;
descriptor->compute(im_gray, keypoints_fg, descs_fg);
descriptor->compute(im_gray, keypoints_bg, descs_bg);
//Only now is the right time to convert keypoints to points, as compute() might remove some keypoints
vector points_fg;
vector points_bg;
for (size_t i = 0; i < keypoints_fg.size(); i++)
{
points_fg.push_back(keypoints_fg[i].pt);
}
for (size_t i = 0; i < keypoints_bg.size(); i++)
{
points_bg.push_back(keypoints_bg[i].pt);
}
//Create normalized points: distance to center
vector points_normalized;
for (size_t i = 0; i < points_fg.size(); i++)
{
points_normalized.push_back(points_fg[i] - center);
}
//Initialize matcher
matcher.initialize(points_normalized, descs_fg, classes_fg, descs_bg, center);
//Initialize consensus get Xi,Xj distance and angle
consensus.initialize(points_normalized);
//Create initial set of active keypoints
for (size_t i = 0; i < keypoints_fg.size(); i++)
{
points_active.push_back(keypoints_fg[i].pt);
classes_active = classes_fg;
}
}
总结:这是一种基于特征点匹配的跟踪算法。创新之处在于它利用特征点相对距离的投票来确定目标位置。优点是对于没有变形的物体,无论物体如何移动或旋转,上述特征点到中心的距离都是在缩放比例下确定的。
作者在论文中说:CMT背后的主要思想是将感兴趣的对象分解成微小的部分,称为关键点。在每一帧中,我们尝试再次找到已经在初始选择中的关键点感兴趣的对象。我们通过使用两种不同的方法来做到这一点。首先,我们通过估计所谓的光流来跟踪从前一帧到当前帧的关键点。其次,我们通过比较它们的描述符来全局匹配关键点。这些方法容易出错,我们采用了一种新颖的方式,通过让每个关键点投票给对象中心来在找到的关键点内寻找共识,如下图所示:
然后通过对中心集群进行投票来确定中心位置: