OpenCV基于C++,利用区域生长算法实现下图所示焊缝缺陷提取。其算法如下: (1)将图像转换为灰度图 (2)利用较高的阈值分割灰度图像,得到种子区域(threshold) (3)(重点)计算连通域的质心点,获得种子(connectedComponentsWithStats) (4)利用一个偏高的阈值(190)得到遮罩区域(threshold) (5)利用种子、遮罩区域,使用区域生长分割(floodFill),得到缺陷图。代码
时间: 2023-07-15 08:14:21 浏览: 111
基于C++的区域生长分割算法(单种子)设计与实现
以下是基于OpenCV的C++代码实现:
```cpp
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// 读入原始图像
Mat src = imread("welding.jpg");
// 转换为灰度图
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
// 较高阈值分割灰度图像,得到种子区域
Mat threshold_img;
threshold(gray, threshold_img, 50, 255, THRESH_BINARY);
// 计算连通域的质心点,获得种子
Mat labels, stats, centroids;
int num_labels = connectedComponentsWithStats(threshold_img, labels, stats, centroids);
// 偏高阈值得到遮罩区域
Mat mask;
threshold(gray, mask, 190, 255, THRESH_BINARY);
// 区域生长分割,得到缺陷图
Mat defect_img = Mat::zeros(src.size(), CV_8UC1);
for (int i = 1; i < num_labels; i++)
{
Point center(cvRound(centroids.at<double>(i, 0)), cvRound(centroids.at<double>(i, 1)));
if (mask.at<uchar>(center) > 0)
{
floodFill(defect_img, labels, center, 255);
}
}
// 显示结果
imshow("Original Image", src);
imshow("Defect Image", defect_img);
waitKey(0);
return 0;
}
```
其中,需要注意的是 `connectedComponentsWithStats()` 函数返回的标签矩阵中,像素值为 0 代表背景,像素值为 1 代表第一个连通域,以此类推。因此,需要从标签矩阵的第二个元素开始遍历。
阅读全文