如何掩盖图像中的分割区域?

Posted

技术标签:

【中文标题】如何掩盖图像中的分割区域?【英文标题】:how to mask the segmented area in a image? 【发布时间】:2020-07-30 00:16:12 【问题描述】:

我想创建一个语义分割模型,它可以使用 U-net 在 USG 中分割毛囊。我已经使用 Labelme 标记了我的训练数据。标记区域的颜色为#800000。如何以黑白形式屏蔽此图像。我已经用#ffffff 替换了颜色。但是在训练模型时,它给出了一个错误:0img.png 违反范围 [0, 1]。找到最大像素值 255。请帮我解决这个问题。图像如下。提前致谢。

【问题讨论】:

您需要黑色的 8 位 (0,0,0) 结果和白色 (255,255,255) 的结果作为 3 个通道还是一个通道?还是您需要黑色的结果为 0,白色的结果为 1?保存结果需要什么图片格式? 【参考方案1】:

聚会可能有点晚了,但我发现最好编写一个单独的代码来使用 OpenCV 生成掩码。

    import json
    import cv2
    import os
    import numpy as np
    from glob import glob
    
    
    output_dir = "masks/"
    #creating the ground_truth folder if it doesn't exist
    os.makedirs(output_dir, exist_ok=True)
    
    json_files = glob("dataset/*.json")
    #loading the json file
    for image_json in json_files:
        with open(image_json) as file:
            data = json.load(file)
        filename = data["imagePath"].split(".")[0]
        
        # creating a new ground truth image
        mask = np.zeros((data["imageHeight"], data["imageWidth"]), dtype='uint8')
        for shape in data['shapes']:
            mask = cv2.fillPoly(mask, [np.array(shape['points'], dtype=np.int32)], 255)
    
        # saving the ground truth masks
        cv2.imwrite(os.path.join(output_dir,filename) + ".png", mask)

此代码回答了您的问题“如何生成黑白蒙版?”。但另一件事,即“最大值为 255”,可能是因为您在训练之前没有对图像数组进行归一化。我之前在做一个分割项目,我在使用 LabelMe 后使用过这段代码,尽管在读取图像时我通过将其除以 255 对其进行了归一化。

【讨论】:

【参考方案2】:

请问您使用的是什么语言和框架?但是在不失一般性的情况下,假设在 Python 中,由于您使用保存多边形注释顶点的 Labelme 标记数据,您可以使用 OpenCV 的 API cv2.fillPoly() 函数来填充零矩阵(将大小保存为输入图像) 具有指定的颜色。这一步制作了可视化的蒙版。

在此之后,需要在颜色和标签之间进行手动映射。标签通常存储在 1 通道矩阵中(而不是具有 3 或 4 通道的彩色图像),其他形状与输入图像相同。如果您只有两个类,您可以将零值标记为背景(例如 0),将其他颜色标记为 1,并将其保存在矩阵文件中以供进一步使用。因此,彩色图像只是用于目视检查,而不是用于训练。模型需要的只是一些简单而不同的数字。例如,现在人们使用“logits”来输出每个类的像素的概率,并选择概率的 argmax(),它返回每个像素的标签。

因此,也许尝试用 [0,num_of_classes - 1] 中的元素值制作一个矩阵将有助于解决问题。

【讨论】:

以上是关于如何掩盖图像中的分割区域?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取超像素分割后的每个小块

用matlab如何通过图像分割来检测边界

如何使用 Python/Opencv 分割二进制图像中的附近元素

如何使背景图像响应并覆盖所有区域

如何保证使用 ortools 计算的路线不会穿越特定区域?

连通区域