使用opencv计算二进制掩码中的分离形状区域
Calculating separated shapes area in a binary mask with opencv
我正在尝试检测人体面具,但我的算法有时会出错,如下图所示。我在想,如果我可以计算图像中单个形状的面积(连接的白色像素),我可以只保留最大的一个,我的问题就会得到解决。有办法吗?
为此,您可以使用 OpenCV 中的 connectedComponents 函数。
retval, labels=cv.connectedComponents(image[, labels[, connectivity[, ltype]]])
有关此功能的更多详细信息,请参阅文档。输出图像是一个标记图像,其中每个连接的组件都被赋予一个标签。
输出 retval 是标签的总数(也是连接组件的数量)。
那么你所要做的就是遍历连接的组件以找到像素最多的组件。
您还可以使用 cv2.findContours() 来获取每个白色斑点的轮廓。等高线有很多额外的属性,你可以在这里找到:
https://docs.opencv.org/master/d1/d32/tutorial_py_contour_properties.html
这包括获取他们的内部区域。
import cv2
import numpy as np
# load image
img = cv2.imread("outline.png");
# set as binary mask
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);
mask = cv2.inRange(gray, 155, 255);
# contours # if you're using OpenCV 3* then it returns as _, contours, _
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);
# find the biggest contour
biggest = None;
biggest_area = -1;
for con in contours:
area = cv2.contourArea(con);
if biggest_area < area:
biggest_area = area;
biggest = con;
# draw the new contour
redraw = np.zeros_like(img);
cv2.drawContours(redraw, [biggest], -1, (100, 150, 0), -1);
# show
cv2.imshow("Biggest", redraw);
cv2.waitKey(0);
我正在尝试检测人体面具,但我的算法有时会出错,如下图所示。我在想,如果我可以计算图像中单个形状的面积(连接的白色像素),我可以只保留最大的一个,我的问题就会得到解决。有办法吗?
为此,您可以使用 OpenCV 中的 connectedComponents 函数。
retval, labels=cv.connectedComponents(image[, labels[, connectivity[, ltype]]])
有关此功能的更多详细信息,请参阅文档。输出图像是一个标记图像,其中每个连接的组件都被赋予一个标签。 输出 retval 是标签的总数(也是连接组件的数量)。
那么你所要做的就是遍历连接的组件以找到像素最多的组件。
您还可以使用 cv2.findContours() 来获取每个白色斑点的轮廓。等高线有很多额外的属性,你可以在这里找到:
https://docs.opencv.org/master/d1/d32/tutorial_py_contour_properties.html
这包括获取他们的内部区域。
import cv2
import numpy as np
# load image
img = cv2.imread("outline.png");
# set as binary mask
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);
mask = cv2.inRange(gray, 155, 255);
# contours # if you're using OpenCV 3* then it returns as _, contours, _
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);
# find the biggest contour
biggest = None;
biggest_area = -1;
for con in contours:
area = cv2.contourArea(con);
if biggest_area < area:
biggest_area = area;
biggest = con;
# draw the new contour
redraw = np.zeros_like(img);
cv2.drawContours(redraw, [biggest], -1, (100, 150, 0), -1);
# show
cv2.imshow("Biggest", redraw);
cv2.waitKey(0);