角点检测方法_什么叫五点取样法

角点检测方法_什么叫五点取样法目录原理讲解【1】为何选取角点作为特征?【2】角点的定义:【3】判断角点的方法:【4】Harris角点检测法示例Opencv自带函数:cornerHarris()函数示例程序1示例程序2原理讲解【1】为何选取角点作为特征?角点是一种局部特征。角落上的可区分性特别强,边缘次之,平滑区域则基本没有区分性。【2】角点的定义:【3】判断角点的方法:这里有个细节:将计算的所有方向上的变化……

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

博主联系方式:
QQ:1540984562
QQ交流群:892023501
群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。

原理讲解

【1】为何选取角点作为特征?

角点是一种局部特征。
1
角落上的可区分性特别强,边缘次之,平滑区域则基本没有区分性。

【2】角点的定义:

2

【3】判断角点的方法:

3
这里有个细节:将计算的所有方向上的变化值平方和的最小值作为像素点的灰度变化特征值。为何是最小值呢?
分别对平均区域、边缘区域、角落区域进行计算,观察结果:
4
取最小值,这样边缘的特征值为0了,将边缘与角点区分开来。(边缘的特点是一个方向变化值不明显,与之垂直的方向变化值明显)
这种方法的缺点:
滑动窗口缺点:窗口滑动只有8个方向,当边缘角落的角度不在这8个方向上则检测不准。

【4】Harris角点检测法

Harris角点检测法使用特征值的方式,使得任何方向上的角点都可以被检测出来。
数学定义:
1
加权函数形式:高斯分布形式、均值函数形式
公式继续化简:
2
泰勒公式回顾:

1
由于图像是二元函数,这里只取,x和y方向上的一阶导数做近似。

3
海森矩阵:
1
矩阵
2
平原地区,四周望去皆是平坦,最陡峭和最不陡峭的地方陡峭程度差不多。
悬崖地区,水平方向上望去很平坦,从其垂直方向看去,十分陡峭。
站立山尖,四周皆是十分陡峭。
R称之为响应函数,k根据经验取0.02~0.04左右

示例

Opencv自带函数:cornerHarris()函数

void cornerHarris( InputArray src, OutputArray dst, int block Size,  int ksize, double k, int borderType = BORDER_DEFAULT)

1.InputArray类型的src,输入图像,即原图像,填Mat类型即可,且需要为单通道8位或者浮点型图像;
2.OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放Harris角点检测的输出结果,和原图片有一样的尺寸和类型;
3.int类型的blockSize,表示邻域的大小,更多详细信息在cornerEigenValsAndVecs()中讲到;
4.int类型的ksize,表示Sobel()算子的孔径的大小;
5.double类型的k,Harris参数;
6.int类型的borderType,图像像素的边界模式。注意它有默认值BORDER_DEFAULT;

示例程序1

int main()
{ 
   
	//改变控制台字体颜色
	system("color 02");
	
	//读取图像
	//Mat src_image = imread("D:\\opencv_picture_test\\霍夫变换\\霍夫变换.png", 0);
	Mat src_image = imread("D:\\opencv_picture_test\\角点检测\\五角星.jpg", 0);
	//出错判断
	if (!src_image.data)
	{ 
   
		cout << "src image load failed!" << endl;
		return -1;
	}
	//进行角点检测,找出角点
	Mat cornerStrength;
	cornerHarris(src_image, cornerStrength,2,3,0.03);

	//对灰度图进行阈值操作,得到二值图并显示
	Mat harrisCorner;
	threshold(cornerStrength, harrisCorner,0.00001,255,THRESH_BINARY);

	//显示
	namedWindow("角点图", WINDOW_NORMAL);
	imshow("角点图", cornerStrength);
	namedWindow("二值图", WINDOW_NORMAL);
	imshow("二值图", harrisCorner);
	waitKey(0);
	return 0;
}

需要注意的是:角点计算后需要进行二值化才能较好地可视化角点。最好是归一化一下。
原图:
原图
cornerStrength角点图:
cornerStrength
harrisCorner二值化后的角点图:
harrisCorner

示例程序2

#include <opencv2/opencv.hpp>
#include <iostream>
#include "windows.h"
#include <stdio.h>
#include <time.h>
#include <math.h> 
//#include "My_ImageProssing_base.h"
#define WINDOW_NAME1 "【程序窗口1】" 
#define WINDOW_NAME2 "【程序窗口2】" 
using namespace cv;
using namespace std;
RNG g_rng(12345);

//*--------------------------动态角点检测-------------------------------------*/

Mat g_srcImage, g_srcImage1, g_grayImage;
int thresh = 20;
int max_thresh = 205;
void on_CornerHarris(int ,void*);
int main()
{ 
   
	//改变控制台字体颜色
	system("color 02");
	
	//读取图像
	//Mat src_image = imread("D:\\opencv_picture_test\\霍夫变换\\霍夫变换.png", 0);
	g_srcImage = imread("D:\\opencv_picture_test\\角点检测\\五角星.jpg", 1);
	//出错判断
	if (!g_srcImage.data)
	{ 
   
		cout << "src image load failed!" << endl;
		return -1;
	}
	//namedWindow("原始图", WINDOW_NORMAL);
	//imshow("原始图", g_srcImage);
	g_srcImage1 = g_srcImage.clone();

	cvtColor(g_srcImage1, g_grayImage,COLOR_BGR2GRAY);

	//创建窗口和滑动条
	namedWindow(WINDOW_NAME1, WINDOW_NORMAL);
	createTrackbar("阈值",WINDOW_NAME1,&thresh,max_thresh, on_CornerHarris);
	//初始化回调函数
	on_CornerHarris(0,0);

	waitKey(0);
	return 0;
}
void on_CornerHarris(int, void*)
{ 
   
	//定义局部变量
	Mat dstImage;
	Mat normImage;	//归一化
	Mat scaleImage;	//线性变换后的八位无符号整型的图
	//初始化,清除上一次调用次函数时他们的值
	dstImage = Mat::zeros(g_srcImage.size(),CV_32FC1);
	g_srcImage1 = g_srcImage.clone();

	//进行角点检测,找出角点
	Mat cornerStrength;
	cornerHarris(g_grayImage, dstImage, 2, 3, 0.03);

	//归一化与转换
	normalize(dstImage, normImage,0,255,NORM_MINMAX,CV_32FC1,Mat());
	convertScaleAbs(normImage, scaleImage);	//将归一化后的图线性变换成8位无符号整数

	//进行绘制
	for (int j = 0;j < normImage.rows;j++)
	{ 
   
		for (int i = 0;i < normImage.rows;i++)
		{ 
   
			Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值
			if ((int)normImage.at<float>(j, i) > thresh+60)
			{ 
   
				circle(g_srcImage1,Point(i,j),5, color,2,8,0);
				circle(scaleImage, Point(i, j), 5, color, 2, 8, 0);
			}
		}
	}
	
	imshow(WINDOW_NAME1, g_srcImage1);
	imshow(WINDOW_NAME2, scaleImage);
}

需要注意的是,当阈值较小的时候,可能会“检测”出若干个角点,绘制时会卡住,所以需要限制一下,这里我们去最低为60。
效果:
1
2


参考资料:

《Opencv3编程入门.毛星云版》
《数字图像处理PPT.李竹版》

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/179489.html原文链接:https://javaforall.net

(0)
上一篇 2022年10月21日 下午1:46
下一篇 2022年10月21日 下午1:46


相关推荐

  • 1.5 密码学应用PKI体系

    1.5 密码学应用PKI体系1.5密码学应用PKI体系

    2022年8月22日
    9
  • TCP报文头部

    TCP报文头部TCP 包头详解主要学习端口号 三次握手 四次挥手 TCP 包头 TCP 报文固定长度 20 字节 可变长度 TCP 包头如下图所示 源端口 目标端口 计算机上的进程要和其他进程通信是要通过计算机端口的 而一个计算机端口某个时刻只能被一个进程占用 所以通过指定源端口和目标端口 就可以知道是哪两个进程需要通信 源端口 目标端口是用 16 位表示的 可推算计算机的端口个数为 2 16 个序列号

    2026年3月19日
    2
  • Modbus功能码及错误码说明

    Modbus功能码及错误码说明有效功能码说明 十进制 功能码说明 01 读取线圈状态 02 读取输入状态 03 读取保持寄存器 04 读取输入寄存器 05 强置单线圈 06 预置单寄存器 07 读取异常状态 08 回送诊断校验 09 编程 只用于 484 10 控询 11 读取事件计数 12 读取通信事件记录 13 编程 184 384 484 584 等 14 探寻 15 强置多线圈 16 预置多线圈 17 报告多寄存器 18 可使主机模拟编程功能

    2026年3月16日
    2
  • linux开放8080端口命令_centos开放80端口

    linux开放8080端口命令_centos开放80端口1.添加映射iptables-tnat-APREROUTING-ptcp–dport80-jREDIRECT–to-port8080-tnat:指出我要操作什么表.(不写就表示filter.默认是filter)-APREROUTING:A添加的意思.表示我要在PREROUTING中添加一个规则–dport80:如果请求80端…

    2026年1月17日
    3
  • 处理Simulink的代数环的方法为逐个添加一阶惯性环节

    处理Simulink的代数环的方法为逐个添加一阶惯性环节处理Simulink的代数环的方法为逐个添加一阶惯性环节。代数环实际上是微分方程的输入在第一步没有值,而如果串联一个积分器的话就可以有初值,从而避免。通过增加一个一个时步的惯性环节,实现在基本不改变输出的情况下避免代数环。测试是可行的。…

    2022年10月5日
    3
  • vue安装axios

    vue安装axiosVue使用axios

    2025年8月15日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号