工程需要,但是不能用matlab,所以用Opencv实现了一下bridge,也不难。
一. bridge操作的定义
在官方文档https://cn.mathworks.com/help/images/ref/bwmorph.html中,bridge操作的定义如下: Bridges unconnected pixels, that is, sets 0-valued pixels to 1 if they have two nonzero neighbors that are not connected. For example: 1 0 0 1 0 1 0 0 1 becomes 1 1 0 1 1 1 0 1 1 也就是说,在一个二值化后的图像中,对于任意一个值为0的像素点,如果它周围(4连通或8连通)存在至少2个值为1且属于不同连通区域的像素点,则把这个像素点值修改为1。
二. 实现思路
按照定义把所有值为0的像素点都走一遍就ok了,注意每次修改后,需要更新连通区域的信息。
三. 代码实现
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <set>
using namespace cv;
using namespace std;
const int dx[] = {
0,
1,
0, -
1,
1, -
1,
1, -
1 };
const int dy[] = {
1,
0, -
1,
0,
1, -
1, -
1,
1 };
set<int> get_neighbors1(Mat src, Mat label_mat,
int x,
int y,
int connectivity =
8) {
set<int> neighbors;
for (
int i =
0; i < connectivity; ++i) {
int tmp_x = x + dx[i];
int tmp_y = y + dy[i];
if (tmp_x >=
0 && tmp_x < src.rows &&
tmp_y >=
0 && tmp_y < src.cols &&
src.at<uchar>(tmp_x, tmp_y) ==
255) {
neighbors.insert(label_mat.at<
int>(tmp_x, tmp_y));
}
}
return neighbors;
}
void bridge(Mat src, Mat &dst,
int connectivity =
8) {
Mat label_mat;
connectedComponents(src, label_mat, connectivity);
dst = src.clone();
for (
int i =
0; i < src.rows; ++i) {
for (
int j =
0; j < src.cols; ++j) {
uchar pixel = src.at<uchar>(i, j);
if (pixel ==
0) {
if (get_neighbors1(src, label_mat, i, j,
4).size() >=
2) {
dst.at<uchar>(i, j) =
255;
connectedComponents(dst, label_mat, connectivity);
}
}
}
}
}
int main() {
Mat image = imread(
"C:\\Users\\whai\\Desktop\\1.png");
cvtColor(image, image, COLOR_BGR2GRAY);
imshow(
"修复前", image);
waitKey();
Mat dst;
bridge(image, dst,
4);
imshow(
"修复后", dst);
imwrite(
"C:\\Users\\whai\\Desktop\\2.png", dst);
waitKey();
return 0;
}
四. 效果
bridge前
bridge后
转载请注明原文地址: https://ju.6miu.com/read-658852.html