图像特征的类型通常指边界、角点(兴趣点)、斑点(兴趣区域)。角点就是图像的一个局部特征,应用广泛。harris角点检测是一种直接基于灰度图像的角点提取算法,稳定性高,尤其对L型角点检测精度高,但由于采用了高斯滤波,运算速度相对较慢,角点信息有丢失和位置偏移的现象,而且角点提取有聚簇现象。

 

 

#include "stdafx.h"

#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp" using namespace cv; void readme(); /** @function main */
int main( int argc, char** argv )
{
/*
if( argc != 3 )
{ readme(); return -1; } */ Mat img_1 = imread( "zhang.jpg", CV_LOAD_IMAGE_GRAYSCALE );
Mat img_2 = imread( "guo.jpg", CV_LOAD_IMAGE_GRAYSCALE ); if( !img_1.data || !img_2.data )
{ std::cout<< " --(!) Error reading images " << std::endl; return -1; } //-- Step 1: Detect the keypoints using SURF Detector
int minHessian = 400; SurfFeatureDetector detector( minHessian ); std::vector<KeyPoint> keypoints_1, keypoints_2; detector.detect( img_1, keypoints_1 ); // 特征点向量
detector.detect( img_2, keypoints_2 ); //-- Draw keypoints
Mat img_keypoints_1; Mat img_keypoints_2; drawKeypoints( img_1, keypoints_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
drawKeypoints( img_2, keypoints_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT ); //-- Show detected (drawn) keypoints
imshow("Keypoints 1", img_keypoints_1 );
imshow("Keypoints 2", img_keypoints_2 ); waitKey(0); return 0;
} /** @function readme */
void readme()
{ std::cout << " Usage: ./SURF_detector <img1> <img2>" << std::endl; }

 

检测keypoints点的检测器是SURF,获取描述子也是用到SURF来描述,而用到的匹配器是FlannBased,最后通过findHomography寻找单映射矩阵,perspectiveTransform获得最终的目标

findHomography 函数是求两幅图像的单应性矩阵,它是一个3*3的矩阵

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2\calib3d\calib3d.hpp> using namespace cv; void readme(); int main( int argc, char** argv )
{ /*
if( argc != 3 )
{ return -1; }*/ Mat img_1 = imread( "test1.jpg", CV_LOAD_IMAGE_GRAYSCALE );
Mat img_2 = imread( "test2.jpg", CV_LOAD_IMAGE_GRAYSCALE ); if( !img_1.data || !img_2.data )
{ return -1; } //-- Step 1: Detect the keypoints using SURF Detector
int minHessian = 400; SurfFeatureDetector detector( minHessian ); std::vector<KeyPoint> keypoints_1, keypoints_2; detector.detect( img_1, keypoints_1 );
detector.detect( img_2, keypoints_2 ); // 角点集合 —— 数目确定 //-- Step 2: Calculate descriptors (feature vectors)
SurfDescriptorExtractor extractor; // 角点描述子 Mat descriptors_1, descriptors_2; extractor.compute( img_1, keypoints_1, descriptors_1 );
extractor.compute( img_2, keypoints_2, descriptors_2 ); /*
//-- Step 3: Matching descriptor vectors with a brute force matcher
BruteForceMatcher< L2<float> > matcher;
std::vector< DMatch > matches;
matcher.match( descriptors_1, descriptors_2, matches ); //-- Draw matches
Mat img_matches;
drawMatches( img_1, keypoints_1, img_2, keypoints_2, matches, img_matches ); //-- Show detected matches
imshow("Matches", img_matches );
*/ //-- Step 3: Matching descriptor vectors using FLANN matcher
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptors_1, descriptors_2, matches ); double max_dist = 0; double min_dist = 100; //-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descriptors_1.rows; i++ )
{
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
} printf("-- Max dist : %f \n", max_dist );
printf("-- Min dist : %f \n", min_dist ); //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist ) —— 阈值
//-- PS.- radiusMatch can also be used here.
std::vector< DMatch > good_matches; for( int i = 0; i < descriptors_1.rows; i++ )
{
if( matches[i].distance < 2*min_dist )
{
good_matches.push_back( matches[i]); // 在匹配源头限制
}
} //-- Draw only "good" matches
Mat img_matches;
drawMatches( img_1, keypoints_1, img_2, keypoints_2,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); //-- Show detected matches
imshow( "Good Matches", img_matches ); //-- Localize the object from img_1 in img_2
std::vector<Point2f> obj;
std::vector<Point2f> scene; for( int i = 0; i < good_matches.size(); i++ )
{
//-- Get the keypoints from the good matches
obj.push_back( keypoints_1[ good_matches[i].queryIdx ].pt );
scene.push_back( keypoints_2[ good_matches[i].trainIdx ].pt );
} Mat H = findHomography( obj, scene, CV_RANSAC ); // findHomography 函数是求两幅图像的单应性矩阵,它是一个3*3的矩阵 //-- Get the corners from the image_1 ( the object to be "detected" )
Point2f obj_corners[4] = { cvPoint(0,0), cvPoint( img_1.cols, 0 ), cvPoint( img_1.cols, img_1.rows ), cvPoint( 0, img_1.rows ) };
Point scene_corners[4]; //-- Map these corners in the scene ( image_2)
for( int i = 0; i < 4; i++ )
{
double x = obj_corners[i].x;
double y = obj_corners[i].y; double Z = 1./( H.at<double>(2,0)*x + H.at<double>(2,1)*y + H.at<double>(2,2) );
double X = ( H.at<double>(0,0)*x + H.at<double>(0,1)*y + H.at<double>(0,2) )*Z;
double Y = ( H.at<double>(1,0)*x + H.at<double>(1,1)*y + H.at<double>(1,2) )*Z;
scene_corners[i] = cvPoint( cvRound(X) + img_1.cols, cvRound(Y) );
} //-- Draw lines between the corners (the mapped object in the scene - image_2 )
line( img_matches, scene_corners[0], scene_corners[1], Scalar(0, 255, 0), 2 );
line( img_matches, scene_corners[1], scene_corners[2], Scalar( 0, 255, 0), 2 );
line( img_matches, scene_corners[2], scene_corners[3], Scalar( 0, 255, 0), 2 );
line( img_matches, scene_corners[3], scene_corners[0], Scalar( 0, 255, 0), 2 ); //-- Show detected matches
imshow( "Good Matches & Object detection", img_matches ); waitKey(0); return 0;
} /**
* @function readme
*/
void readme()
{ std::cout << " Usage: ./SURF_descriptor <img1> <img2>" << std::endl; }

利用findHomography函数利用匹配的关键点找出相应的变换,再利用perspectiveTransform函数映射点群。

 

转自:http://blog.csdn.net/yang_xian521/article/details/6901762

OPENCV(6) —— 角点检测的更多相关文章

  1. 【OpenCV】角点检测:Harris角点及Shi-Tomasi角点检测

    角点 特征检测与匹配是Computer Vision 应用总重要的一部分,这需要寻找图像之间的特征建立对应关系.点,也就是图像中的特殊位置,是很常用的一类特征,点的局部特征也可以叫做“关键特征点”(k ...

  2. OpenCV Shi-Tomasi角点检测子

    Shi-Tomasi角点检测子 目标 在这个教程中我们将涉及: 使用函数 goodFeaturesToTrack 来调用Shi-Tomasi方法检测角点. 理论 代码 这个教程的代码如下所示.源代码还 ...

  3. OpenCV Harris 角点检测子

    Harris 角点检测子 目标 本教程中我们将涉及: 有哪些特征?它们有什么用? 使用函数 cornerHarris 通过 Harris-Stephens方法检测角点. 理论 有哪些特征? 在计算机视 ...

  4. Opencv Shi-Tomasi角点检测

    #include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...

  5. Opencv Harris角点检测

    #include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...

  6. OpenCV 之 角点检测

    角点 (corners) 的定义有两个版本:一是 两条边缘的交点,二是 邻域内具有两个主方向的特征点. 一般而言,角点是边缘曲线上曲率为极大值的点,或者 图像亮度发生剧烈变化的点.例如,从人眼角度来看 ...

  7. opencv::自定义角点检测

    #include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespac ...

  8. opencv笔记6:角点检测

    time:2015年10月09日 星期五 23时11分58秒 # opencv笔记6:角点检测 update:从角点检测,学习图像的特征,这是后续图像跟踪.图像匹配的基础. 角点检测是什么鬼?前面一篇 ...

  9. opencv: 角点检测源码分析;

    以下6个函数是opencv有关角点检测的函数 ConerHarris, cornoerMinEigenVal,CornorEigenValsAndVecs, preConerDetect, coner ...

随机推荐

  1. 继续过Hard题目.周五

      # Title Editorial Acceptance Difficulty Frequency   . 65 Valid Number     12.6% Hard    . 126 Word ...

  2. 多线程相互排斥--mutex

    多线程之线程同步Mutex (功能与Critial Sections同样,可是属于内核对象,訪问速度较慢.能够被不同进程调用) 一 Mutex     相互排斥对象(mutex)内核对象可以确保线程拥 ...

  3. poj2280--Amphiphilic Carbon Molecules(扫描线+极角排序+转换坐标)

    题目链接:id=2280">点击打开链接 题目大意:给出n个点的坐标.每一个点有一个值0或者1,如今有一个隔板(无限长)去分开着n个点,一側统计0的个数,一側统计1的个数,假设点在板上 ...

  4. mysql-汇总(聚集)函数

    我们需要汇总数据而不用把他们实际检索出来,他们主要用来进行分析和报表数据的生成. 1.AVG:通过对表中行数计数并计算特定列值之和,求得该列的平均值.可用来返回所有列的平均值,也可以用来返回特定列或行 ...

  5. 【POJ 1845】 Sumdiv (整数唯分+约数和公式+二分等比数列前n项和+同余)

    [POJ 1845] Sumdiv 用的东西挺全 最主要通过这个题学了约数和公式跟二分求等比数列前n项和 另一种小优化的整数拆分  整数的唯一分解定理: 随意正整数都有且仅仅有一种方式写出其素因子的乘 ...

  6. Redis的好处知识

    参考文章 http://www.cnblogs.com/wupeiqi/articles/5132791.html 使用Redis有哪些好处? () 速度快,因为数据存在内存中,类似于HashMap, ...

  7. 图论之堆优化的Prim

    本题模板,最小生成树,洛谷P3366 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边 ...

  8. 如何让alertdialog选择完后自动关闭

    builder.setIcon(R.drawable.ic_system) .setTitle("串口号") .setSingleChoiceItems(mPorts, mSele ...

  9. Python开源爬虫项目代码:抓取淘宝、京东、QQ、知网数据--转

    数据来源:数据挖掘入门与实战  公众号: datadw scrapy_jingdong[9]- 京东爬虫.基于scrapy的京东网站爬虫,保存格式为csv.[9]: https://github.co ...

  10. Ionic2中的Navigation.md

    1. 概述 为了能够得到同原生应用类似的导航效果,Ionic创建了几个navagation组件来实现pages之间的导航操作,这种导航跟原生Angular2中的route机制是不一样的,我们可以借助于 ...