【OpenCV3经典编程100例】(24)2D特征:Harris角点检测cornerHarris()

一、2d特征相关知识

Learn about how to use the feature points detectors, descriptors and matching inside OpenCV.

1 什么是特征

在计算机视觉中,通常我们需要找到不同帧(图像)之间的匹配点。 为什么? 如果我们知道两个图像如何相互关联,我们可以使用这两个图像来提取信息。当我们说匹配点时,我们一般指的是场景中可以轻易识别的特征。它具有唯一可识别性。

2 图像特征的类型

    a)       边缘

    b)       角点(也称为感兴趣点)

    c)       斑点(也称为感兴趣区域)

3 角点

角点是两条边缘的交点,所以它表示这两条边的方向改变的点。 因此,图像的梯度(在两个方向上)具有很高的变化,这可用来进行角点检测。

角点没有明确的数学定义,但人们普遍认为角点是二维图像亮度变化剧烈的点或图像边缘曲线上曲率极大值的点。

角点是图像很重要的特征,对图像图形的理解和分析有很重要的作用。角点在保留图像图形重要特征的同时,可以有效地减少信息的数据量,使其信息的含量很高,有效地提高了计算的速度,有利于图像的可靠匹配,使得实时处理成为可能。

角点在三维场景重建、运动估计、目标跟踪、目标识别、图像配准与匹配等计算机视觉领域起着非常重要的作用。

扫描二维码关注公众号,回复: 1802608 查看本文章

4 角点检测

角点检测算法可归纳为3类:

    a)       基于灰度图像的角点检测

        1)       基于梯度

        2)       基于模板

        3)       基于模板梯度组合

    b)       基于二值图像的角点检测

    c)       基于轮廓曲线的角点检测

其中基于模板的方法主要考虑像素邻域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点。常见的基于模板的角点检测算法有Kitchen-Rosenfeld角点检测算法,Harris角点检测算法、KLT角点检测算法及SUSAN角点检测算法。和其他角点检测算法相比,SUSAN角点检测算法具有算法简单、位置准确、抗噪声能力强等特点。

5 Harris角点检测算法

Harris角点检测算法是一种基于灰度图像的角点检测算法。

二、opencv函数原型和参数解析

void cornerHarris(
	InputArray src,//输入图像,单通道8位或浮点图像
	OutputArray dst,//输出图像类型CV_32FC1,大小同原图像
	int blockSize,//邻域的大小
	int ksize,//Sobel算子的孔径大小
	double k,//Harris参数
	int borderType = BORDER_DEFAULT);//边界模式

三、c++示例代码

//包含头文件
#include <opencv2/opencv.hpp>
//命名空间
using namespace cv;
using namespace std;
//全局函数声明部分

//主函数
int main()
{
	//【1】载入图像
	Mat srcImage = imread("G:\\opencvtest\\testImage\\house.jpg");
	//【2】检查是否载入成功
	if (srcImage.empty())
	{
		printf("读取图片错误,请确认目录下是否有imread函数指定图片存在! \n ");
		return 0;
	}
	//【3】图像灰度化
	Mat grayImage;
	cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
	//【4】角点检测
	Mat dstImage = Mat::zeros(srcImage.size(), CV_32FC1);
	cornerHarris(grayImage, dstImage, 2, 3, 0.04);
	//【5】归一化与转换8UC1
	Mat normImage, scaledImage;
	normalize(dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
	convertScaleAbs(normImage, scaledImage);
	//【6】绘制角点
	for (int i = 0; i < normImage.rows; i++)
	{
		for (int j = 0; j < normImage.cols; j++) 
		{
			if ((int)normImage.at<float>(i, j) > 150)
			{
				circle(srcImage, Point(j, i), 5, Scalar(0, 0, 255), 2);
				circle(scaledImage, Point(j, i), 5, Scalar(0), 2);
			}
		}
	}
	//【7】显示图像
	imshow("24-彩色原图", srcImage);
	imshow("24-角点检测", scaledImage);
	//【8】保持窗口显示
	waitKey(0);
	return 0;
}

四、运行截图

1 彩色原图,检测到的角点画圆圈


2 亮度高于阈值的像素点画圆圈



猜你喜欢

转载自blog.csdn.net/misterjiajia/article/details/80820928