我有一个来自 Detectron 2 的实例分割 + 2D 边界框结构,我从中将 pred_masks 转换为二进制对象(感兴趣的)掩码。
所以,在这里,我的问题是如何将这个二进制掩码转换为二进制图像,其中整个图像是黑色的,但对象掩码中感兴趣对象周围的边界是白色的?
segmenter = get_pointrend_predictor()
instances = segmenter(image)["instances"]
vis = PointRendVisualizer(image, metadata=MetadataCatalog.get("coco_2017_val"))
Image.fromarray(vis.draw_instance_predictions(instances.to("cpu")).get_image())
torch.Size([1, 224, 400])
na = instances[1].pred_masks.to('cpu').numpy()
print(na.shape)
(1, 224, 400)
na = na.reshape(224, 400)
na.shape
(224, 400)
na = np.where(na == False, 0, na)
na = np.where(na == True, 255, na)
plt.imshow(na)
在这个具体的例子中,我感兴趣的是在小象的边界上画一条白线(这是我在实例分割掩码对象中的第二个实例)。
不幸的是,我没有小象的边界图,但这里有一个人类边界的例子(以白线显示): ^ 图片参考:https://www.programmersought.com/article/52814639867/
我刚刚想出了提取位掩码边缘的方法。
na = outputs['instances'][1].pred_masks.to('cpu').numpy()
na = na.reshape(1024, 683)
from detectron2.utils.visualizer import GenericMask
gm = GenericMask(na, 1024, 683)
sg = gm.polygons[0].reshape(-1,2)
print(sg)
通过代码,我得到了多边形边的列表。这是气球的面具。
为了验证它,我将多边形翻译成JavaScript,如下图所示,然后运行它。显然它有效。
形态学操作(膨胀或腐蚀)在边界提取中非常方便:
import cv2
seg_mask = cv2.imread('images/seg_mask .png', 0) # this is your segmentation mask
dilated_seg_mask = cv2.dilate(seg_mask, kernel, iterations=1)
plt.figure(figsize=(12,5))
plt.subplot(121), plt.imshow(seg_mask, cmap='viridis'), plt.axis('off'), plt.title('segmentation mask', size=20)
plt.subplot(122), plt.imshow(dilated_seg_mask-seg_mask, cmap='gray'), plt.axis('off'), plt.title('extracted boundary', size=20)
plt.tight_layout()
plt.show()