角点检测
在图像边缘中有一些特殊的像素点值得我们关注,那就是图像边缘的角点,这些角点更能反映出图像中对象的整体特征,基于角点周围的像素块生成特征描述可以更好的描述图像特征数据
Harris与Shi-Tomasi 的计算角点响应公式
Harris角点检测
对输入图像进行 Harris 边界检测。输出是一幅浮点值图像,大小与输入图像大小相同,浮点值越高,表明越可能是特征角点(也可以对图像进行阈值化)。
Harris角点检测的Api如下
cornerHarris(Mat src, Mat dst, int blockSize, int ksize, double k)
- src:单通道的8位或者浮点数图像
- dst:输出的每个像素点的响应值,CV_32F类型,大小与输入图像一致
- blockSize:根据特征向量计算矩阵M的大小,常见取值为2
- ksize:Sobel算子梯度计算 一般取值3
- k:系数大小,取值范围为0.02-0.04
用代码来展示
Mat m = Imgcodecs.imread("C:\\test\\shape.png");
HighGui.imshow("原始图片",m);
Mat gray = new Mat();
Imgproc.cvtColor(m,gray,Imgproc.COLOR_BGR2GRAY);
//角点发现
Mat harris = new Mat();
Imgproc.cornerHarris(gray,harris,2,3,0.04);
//绘制角点
float[] floats = new float[harris.cols()];
for (int i = 0; i < harris.rows() ; i++) {
harris.get(i,0,floats);
for (int j = 0; j < floats.length; j++) {
if (floats[j] > 0.01){//越接近于角点数值越大
System.out.println(floats[j] );
Imgproc.circle(m,new Point(j,i),5,new Scalar(255,0,255));
}
}
}
运行结果
Shi-Tomasi角点检测
Shi-Tomasi作为改进的算法也有很大应用场景,尤其是动态跟踪用的还比较多。
相关的函数Api如下
goodFeaturesToTrack(Mat image, MatOfPoint corners, int maxCorners, double qualityLevel, double minDistance, Mat mask, int blockSize, int gradientSize, boolean useHarrisDetector, double k)
- image:表示输入图像、类型为单通道8位或浮点数
- corner:输出得到的角点
- maxCorners:表示获取前N个最强的R值角点
- qualityLevel:它与最大值R相乘得到阈值T,低于他的全部舍去、取值范围 0~1
- minDistance:最终返回的角点之间的最小距离,小于这个距离将被舍去
- mask:用于指定输入图像中蚕吐角点计算的像素点。
- blockSize:计算矩阵M时候需要,通常为3
- useHarrisDetector:是否使用Harris角点检测
- k:当使用Harris角点才用得到
下面通过代码展示
Mat m = Imgcodecs.imread("C:\\test\\shape.png");
HighGui.imshow("原始图片",m);
Mat gray = new Mat();
Imgproc.cvtColor(m,gray,Imgproc.COLOR_BGR2GRAY);
//角点发现
MatOfPoint corners = new MatOfPoint();
Imgproc.goodFeaturesToTrack(gray,corners,15,0.5,10,new Mat(),3,false,0.04);
Point[] points = corners.toArray();
for (Point p :points) {
Imgproc.circle(m,p,5,new Scalar(0,0,255));
}