c++视觉检测-----角点检测
角点检测:cornerHarris()
cornerHarris()
函数是OpenCV中用于执行Harris角点检测的函数。Harris角点检测是一种用于检测图像中角点的技术,通常用于特征检测和图像匹配。以下是cornerHarris()
函数的用法:
void cornerHarris(InputArray src, // 输入图像(单通道、8位或32位浮点类型)OutputArray dst, // 输出角点响应图像,通常是32位浮点类型int blockSize, // 角点检测中的邻域大小(建议为2-3)int ksize, // Sobel算子的孔径大小(建议为3)double k, // Harris检测方程中的自由参数,一般取0.04 - 0.06int borderType = BORDER_DEFAULT
);
以下是参数的解释:
-
src
:输入图像,通常是单通道的8位或32位浮点型图像。 -
dst
:输出角点响应图像,通常是一个32位浮点型图像,用于存储检测到的角点的响应值。 -
blockSize
:指定角点检测时使用的邻域大小。它通常是2x2或3x3的小邻域。 -
ksize
:Sobel算子的孔径大小,用于计算图像梯度。 -
k
:Harris检测方程中的自由参数,一般取0.04到0.06之间的值。它决定了角点响应的敏感性。 -
borderType
:边界类型,通常设置为BORDER_DEFAULT
。
cornerHarris()
函数执行Harris角点检测,并将检测结果存储在dst
中。通常,你可以检查dst
中的响应值来确定图像中的角点位置。较高的响应值通常表示角点。
以下是一个简单的示例,演示如何使用cornerHarris()
函数执行Harris角点检测:
#include "opencv2/opencv.hpp"using namespace cv;int main()
{Mat srcImage = imread("1.jpg", IMREAD_GRAYSCALE);if (srcImage.empty()){std::cout << "Could not open or find the image!" << std::endl;return -1;}Mat cornerResponse;cornerHarris(srcImage, cornerResponse, 2, 3, 0.04);Mat cornerMap = Mat::zeros(cornerResponse.size(), CV_8UC1);double maxResponse;minMaxLoc(cornerResponse, 0, &maxResponse);for (int i = 0; i < cornerResponse.rows; i++){for (int j = 0; j < cornerResponse.cols; j++){if (cornerResponse.at<float>(i, j) > 0.01 * maxResponse){circle(cornerMap, Point(j, i), 5, Scalar(255), 2);}}}imshow("Corner Map", cornerMap);waitKey(0);return 0;
}
在此示例中,我们加载了一个灰度图像,然后使用cornerHarris()
函数进行角点检测。最后,我们在角点上绘制圆圈,将检测到的角点可视化。
使用本地相机进行角点检测
#include <opencv2/opencv.hpp>using namespace cv;// 滑块回调函数
void onTrackbar(int, void*);int main()
{VideoCapture cap(0);if (!cap.isOpened()){std::cerr << "Error: Could not open the camera." << std::endl;return -1;}Mat frame;Mat grayFrame;namedWindow("Harris Corner Detection", WINDOW_AUTOSIZE);int blockSize = 2;int ksize = 3;int k = 0.04;int thresholdValue = 100;int radius = 5;createTrackbar("Block Size", "Harris Corner Detection", &blockSize, 10, onTrackbar);createTrackbar("K-Size", "Harris Corner Detection", &ksize, 10, onTrackbar);createTrackbar("K Value", "Harris Corner Detection", &k, 100, onTrackbar);createTrackbar("Threshold", "Harris Corner Detection", &thresholdValue, 1000, onTrackbar);createTrackbar("Radius", "Harris Corner Detection", &radius, 20, onTrackbar);while (true){cap >> frame;if (frame.empty()){break;}cvtColor(frame, grayFrame, COLOR_BGR2GRAY);Mat cornerResponse;cornerHarris(grayFrame, cornerResponse, blockSize * 2 + 2, ksize * 2 + 1, k / 100.0);Mat cornerMap = Mat::zeros(cornerResponse.size(), CV_8UC1);double maxResponse;minMaxLoc(cornerResponse, 0, &maxResponse);for (int i = 0; i < cornerResponse.rows; i++){for (int j = 0; j < cornerResponse.cols; j++){if (cornerResponse.at<float>(i, j) > thresholdValue / 1000.0 * maxResponse){circle(cornerMap, Point(j, i), radius, Scalar(255), 2);}}}imshow("Harris Corner Detection", cornerMap);if (waitKey(30) >= 0){break;}}return 0;
}void onTrackbar(int, void*)
{// You can add custom behavior when trackbars are moved if needed.
}
使用本地相机进行二值图角点检测
#include <opencv2/opencv.hpp>using namespace cv;Mat frame; // 用于存储摄像头捕捉的帧
Mat cornerResponse; // 存储Harris角点响应
Mat cornerMap; // 二值图像
double maxResponse; // 最大响应值int main()
{VideoCapture cap(0); // 打开默认相机(通常是内置摄像头)if (!cap.isOpened()){std::cerr << "Error: Could not open the camera." << endl;return -1;}namedWindow("Harris Corner Map", WINDOW_AUTOSIZE);while (true){cap >> frame; // 从摄像头捕捉帧if (frame.empty()){break;}// 转换为灰度图像Mat gray;cvtColor(frame, gray, COLOR_BGR2GRAY);// Harris角点检测cornerHarris(gray, cornerResponse, 2, 3, 0.04);// 查找最大响应值minMaxLoc(cornerResponse, 0, &maxResponse);// 初始化二值图像cornerMap = Mat::zeros(cornerResponse.size(), CV_8UC1);// 根据阈值将角点标记为白色或黑色for (int i = 0; i < cornerResponse.rows; i++){for (int j = 0; j < cornerResponse.cols; j++){if (cornerResponse.at<float>(i, j) > 0.01* maxResponse){cornerMap.at<uchar>(i, j) = 255;}else{cornerMap.at<uchar>(i, j) = 0;}}}imshow("Harris Corner Map", cornerMap);if (waitKey(30) == 27) // 按下Esc键退出{break;}}cap.release();destroyAllWindows();return 0;
}