本系列代码托管于:https://github.com/chintsan-code/opencv4-tutorials
本篇使用的项目为:corner_detect
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void harris_demo(Mat &image);
void shitomas_demo(Mat &image);
int main(int argc, const char** argv) {
VideoCapture capture("../sample/color_object.mp4");
if (!capture.isOpened()) {
printf("could not open the camera...\n");
}
namedWindow("frame", WINDOW_AUTOSIZE);
Mat frame;
while (true) {
bool ret = capture.read(frame);
if (!ret) break;
imshow("frame", frame);
shitomas_demo(frame);
imshow("result", frame);
char c = waitKey(1);
if (c == 27) { // ESC
break;
}
}
capture.release();
waitKey(0);
destroyAllWindows();
return 0;
}
void harris_demo(Mat &image) {
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY);
Mat dst;
double k = 0.04;
int blocksize = 2;
int ksize = 3;
cornerHarris(gray, dst, blocksize, ksize, k);
Mat dst_norm = Mat::zeros(dst.size(), dst.type());
normalize(dst, dst_norm, 0, 255, NORM_MINMAX, -1, Mat());
convertScaleAbs(dst_norm, dst_norm);
// draw corners
RNG rng(12345);
for (int row = 0; row < image.rows; row++) {
for (int col = 0; col < image.cols; col++) {
int rsp = dst_norm.at<uchar>(row, col);
if (rsp > 150) {
int b = rng.uniform(0, 255);
int g = rng.uniform(0, 255);
int r = rng.uniform(0, 255);
circle(image, Point(col, row), 5, Scalar(b, g, r), 2, 8, 0);
}
}
}
}
void shitomas_demo(Mat &image) {
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY);
vector<Point2f> corners;
double quality_level = 0.01;
RNG rng(12345);
goodFeaturesToTrack(gray, corners, 200, quality_level, 3, Mat(), 3, false);
for (int i = 0; i < corners.size(); i++) {
int b = rng.uniform(0, 255);
int g = rng.uniform(0, 255);
int r = rng.uniform(0, 255);
circle(image, corners[i], 5, Scalar(b, g, r), 2, 8, 0);
}
}
角点定义
在X方向和Y方向都有最大的梯度变化的像素点
cornerHarris:Harris角点检测
void cornerHarris( InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType = BORDER_DEFAULT );
- src:输入图像,单通道的8-bit或浮点图像
- dst:存储着Harris角点检测的图像矩阵,与src具有相同的尺寸,类型为CV_32FC1
- blockSize:邻域大小
- ksize:Sobel算子的卷积核尺寸
- k:Harris角点检测器中的k,一般取值0.04~0.06
- borderType:边缘处理方式
\(\lambda_1和\lambda_2都比较小,认为是平坦区域(FlatRegion)\)
\(\lambda_1>>\lambda_2或\lambda_2>>\lambda_1,认为是边缘(Edge)\)
\(\lambda_1和\lambda_2都比较大是,才认为是角点(Corner)\)
goodFeaturesToTrack:Shi-tomasi角点检测
Shi-tomasi是对Harris角点检测计算的简化
void goodFeaturesToTrack( InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask = noArray(), int blockSize = 3, bool useHarrisDetector = false, double k = 0.04 );
- image: 输入图像,单通道的8-bit或32-bit浮点图像
- corners:角点,vector
- maxCorners:最多检测多少角点,如果设为0或负数,检测全部
- qualityLevel:用于过滤角点。例如最佳角点的响应为1500,qualityLevel为0.01,那么响应小于15的角点都会被过滤掉
- minDistance:角点间的最小距离,用于过滤。如果小于这个值,就认为是同一个角点
- mask:掩模
- blockSize:邻域大小
- useHarrisDetector:使用Harris角点检测
- k:Harris角点检测器中的k,一般取值0.04~0.06。只有在使用Harris角点检测器时才起作用
计算\(min(\lambda_1,\lambda_2)\)超过一定阈值即认为是角点
评论 (0)