读取图片-》特征点检测(位置,角度,层)-》特征点描述的提取(16*8维的特征向量)-》匹配-》显示
其中,特征点提取主要有两个步骤,见上行黄子部分。下面做具体分析。
1、使用opencv内置的库读取两幅图片
2、生成一个SiftFeatureDetector的对象,这个对象顾名思义就是SIFT特征的探测器,用它来探测衣服图片中SIFT点的特征,存到一个KeyPoint类型的vector中。这里有必要说keypoint的数据结构,涉及内容较多,具体分析查看opencv中keypoint数据结构分析,里面讲的自认为讲的还算详细(表打我……)。简而言之最重要的一点在于:
keypoint只是保存了opencv的sift库检测到的特征点的一些基本信息,但sift所提取出来的特征向量其实不是在这个里面,特征向量通过SiftDescriptorExtractor 提取,结果放在一个Mat的数据结构中。这个数据结构才真正保存了该特征点所对应的特征向量。具体见后文对SiftDescriptorExtractor 所生成的对象的详解。
就因为这点没有理解明白耽误了一上午的时间。哭死!
3、对图像所有KEYPOINT提取其特征向量:
得到keypoint只是达到了关键点的位置,方向等信息,并无该特征点的特征向量,要想提取得到特征向量就还要进行SiftDescriptorExtractor
的工作,建立了SiftDescriptorExtractor
对象后,通过该对象,对之前SIFT产生的特征点进行遍历,找到该特征点所对应的128维特征向量。具体方法参见opencv中SiftDescriptorExtractor所做的SIFT特征向量提取工作简单分析。通过这一步后,所有keypoint关键点的特征向量被保存到了一个MAT的数据结构中,作为特征。
4、对两幅图的特征向量进行匹配,得到匹配值。
两幅图片的特征向量被提取出来后,我们就可以使用BruteForceMatcher对象对两幅图片的descriptor进行匹配,得到匹配的结果到matches中。
至此,SIFT从特征点的探测到最后的匹配都已经完成,虽然匹配部分不甚了解,只扫对于如何使用OPENCV进行sift特征的提取有了一定的理解。接下来可以开始进行下一步的工作了。
附:使用OPENCV下SIFT库做图像匹配的例程
// opencv_empty_proj.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/features2d/features2d.hpp>
#include<opencv2/nonfree/nonfree.hpp>
#include<opencv2/legacy/legacy.hpp>
#include<vector>
using namespace std
using namespace cv
int _tmain(int argc, _TCHAR* argv[])
{
const char* imagename = "img.jpg"
//从文件中读入图像
Mat img = imread(imagename)
Mat img2=imread("img2.jpg")
//如果读入图像失败
if(img.empty())
{
fprintf(stderr, "Can not load image %s\n", imagename)
return -1
}
if(img2.empty())
{
fprintf(stderr, "Can not load image %s\n", imagename)
return -1
}
//显示图像
imshow("image before", img)
imshow("image2 before",img2)
//sift特征检测
SiftFeatureDetector siftdtc
vector<KeyPoint>kp1,kp2
siftdtc.detect(img,kp1)
Mat outimg1
drawKeypoints(img,kp1,outimg1)
imshow("image1 keypoints",outimg1)
KeyPoint kp
vector<KeyPoint>::iterator itvc
for(itvc=kp1.begin()itvc!=kp1.end()itvc++)
{
cout<<"angle:"<<itvc->angle<<"\t"<<itvc->class_id<<"\t"<<itvc->octave<<"\t"<<itvc->pt<<"\t"<<itvc->response<<endl
}
siftdtc.detect(img2,kp2)
Mat outimg2
drawKeypoints(img2,kp2,outimg2)
imshow("image2 keypoints",outimg2)
SiftDescriptorExtractor extractor
Mat descriptor1,descriptor2
BruteForceMatcher<L2<float>>matcher
vector<DMatch>matches
Mat img_matches
extractor.compute(img,kp1,descriptor1)
extractor.compute(img2,kp2,descriptor2)
imshow("desc",descriptor1)
cout<<endl<<descriptor1<<endl
matcher.match(descriptor1,descriptor2,matches)
drawMatches(img,kp1,img2,kp2,matches,img_matches)
imshow("matches",img_matches)
//此函数等待按键,按键盘任意键就返回
waitKey()
return 0
}
1. 创建单个对象跟踪器(Tracker)多对象跟踪器只是单个对象跟踪器的集合。我们首先定义一个函数,该函数将跟踪器类型作为输入并创建一个跟踪器对象。OpenCV具有8种不同的跟踪器类型:BOOSTING,MIL,KCF,TLD,MEDIANFLOW,GOTURN,MOSSE和CSRT。
我们定义一个跟踪器函数createTrackerByName:
通过输入跟踪器名称,返回对应类型的跟踪器。
2. 读取视频的初始帧
多对象跟踪器(MultiTracker)需要两个输入:
初始视频帧
通过边界框(boundingbox)确定的对象位置
来看代码:我们建立了程序入口,并设定默认追踪算法为CSRT算法(注:GOTURN算法需要安装配置Caffe)。从摄像头读取初始帧
3.在初始帧中找到对象
OpenCV提供了一个名为selectROI的功能,该功能会d出一个GUI以选择边界框(也称为关注区域(ROI))。
SQL Server / Oracle / MS Access: CREATE TABLE Persons(
P_Id int NOT NULL UNIQUE,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)