学习OpenCV——ORB简化版&Location加速版
根据前面surf简化版的结构,重新把ORB检测的代码给简化以下,发现虽然速度一样,确实能省好多行代码,关键是有
BruteForceMatcher<HammingLUT>matcher的帮忙,直接省的写了一个函数;
NB类型:class gpu::BruteForceMatcher_GPU
再加上findHomography,之后perspectiveTransform就可以location,但是这样速度很慢;
于是改动一下,求matches的keypoints的x与y坐标和的平均值,基本上就是对象中心!!!
以这个点为中心画与原对象大小相同的矩形框,就可以定位出大概位置,但是肯定不如透视变换准确,而且不具有尺度不变性。
但是鲁棒性应该更好,因为,只要能match成功,基本都能定位中心,但是透视变换有时却因为尺度变换过大等因素,画出很不靠谱的矩形框!
- #include "opencv2/objdetect/objdetect.hpp"
- #include "opencv2/features2d/features2d.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include "opencv2/calib3d/calib3d.hpp"
- #include "opencv2/imgproc/imgproc_c.h"
- #include "opencv2/imgproc/imgproc.hpp"
- #include <string>
- #include <vector>
- #include <iostream>
- using namespace cv;
- using namespace std;
- char* image_filename1 = "D:/src.jpg";
- char* image_filename2 = "D:/Demo.jpg";
- int main()
- {
- Mat img1 = imread( image_filename1, CV_LOAD_IMAGE_GRAYSCALE );
- Mat img2 = imread( image_filename2, CV_LOAD_IMAGE_GRAYSCALE );
- int64 st,et;
- ORB orb1(30,ORB::CommonParams(1.2,1));
- ORB orb2(100,ORB::CommonParams(1.2,1));
- vector<KeyPoint>keys1,keys2;
- Mat descriptor1,descriptor2;
- orb1(img1,Mat(),keys1,descriptor1,false);
- st=getTickCount();
- orb2(img2,Mat(),keys2,descriptor2,false);
- et=getTickCount()-st;
- et=et*1000/(double)getTickFrequency();
- cout<<"extract time:"<<et<<"ms"<<endl;
- vector<DMatch> matches;
- //<em>class </em><tt class="descclassname">gpu::</tt><tt class="descname"><span class="highlighted">BruteForce</span>Matcher_GPU</tt>
- BruteForceMatcher<HammingLUT>matcher;//BruteForceMatcher支持<Hamming> <L1<float>> <L2<float>>
- //FlannBasedMatcher matcher;不支持
- st=getTickCount();
- matcher.match(descriptor1,descriptor2,matches);
- et=getTickCount()-st;
- et=et*1000/getTickFrequency();
- cout<<"match time:"<<et<<"ms"<<endl;
- Mat img_matches;
- drawMatches( img1, keys1, img2, keys2,
- matches, img_matches, Scalar::all(-1), Scalar::all(-1),
- vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
- imshow("match",img_matches);
- cout<<"match size:"<<matches.size()<<endl;
- /*
- Mat showImg;
- drawMatches(img1,keys1,img2,keys2,matchs,showImg);
- imshow( "win", showImg );
- */
- waitKey(0);
- st=getTickCount();
- vector<Point2f>pt1;
- vector<Point2f>pt2;
- float x=0,y=0;
- for(size_t i=0;i<matches.size();i++)
- {
- pt1.push_back(keys1[matches[i].queryIdx].pt);
- pt2.push_back(keys2[matches[i].trainIdx].pt);
- x+=keys2[matches[i].trainIdx].pt.x;
- y+=keys2[matches[i].trainIdx].pt.y;
- }
- x=x/matches.size();
- y=y/matches.size();
- Mat homo;
- homo=findHomography(pt1,pt2,CV_RANSAC);
- vector<Point2f>src_cornor(4);
- vector<Point2f>dst_cornor(4);
- src_cornor[0]=cvPoint(0,0);
- src_cornor[1]=cvPoint(img1.cols,0);
- src_cornor[2]=cvPoint(img1.cols,img1.rows);
- src_cornor[3]=cvPoint(0,img1.rows);
- perspectiveTransform(src_cornor,dst_cornor,homo);
- Mat img=imread(image_filename2,1);
- line(img,dst_cornor[0],dst_cornor[1],Scalar(255,0,0),2);
- line(img,dst_cornor[1],dst_cornor[2],Scalar(255,0,0),2);
- line(img,dst_cornor[2],dst_cornor[3],Scalar(255,0,0),2);
- line(img,dst_cornor[3],dst_cornor[0],Scalar(255,0,0),2);
- /*
- line(img,cvPoint((int)dst_cornor[0].x,(int)dst_cornor[0].y),cvPoint((int)dst_cornor[1].x,(int)dst_cornor[1].y),Scalar(255,0,0),2);
- line(img,cvPoint((int)dst_cornor[1].x,(int)dst_cornor[1].y),cvPoint((int)dst_cornor[2].x,(int)dst_cornor[2].y),Scalar(255,0,0),2);
- line(img,cvPoint((int)dst_cornor[2].x,(int)dst_cornor[2].y),cvPoint((int)dst_cornor[3].x,(int)dst_cornor[3].y),Scalar(255,0,0),2);
- line(img,cvPoint((int)dst_cornor[3].x,(int)dst_cornor[3].y),cvPoint((int)dst_cornor[0].x,(int)dst_cornor[0].y),Scalar(255,0,0),2);
- */
- circle(img,Point(x,y),10,Scalar(0,0,255),3,CV_FILLED);
- line(img,Point(x-img1.cols/2,y-img1.rows/2),Point(x+img1.cols/2,y-img1.rows/2),Scalar(0,0,255),2);
- line(img,Point(x+img1.cols/2,y-img1.rows/2),Point(x+img1.cols/2,y+img1.rows/2),Scalar(0,0,255),2);
- line(img,Point(x+img1.cols/2,y+img1.rows/2),Point(x-img1.cols/2,y+img1.rows/2),Scalar(0,0,255),2);
- line(img,Point(x-img1.cols/2,y+img1.rows/2),Point(x-img1.cols/2,y-img1.rows/2),Scalar(0,0,255),2);
- imshow("location",img);
- et=getTickCount()-st;
- et=et*1000/getTickFrequency();
- cout<<"location time:"<<et<<"ms"<<endl;
- waitKey(0);
- }
from: http://blog.csdn.net/yangtrees/article/details/7545820
学习OpenCV——ORB简化版&Location加速版的更多相关文章
- 学习OpenCV——Surf简化版
之前写过一遍关于学习surf算法的blog:http://blog.csdn.net/sangni007/article/details/7482960 但是代码比较麻烦,而且其中还涉及到flann算 ...
- Keras学习环境配置-GPU加速版(Ubuntu 16.04 + CUDA8.0 + cuDNN6.0 + Tensorflow)
本文是个人对Keras深度学习框架配置的总结,不周之处请指出,谢谢! 1. 首先,我们需要安装Ubuntu操作系统(Windows下也行),这里使用Ubuntu16.04版本: 2. 安装好Ubunt ...
- 转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】
文章来自于:http://blog.renren.com/share/246648717/8171467499 基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴 ...
- 《学习OpenCV(中文版)》
<模式识别中文版(希)西奥多里蒂斯> <学习OpenCV(中文版)> 矩阵计算 英文版 第四版 Matrix Computations OpenCV 3.x with Pyth ...
- 前端学习 node 快速入门 系列 —— 简易版 Apache
其他章节请看: 前端学习 node 快速入门 系列 简易版 Apache 我们用 node 来实现一个简易版的 Apache:提供静态资源访问的能力. 实现 直接上代码. - demo - stati ...
- 学习opencv之路(一)
先看一下<学习opencv> 找几个demo 学会相机标定 我做的是单目相机的标定.
- 实验楼课程管理程序-深入学习《C++ Primer第五版》实验报告&学习笔记1
本片博客为实验楼的训练营课程深入学习<C++ Primer第五版>的实验报告和学习笔记. 原课程地址为:https://www.shiyanlou.com/courses/405# 原文出 ...
- [纯小白学习OpenCV系列]官方例程00:世界观与方法论
2015-11-11 ----------------------------------------------------------------------------------- 其实,写博 ...
- 《学习OpenCV》中求给定点位置公式
假设有10个三维的点,使用数组存放它们有四种常见的形式: ①一个二维数组,数组的类型是CV32FC1,有n行,3列(n×3) ②类似①,也可以用一个3行n列(3×n)的二维数组 ③④用一个n行1列(n ...
随机推荐
- TCP/IP简介
TCP/IP协议分层 提到协议分层,我们很容易联想到ISO-OSI的七层协议经典架构,但是TCP/IP协议族的结构则稍有不同.如图所示 TCP/IP协议族按照层次由上到下,层层包装.最上面的就是应用层 ...
- Cacti安装详细步骤
原文链接: https://www.centos.bz/2012/01/cacti-install-tutorials/ Cacti-监控MySQL: http://www.cszhi.com/201 ...
- document.execCommand(”BackgroundImageCache”, false, true)
很多时候我们要给一些按钮或是img设置背景,而为了达到数据与表现样式分离的效果,通常背景样式都是在CSS里设定的,但是这个行为在IE会有一 个Bug,那就是因为 IE默认情况下不缓存背景图片,所以当鼠 ...
- 500Internal Server Error
在今晚测试wamp的项目时,当我导入一个项目到www目录下时出现如下错误:Internal Server ErrorThe server encountered an internal error o ...
- Makefile 如何轻松搞定
最近在学习Linux下的C编程,买了一本叫<Linux环境下的C编程指南>读到makefile就越看越迷糊,可能是我的理解能不行. 于是google到了以下这篇文章.通俗易懂.然后把它贴出 ...
- 逻辑运算符——逻辑与&&、逻辑或||
一直以来,都是认为逻辑运算符返回的是布尔值,却突然发现:并不是这样. 对于||来说,如果条件判断结果为true就返回第一个操作数的值,如果为false就返回第二个操作数的值. &&则相 ...
- new char[]和new char()的区别
new char[1];分配一块连续的内存,也就是一个数组,里面有1个元素new char(1);分配一块内存,有一个元素,该元素被初始化为1
- 帝国CMS备忘
一. 2级导航: 类似下图这种导航: 实现方式如: 1. 定义一个标签模板,记住ID,具体内容如: 页面模板内容: <li><a href=”[!—bclassurl—]”>[ ...
- python装饰器方法
前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释. 今天查看dja ...
- 通过iphone蓝牙与经过苹果MFI授权认证的硬件通讯,传输图片(转)
http://blog.csdn.net/hwj2012/article/details/7883711 相关: http://blog.csdn.net/xufeidll/article/detai ...