用C和C++,opencv实现连通区域标记的两遍扫描算法,最后结果以窗口显示
时间: 2024-05-06 15:20:29 浏览: 77
以下是用C++和OpenCV实现连通区域标记的两遍扫描算法的示例代码:
```
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("image.jpg", CV_LOAD_IMAGE_GRAYSCALE);
if (img.empty())
{
cout << "Could not open or find the image" << endl;
return -1;
}
int label = 1;
int num_labels = 0;
vector<int> labels(1000000, 0); // assuming max 1000x1000 image size
// First pass
for (int y = 0; y < img.rows; y++)
{
for (int x = 0; x < img.cols; x++)
{
if (img.at<uchar>(y, x) == 255) // if pixel is white
{
if (x == 0 && y == 0)
{
labels[label] = label;
label++;
}
else if (x == 0 && y != 0)
{
if (img.at<uchar>(y - 1, x) == 255)
labels[y * img.cols + x] = labels[(y - 1) * img.cols + x];
else
{
labels[label] = label;
labels[y * img.cols + x] = label;
label++;
}
}
else if (x != 0 && y == 0)
{
if (img.at<uchar>(y, x - 1) == 255)
labels[y * img.cols + x] = labels[y * img.cols + x - 1];
else
{
labels[label] = label;
labels[y * img.cols + x] = label;
label++;
}
}
else
{
if (img.at<uchar>(y, x - 1) == 255 && img.at<uchar>(y - 1, x) == 255)
{
labels[y * img.cols + x] = min(labels[y * img.cols + x - 1], labels[(y - 1) * img.cols + x]);
if (labels[y * img.cols + x - 1] != labels[(y - 1) * img.cols + x])
{
// Merge labels
int min_label = min(labels[y * img.cols + x - 1], labels[(y - 1) * img.cols + x]);
int max_label = max(labels[y * img.cols + x - 1], labels[(y - 1) * img.cols + x]);
for (int i = 0; i < img.rows * img.cols; i++)
{
if (labels[i] == max_label)
labels[i] = min_label;
}
}
}
else if (img.at<uchar>(y, x - 1) == 255)
labels[y * img.cols + x] = labels[y * img.cols + x - 1];
else if (img.at<uchar>(y - 1, x) == 255)
labels[y * img.cols + x] = labels[(y - 1) * img.cols + x];
else
{
labels[label] = label;
labels[y * img.cols + x] = label;
label++;
}
}
}
}
}
// Second pass
for (int y = 0; y < img.rows; y++)
{
for (int x = 0; x < img.cols; x++)
{
if (img.at<uchar>(y, x) == 255) // if pixel is white
{
int l = labels[y * img.cols + x];
if (l > 0)
{
if (labels[l] == l)
{
num_labels++;
labels[l] = num_labels;
}
else
labels[y * img.cols + x] = labels[l];
}
}
}
}
// Display result
Mat result(img.rows, img.cols, CV_8UC3, Scalar(0, 0, 0));
vector<Vec3b> colors(num_labels + 1);
for (int i = 0; i <= num_labels; i++)
{
colors[i] = Vec3b(rand() & 255, rand() & 255, rand() & 255);
}
for (int y = 0; y < img.rows; y++)
{
for (int x = 0; x < img.cols; x++)
{
if (img.at<uchar>(y, x) == 255) // if pixel is white
{
int l = labels[y * img.cols + x];
if (l > 0)
{
result.at<Vec3b>(y, x) = colors[l];
}
}
}
}
namedWindow("Result", WINDOW_NORMAL);
imshow("Result", result);
waitKey(0);
return 0;
}
```
该代码中的第一遍扫描使用了4个条件语句处理边界和邻域情况,第二遍扫描将标签替换为最小等价标签或新标签。最后,将每个区域分配一个随机颜色,并将结果显示在窗口中。
阅读全文