opencv python num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh) 如何将二值图像中的非连通域的区域变为黑色
时间: 2024-02-17 08:01:08 浏览: 17
可以使用以下代码将二值图像中的非连通域的区域变为黑色:
```python
import cv2
# 读取二值图像
img = cv2.imread('binary_image.png', 0)
# 进行连通域分析
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(img)
# 获取连通域的面积
area = stats[:, cv2.CC_STAT_AREA]
# 找到最大的连通域
max_area_label = area.argmax()
# 将非最大连通域的区域变为黑色
for i in range(num_labels):
if i != max_area_label:
img[labels == i] = 0
# 显示结果
cv2.imshow('result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
在上述代码中,我们首先读取二值图像并进行连通域分析,然后获取每个连通域的面积。接着,我们找到最大的连通域,并将非最大连通域的区域变为黑色。具体来说,我们遍历每个连通域的标签,如果该标签不是最大连通域的标签,就将对应的像素点设置为黑色。
相关问题
import numpy as np import cv2 as cv # 加载图片 img = cv.imread('4.jpg') # 灰度化 img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 二值化 ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY) # 寻找连通域 num_labels, labels, stats, centroids = cv.connectedComponentsWithStats(thresh, connectivity=8) # 计算平均面积 areas = list() for i in range(num_labels): areas.append(stats[i][-1]) print("轮廓%d的面积:%d" % (i, stats[i][-1])) area_avg = np.average(areas[1:-1]) print("轮廓平均面积:", area_avg) # 筛选超过平均面积的连通域 image_filtered = np.zeros_like(img) for (i, label) in enumerate(np.unique(labels)): # 如果是背景,忽略 if label == 0: continue if stats[i][-1] < area_avg : image_filtered[labels == i] = 255 #cv.imshow("image_filtered", image_filtered) #cv.imshow("img", img) cv.imwrite('4.jpg',image_filtered ) cv.waitKey() cv.destroyAllWindows(),将上述代码转化为c++形式
以下是将上述Python代码转化为C++形式的示例:
```cpp
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
// 加载图片
Mat img = imread("4.jpg");
// 灰度化
Mat img_gray;
cvtColor(img, img_gray, COLOR_BGR2GRAY);
// 二值化
Mat thresh;
threshold(img_gray, thresh, 127, 255, THRESH_BINARY);
// 寻找连通域
Mat labels, stats, centroids;
int num_labels = connectedComponentsWithStats(thresh, labels, stats, centroids, 8);
// 计算平均面积
vector<int> areas;
for (int i = 0; i < num_labels; i++) {
areas.push_back(stats.at<int>(i, CC_STAT_AREA));
cout << "轮廓" << i << "的面积:" << stats.at<int>(i, CC_STAT_AREA) << endl;
}
double area_avg = mean(Mat(areas))[0];
cout << "轮廓平均面积:" << area_avg << endl;
// 筛选超过平均面积的连通域
Mat image_filtered = Mat::zeros(img.size(), CV_8UC1);
for (int i = 1; i < num_labels; i++) {
if (stats.at<int>(i, CC_STAT_AREA) < area_avg) {
labels.setTo(0, labels == i);
} else {
image_filtered.setTo(255, labels == i);
}
}
// 显示结果
imshow("image_filtered", image_filtered);
imshow("img", img);
waitKey();
destroyAllWindows();
// 保存结果
imwrite("4.jpg", image_filtered);
return 0;
}
```
需要注意的是,C++中没有Python中的`list`类型,需要使用`vector`替代。同时,C++中没有Python中的`np.average()`方法,需要使用OpenCV的`mean()`方法计算平均值。此外,C++中的Mat类需要使用`.at()`方法访问元素,而不是Python中的下标索引。
使用cv2.threshold得到二值图像 二值图像中 计算白色区域 若白色区域面积小于4个像素 则将该区域变为黑色 opencv python
要将二值图像中小于4个像素的白色区域变为黑色,可以使用cv2.threshold()函数先将灰度图像二值化,然后使用cv2.connectedComponentsWithStats()函数来获取每个连通区域的面积,并通过遍历连通区域的方式找到小于4个像素的白色区域。具体实现如下:
``` python
import cv2
import numpy as np
# 读取灰度图像
img = cv2.imread('gray_image.png', cv2.IMREAD_GRAYSCALE)
# 将灰度图像二值化
ret, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 获取连通区域信息
ret, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity=8)
# 遍历连通区域
for i in range(1, ret):
# 获取当前连通区域的面积
area = stats[i, cv2.CC_STAT_AREA]
# 如果面积小于4个像素,则将该区域变为黑色
if area < 4:
labels[labels == i] = 0
# 将处理后的连通区域标签图转换为二值图像
img[labels == 0] = 0
img[labels > 0] = 255
# 显示结果
cv2.imshow('result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
在上述代码中,首先使用cv2.threshold()函数将灰度图像二值化。然后使用cv2.connectedComponentsWithStats()函数获取连通区域信息。接着遍历连通区域,获取每个连通区域的面积,如果面积小于4个像素,则将该区域在标签图中对应的像素值赋为0,也就是将该区域变为黑色。最后将处理后的标签图转换为二值图像,并显示结果。