Opencv 分水岭算法C++
时间: 2023-11-14 11:18:47 浏览: 81
OpenCV 中的分水岭算法可以用于图像分割,将图像分成不同的区域。下面是一个基本的 C++ 代码示例:
```c++
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("input.png", IMREAD_GRAYSCALE);
if (img.empty())
{
cerr << "Error: Unable to load image!" << endl;
return -1;
}
// 对图像进行二值化处理
Mat binary;
threshold(img, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
// 进行形态学操作
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(binary, binary, MORPH_OPEN, kernel);
// 计算距离变换
Mat distTransform;
distanceTransform(binary, distTransform, DIST_L2, 5);
// 构建标签图像
Mat labels;
connectedComponents(distTransform > 3, labels, 8);
// 将背景标签设为0
labels = labels + 1;
// 执行分水岭算法
watershed(img, labels);
// 将分割结果可视化
Mat output = Mat::zeros(img.size(), CV_8UC3);
for (int i = 0; i < labels.rows; i++)
{
for (int j = 0; j < labels.cols; j++)
{
int label = labels.at<int>(i, j);
if (label == -1)
{
output.at<Vec3b>(i, j) = Vec3b(0, 0, 255); // 红色
}
else if (label > 0 && label <= 2)
{
output.at<Vec3b>(i, j) = Vec3b(255, 0, 0); // 蓝色
}
else if (label > 2 && label <= 4)
{
output.at<Vec3b>(i, j) = Vec3b(0, 255, 0); // 绿色
}
else if (label > 4 && label <= 6)
{
output.at<Vec3b>(i, j) = Vec3b(255, 255, 0); // 青色
}
else if (label > 6 && label <= 8)
{
output.at<Vec3b>(i, j) = Vec3b(255, 0, 255); // 洋红色
}
else if (label > 8 && label <= 10)
{
output.at<Vec3b>(i, j) = Vec3b(0, 255, 255); // 黄色
}
else
{
output.at<Vec3b>(i, j) = Vec3b(255, 255, 255); // 白色
}
}
}
imshow("Input", img);
imshow("Output", output);
waitKey(0);
return 0;
}
```
在这个示例中,我们首先加载图像并对其进行二值化处理。然后进行形态学操作和距离变换,以便在后续的分水岭算法中使用。我们使用 `connectedComponents` 函数计算标签图像,然后将背景标签设为0。最后,我们执行分水岭算法,将分割结果可视化。
阅读全文