OpenCV中的Harris角点检测:
C++:voidcornerHarris(InputArraysrc,OutputArraydst,intblockSize,intksize,doublek,intborderType=BORDER_DEFAULT)
参数的意义如下:
第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位或者浮点型图像。
第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放Harris角点检测的输出结果,和源图片有一样的尺寸和类型。
第三个参数,int类型的blockSize,表示邻域的大小,更多的详细信息在cornerEigenValsAndVecs()中有讲到。
第四个参数,int类型的ksize,表示Sobel()算子的孔径大小。
第五个参数,double类型的k,Harris参数。
第六个参数,int类型的borderType,图像像素的边界模式,注意它有默认值BORDER_DEFAULT。更详细的解释,参考borderInterpolate( )函数。
C++代码如下:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
Mat image;
Mat imageGray;
int thresh = 200;
int MaxThresh = 255;
void Trackbar(int, void*); //阈值控制
int main()
{
image = imread("E:\\testimage\\harris.jpg");
cvtColor(image, imageGray, CV_RGB2GRAY);
GaussianBlur(imageGray, imageGray, Size(5, 5), 1); // 滤波去噪
namedWindow("Corner Detected");
createTrackbar("threshold:", "Corner Detected", &thresh, MaxThresh, Trackbar);
imshow("Corner Detected", image);
//Trackbar(0, 0);
waitKey();
return 0;
}
void Trackbar(int, void*)
{
Mat dst, dst8u, dstshow, imageSource;
dst = Mat::zeros(image.size(), CV_32FC1);
imageSource = image.clone();
cornerHarris(imageGray, dst, 3, 3, 0.04, BORDER_DEFAULT);
normalize(dst, dst8u, 0, 255, CV_MINMAX); //归一化
convertScaleAbs(dst8u, dstshow);//将归一化得图线性变成8位无符号整形
imshow("dst", dstshow); //dst显示
for (int i = 0;i<image.rows;i++)
{
for (int j = 0;j<image.cols;j++)
{
if (dstshow.at<uchar>(i, j)>thresh+30) //阈值判断
{
circle(imageSource, Point(j, i), 2, Scalar(0, 0, 255), 2); //标注角点
}
}
}
imshow("Corner Detected", imageSource);
}
python代码如下:
import cv2
import numpy as np
img = cv2.imread("E:\\testimage\\harris.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
# 输入图像必须是 float32 ,最后一个参数在 0.04 到 0.05 之间
dst = cv2.cornerHarris(gray,2,3,0.04)
#result is dilated for marking the corners, not important
dst = cv2.dilate(dst,None)
# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]#这里是设定一个阈值 当大于这个阈值分数的都可以判定为角点
cv2.imshow('dst',img)
if cv2.waitKey(0) & 0xff == 27:
cv2.destroyAllWindows()