给出一个实现非极大值抑制的C++程序
时间: 2024-04-19 14:29:00 浏览: 82
当然可以!以下是一个简单的C++程序,用于实现非极大值抑制(Non-Maximum Suppression)的算法,常用于边缘检测中:
```cpp
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat nonMaximumSuppression(const Mat& magnitude, const Mat& gradient)
{
Mat nmsImage = magnitude.clone();
for (int i = 1; i < magnitude.rows - 1; i++)
{
for (int j = 1; j < magnitude.cols - 1; j++)
{
float angle = gradient.at<float>(i, j);
// 根据梯度方向判断上下或左右两个像素是否为局部最大值
float q = 255, r = 255;
if ((angle >= 0 && angle < 45) || (angle >= 180 && angle < 225))
{
q = magnitude.at<float>(i, j + 1);
r = magnitude.at<float>(i, j - 1);
}
else if ((angle >= 45 && angle < 90) || (angle >= 225 && angle < 270))
{
q = magnitude.at<float>(i + 1, j);
r = magnitude.at<float>(i - 1, j);
}
else if ((angle >= 90 && angle < 135) || (angle >= 270 && angle < 315))
{
q = magnitude.at<float>(i + 1, j + 1);
r = magnitude.at<float>(i - 1, j - 1);
}
else if ((angle >= 135 && angle < 180) || (angle >= 315 && angle < 360))
{
q = magnitude.at<float>(i - 1, j + 1);
r = magnitude.at<float>(i + 1, j - 1);
}
// 如果当前像素不是局部最大值,则将其置为0
if (magnitude.at<float>(i, j) <= q || magnitude.at<float>(i, j) <= r)
{
nmsImage.at<float>(i, j) = 0;
}
}
}
return nmsImage;
}
int main()
{
Mat inputImage = imread("input.jpg", IMREAD_GRAYSCALE); // 替换为你的输入图像的文件名
if (inputImage.empty())
{
cout << "无法读取输入图像!" << endl;
return -1;
}
Mat dx, dy;
Sobel(inputImage, dx, CV_32F, 1, 0); // 计算x方向的梯度
Sobel(inputImage, dy, CV_32F, 0, 1); // 计算y方向的梯度
Mat magnitude, gradient;
cartToPolar(dx, dy, magnitude, gradient); // 将梯度转换为幅值和角度
Mat nmsImage = nonMaximumSuppression(magnitude, gradient);
namedWindow("Input Image", WINDOW_NORMAL);
namedWindow("Non-Maximum Suppression", WINDOW_NORMAL);
imshow("Input Image", inputImage);
imshow("Non-Maximum Suppression", nmsImage);
waitKey(0);
return 0;
}
```
请确保已经安装了OpenCV库,并根据需要修改`imread`函数中的文件名。这个程序加载了一个灰度图像文件,然后计算图像的梯度信息,并使用非极大值抑制算法对梯度幅值进行处理,以提取边缘信息。最后,显示原始图像和应用非极大值抑制后的图像。
阅读全文