使用Canny函数处理图像,x,y分别是3求出来的梯度,低阈值50,高阈值150代码
时间: 2024-10-11 14:12:01 浏览: 32
在使用Canny边缘检测算法处理图像时,你需要通过计算图像的梯度来确定哪些像素被认为是边缘。Canny算子通常包含以下几个步骤:
1. **高斯滤波**:首先,对图像应用高斯滤波器(gaussian blur),用于平滑并减少噪声,`x` 和 `y` 分别表示两个方向上的梯度。
```c++
cv::Mat img_blur; // 创建一个空矩阵存储高斯模糊后的结果
cv::GaussianBlur(src, img_blur, cv::Size(3, 3), 0);
```
这里的`src`是你原始的输入图像,`cv::Size(3, 3)`指定了3x3的高斯核大小。
2. **计算梯度**:然后计算图像在每个像素处的梯度强度和方向。`Sobel`操作可以做到这一点,例如:
```c++
cv::Mat grad_x, grad_y; // 存储水平和垂直方向的梯度
cv::Sobel(img_blur, grad_x, CV_64F, 1, 0); // 水平梯度
cv::Sobel(img_blur, grad_y, CV_64F, 0, 1); // 垂直梯度
```
3. **计算梯度幅值和方向**:
- 应用公式计算梯度幅值 `sqrt(grad_x * grad_x + grad_y * grad_y)`
- 将方向转换成弧度 `atan2(grad_y, grad_x)`
4. **非极大值抑制**(Non-Maximum Suppression, NMS):消除方向不是局部最大值的响应点。
5. **双阈值处理**:
- 找到大于高阈值 `150` 的像素,并标记为强边缘
- 对于小于低阈值 `50` 的像素,取消标记(除非它与强边缘相邻)
```c++
cv::Mat edges;
cv::Canny(img_blur, edges, 50, 150, 3); // 第三个参数是二阶导数检测的迭代次数
```
完整的代码片段如下:
```cpp
#include <opencv2/opencv.hpp>
// ...
cv::Mat src, img_blur, grad_x, grad_y, edges;
// ... (加载图片)
// ...
cv::GaussianBlur(src, img_blur, cv::Size(3, 3), 0);
cv::Sobel(img_blur, grad_x, CV_64F, 1, 0);
cv::Sobel(img_blur, grad_y, CV_64F, 0, 1);
cv::Mat grad_mag, angle;
grad_mag = cv::sqrt((grad_x * grad_x) + (grad_y * grad_y));
angle = cv::arctan2(grad_y, grad_x) / CV_PI * 180;
// ... (继续进行NMS和双阈值处理)
edges = cv::Canny(img_blur, edges, 50, 150, 3);
// ... (后续处理,保存结果等)
```
阅读全文