opencv4.1.2+contrib win10 VS2019
算法基础
角点是一类比较特殊的点,构成角点的条件两条或者多条线的交叉,线可以理解为边缘特征很强的像素点的集合,在opencv
中大部分的图像处理基于掩膜移动来实现,在矩形框内如果在没有角点的区域内也就是所谓的平原地带,无论向哪个方向移动,矩形框内圈住的内容的梯度变化都不大,如果矩形框处在单边缘线上,矩形框移动时只能在一个方向产生较大的梯度变化,不构成角。矩形框框住角点,矩形框的移动会造成各个方向梯度的变化。
计算点x
方向与y
方向梯度,某个点在x
与y
方向梯度变化都很大,证明该点为角点。梯度(某个方向变化最快的方向)
API介绍
void cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT)
参数介绍
- InputArray类型的src,输入图像,即原图像,填
Mat
类单通道浮点型图像; - OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放
Harris
角点检测的输出结果,和原图片有一样的尺寸和类型; - int类型的blockSize,表示邻域的大小,更多详细信息在
cornerEigenValsAndVecs()
中讲到; - int类型的ksize,表示
Sobel()
算子的孔径的大小; - double类型的k,
Harris
参数; - int类型的borderType,图像像素的边界模式。注意它有默认值
BORDER_DEFAULT
代码演示
#include <iostream>
#include <opencv2/opencv.hpp>
#include <math.h>
using namespace std;
using namespace cv;
#define Pic_Path "E:\\picture\\"
#define Pic_Name "harris1.jpg"
Mat src;
void Harris_Demo(int, void*);
int main(void)
{
Mat gray_src;
int cur_value = 180;
int max_value = 255;
string pic = string(Pic_Path) + string(Pic_Name);
cout << "图片详细信息:" << pic << endl;
src = imread(pic);
if (src.empty())
{
cout << "图片不存在" << endl;
return -1;
}
namedWindow("原始图片", WINDOW_AUTOSIZE);
imshow("原始图片", src);
cvtColor(src, gray_src, COLOR_BGR2GRAY); //原始图片转化为灰度图
createTrackbar("调整", "原始图片", &cur_value, max_value, Harris_Demo, &gray_src);
waitKey(0);
destroyAllWindows();
return 0;
}
//角点检测算法部分
void Harris_Demo(int cur_value, void* gray_src)
{
Mat harris_src,norm_dst, norm_src, scale_dst,harris_dst;
copyTo(*(Mat*)(gray_src), harris_src,Mat()); //获取灰度图像
norm_src = Mat::zeros(harris_src.size(), CV_32FC1); //创建画布 用于承装harris计算结果
int ksize = 13; //算子size
int blocksize = 2; //邻域size
double k = 0.04; //典型值
cornerHarris(harris_src, norm_src, blocksize, ksize, k, BORDER_DEFAULT); //计算获取角点值
normalize(norm_src, norm_dst, 0, 255, NORM_MINMAX, CV_32FC1,Mat()); //进行归一化 原始值有负值 乱七八糟 后期不好处理
convertScaleAbs(norm_dst, scale_dst); //将计算结果转化为8位无符号
copyTo(src, harris_dst, Mat()); //复制原始图像 用来在上面做标记
//绘制角点 在角点的位置进行画圈标记
for(size_t i=0;i<scale_dst.rows;i++)
for (size_t j = 0; j < scale_dst.cols; j++)
{
if (scale_dst.at<uchar>(i, j) > cur_value)
{
circle(harris_dst, Point(j, i), 5, Scalar(0, 0, 255), 1, 8, 0);
}
}
//显示检测结果
namedWindow("角点检测", WINDOW_AUTOSIZE);
imshow("角点检测", harris_dst);
}
运行结果
参考链接:https://www.cnblogs.com/klitech/p/5779600.html
参考链接:https://blog.csdn.net/qq_18343569/article/details/48006093
参考链接:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/features2d/trackingmotion/harris_detector/harris_detector.html
参考链接:https://blog.csdn.net/weixin_42018112/article/details/88079998