使用C++,C,opencv实现连通区域标记的两遍扫描算法,结果以窗口显示
时间: 2024-05-03 16:22:48 浏览: 18
以下是使用C++和OpenCV实现连通区域标记的两遍扫描算法的示例代码:
```c++
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("test.jpg", IMREAD_COLOR);
if (img.empty())
{
cerr << "Failed to read image" << endl;
return -1;
}
cvtColor(img, img, COLOR_BGR2GRAY); // 转换为灰度图像
int label = 1; // 初始化标记
for (int i = 0; i < img.rows; i++)
{
for (int j = 0; j < img.cols; j++)
{
if (img.at<uchar>(i, j) == 255) // 如果像素值是255(白色)
{
// 进行两遍扫描
if (i == 0 && j == 0)
{
img.at<uchar>(i, j) = label;
label++;
}
else if (i == 0 && j != 0)
{
if (img.at<uchar>(i, j - 1) == 0)
{
img.at<uchar>(i, j) = label;
label++;
}
else
{
img.at<uchar>(i, j) = img.at<uchar>(i, j - 1);
}
}
else if (i != 0 && j == 0)
{
if (img.at<uchar>(i - 1, j) == 0)
{
img.at<uchar>(i, j) = label;
label++;
}
else
{
img.at<uchar>(i, j) = img.at<uchar>(i - 1, j);
}
}
else
{
if (img.at<uchar>(i - 1, j) == 0 && img.at<uchar>(i, j - 1) == 0)
{
img.at<uchar>(i, j) = label;
label++;
}
else if (img.at<uchar>(i - 1, j) != 0 && img.at<uchar>(i, j - 1) == 0)
{
img.at<uchar>(i, j) = img.at<uchar>(i - 1, j);
}
else if (img.at<uchar>(i - 1, j) == 0 && img.at<uchar>(i, j - 1) != 0)
{
img.at<uchar>(i, j) = img.at<uchar>(i, j - 1);
}
else if (img.at<uchar>(i - 1, j) == img.at<uchar>(i, j - 1))
{
img.at<uchar>(i, j) = img.at<uchar>(i - 1, j);
}
else
{
img.at<uchar>(i, j) = img.at<uchar>(i - 1, j);
int min_label = min(img.at<uchar>(i, j - 1), img.at<uchar>(i - 1, j));
int max_label = max(img.at<uchar>(i, j - 1), img.at<uchar>(i - 1, j));
for (int k = 0; k < img.rows; k++)
{
for (int l = 0; l < img.cols; l++)
{
if (img.at<uchar>(k, l) == max_label)
{
img.at<uchar>(k, l) = min_label;
}
}
}
}
}
}
}
}
// 对每个连通区域进行标记
vector<int> labels;
for (int i = 0; i < img.rows; i++)
{
for (int j = 0; j < img.cols; j++)
{
if (img.at<uchar>(i, j) != 0)
{
int label = img.at<uchar>(i, j);
if (find(labels.begin(), labels.end(), label) == labels.end())
{
labels.push_back(label);
}
}
}
}
// 随机生成颜色
vector<Vec3b> colors(labels.size());
for (size_t i = 0; i < labels.size(); i++)
{
colors[i] = Vec3b(rand() % 256, rand() % 256, rand() % 256);
}
// 根据标记填充颜色
Mat output = Mat::zeros(img.size(), CV_8UC3);
for (int i = 0; i < img.rows; i++)
{
for (int j = 0; j < img.cols; j++)
{
if (img.at<uchar>(i, j) != 0)
{
int label = img.at<uchar>(i, j);
output.at<Vec3b>(i, j) = colors[label - 1];
}
}
}
namedWindow("Output", WINDOW_NORMAL);
imshow("Output", output);
waitKey(0);
return 0;
}
```
注意:该算法仅适用于二值图像。如果需要处理彩色图像,请先将其转换为灰度图像。