Canny边缘算子
cv::Canny()
是OpenCV库中用于执行Canny边缘检测的函数。Canny边缘检测是一种广泛使用的图像处理技术,用于检测图像中的边缘。
以下是cv::Canny()
函数的一般用法和参数:
void cv::Canny(cv::InputArray image, // 输入图像,通常是灰度图像cv::OutputArray edges, // 输出的边缘图像double threshold1, // 低阈值double threshold2, // 高阈值int apertureSize = 3, // Sobel算子的大小,通常为3bool L2gradient = false // 是否使用L2范数
);
image
: 输入图像,通常是灰度图像。edges
: 输出的边缘图像,边缘像素将被标记为白色,非边缘像素将被标记为黑色。threshold1
和threshold2
: 低阈值和高阈值。这两个阈值用于控制边缘检测的灵敏度。通常,threshold1
设置为较低的值,而threshold2
设置为较高的值。如果图像梯度幅值高于threshold2
,则被认为是强边缘。如果图像梯度幅值介于threshold1
和threshold2
之间,且与强边缘相连,则被认为是弱边缘。apertureSize
: Sobel算子的大小,通常为3,表示使用3x3的Sobel核进行梯度计算。L2gradient
: 是否使用L2范数计算图像梯度,默认为false
。如果设置为true
,则使用更精确但计算量更大的L2范数,否则使用默认的L1范数。
cv::Canny()
函数通过计算图像的梯度,并根据阈值将像素分为强边缘和弱边缘,最终生成边缘图像。你可以根据具体应用的需求调整阈值和其他参数以获得最佳的边缘检测效果。
以下是一个简单的C++示例,演示如何使用OpenCV的Canny函数来进行边缘检测:
#include <opencv2/opencv.hpp>int main() {// 读取输入图像cv::Mat inputImage = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);if (inputImage.empty()) {std::cerr << "Error: Could not read the input image." << std::endl;return -1;}// 创建输出图像cv::Mat edgeImage;// 设置Canny边缘检测的参数double lowThreshold = 50; // 低阈值double highThreshold = 150; // 高阈值int apertureSize = 3; // Sobel算子的孔径大小bool L2gradient = false; // 是否使用L2范数// 应用Canny边缘检测cv::Canny(inputImage, edgeImage, lowThreshold, highThreshold, apertureSize, L2gradient);// 显示原始图像和边缘图像cv::imshow("Original Image", inputImage);cv::imshow("Canny Edge Detection", edgeImage);cv::waitKey(0);return 0;
}
使用相机实时canny 算子边缘检测
#include <opencv2/opencv.hpp>cv::Mat inputImage;
cv::Mat edges;int lowThreshold = 50;
int maxLowThreshold = 200;void updateCanny(int, void*) {cv::Canny(inputImage, edges, lowThreshold, lowThreshold * 3, 3);cv::imshow("Canny Edges", edges);
}int main() {cv::VideoCapture cap(0); // 打开本地相机(通常为0)if (!cap.isOpened()) {std::cerr << "Error: Could not open the camera." << std::endl;return -1;}cv::namedWindow("Canny Edges", cv::WINDOW_NORMAL);cv::createTrackbar("Low Threshold", "Canny Edges", &lowThreshold, maxLowThreshold, updateCanny);while (true) {cap >> inputImage;if (inputImage.empty()) {break;}updateCanny(0, 0);char key = cv::waitKey(10);if (key == 27) { // 按下ESC键退出循环break;}}cap.release();cv::destroyAllWindows();return 0;
}