【语义分割】将VOC格式分割掩码覆盖到原图生成标注可视化

本文介绍了如何使用Python和OpenCV库,读取和修改图像文件路径,根据掩码值调整BGR颜色,然后将彩色掩码应用到原图上,实现批量处理,以标记和区分不同的类别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

修改文件路径,并且根据掩码像素值修改BGR色盘。


单图:

import cv2
import numpy as np

# Load the original image and the mask image
original_image_path = 'VOCdevkit/VOC/JPEGImages/1.jpg'
mask_image_path = 'VOCdevkit/VOC/SegmentationClass/1.png'
original_image = cv2.imread(original_image_path)
mask_image = cv2.imread(mask_image_path, cv2.IMREAD_UNCHANGED)

# Resize mask to match the original image if necessary
if mask_image.shape[:2] != original_image.shape[:2]:
    mask_image = cv2.resize(mask_image, (original_image.shape[1], original_image.shape[0]), interpolation=cv2.INTER_NEAREST)

# If the mask is not single channel, convert it to grayscale
if len(mask_image.shape) > 2:
    mask_image = cv2.cvtColor(mask_image, cv2.COLOR_BGR2GRAY)

# Get the unique values from the mask image which represent different categories
unique_values = np.unique(mask_image)

# Define colors for the unique categories we found in the mask
# We'll use a different color for each category value.
# The colors are in BGR format as OpenCV uses BGR by default.
category_colors = {
    0: [0, 0, 0],       # Black for background
    132: [153, 76, 0],  
    135: [0, 0, 153],  
    167: [0, 76, 153],  
    179: [204, 0, 102] 
}

# Create an empty colored mask with the same size as the original mask
colored_mask = np.zeros_like(original_image, dtype=np.uint8)

# Apply colors to the mask
for value in unique_values:
    # We check if the value is in our category colors, if not we continue to the next value
    if value in category_colors:
        colored_mask[mask_image == value] = category_colors[value]

# Blend the colored mask with the original image
overlayed_image = cv2.addWeighted(original_image, 1, colored_mask, 0.7, 0)

# Save the result
output_path = 'data/ground-truth/image.png'
cv2.imwrite(output_path, overlayed_image)
print(f"Image with colored mask overlay saved to {output_path}")

批量处理:

import cv2
import numpy as np
import os

# Set the directories for the images and masks
original_images_dir = 'VOCdevkit/VOC/JPEGImages'
mask_images_dir = 'VOCdevkit/VOC/SegmentationClass'
output_images_dir = 'VOCdevkit/VOC/visual'

# Ensure the output directory exists
if not os.path.exists(output_images_dir):
    os.makedirs(output_images_dir)

# Define the colors for the categories found in the mask images
category_colors = {
    0: [0, 0, 0],
    132: [153, 76, 0],
    135: [0, 0, 153],
    181: [0, 76, 153],
    167: [0, 76, 153],
    179: [204, 0, 102]
}

# Process images
for image_filename in os.listdir(original_images_dir):
    # Construct the full path to the original image
    original_image_path = os.path.join(original_images_dir, image_filename)

    # Check if the file is a JPG image
    if not image_filename.lower().endswith('.jpg'):
        continue  # Skip non-JPG files

    # Construct the corresponding mask image path (assuming same filename but with .png extension)
    mask_image_filename = os.path.splitext(image_filename)[0] + '.png'
    mask_image_path = os.path.join(mask_images_dir, mask_image_filename)

    # Check if the corresponding mask image exists
    if not os.path.exists(mask_image_path):
        print(f"No corresponding mask found for {image_filename}, skipping...")
        continue

    # Read the original image and mask image
    original_image = cv2.imread(original_image_path)
    mask_image = cv2.imread(mask_image_path, cv2.IMREAD_UNCHANGED)

    # Resize the mask to match the original image if necessary
    if mask_image.shape[:2] != original_image.shape[:2]:
        mask_image = cv2.resize(mask_image, (original_image.shape[1], original_image.shape[0]), interpolation=cv2.INTER_NEAREST)

    # If the mask is not single channel, convert it to grayscale
    if len(mask_image.shape) > 2:
        mask_image = cv2.cvtColor(mask_image, cv2.COLOR_BGR2GRAY)

    # Apply colors to the mask
    colored_mask = np.zeros_like(original_image, dtype=np.uint8)
    for value in np.unique(mask_image):
        if value in category_colors:
            colored_mask[mask_image == value] = category_colors[value]

    # Blend the colored mask with the original image
    overlayed_image = cv2.addWeighted(original_image, 1, colored_mask, 0.5, 0)

    # Save the result to the output directory
    output_image_path = os.path.join(output_images_dir, image_filename)
    cv2.imwrite(output_image_path, overlayed_image)
    print(f"Saved overlayed image for {image_filename} to {output_image_path}")

### VOC语义分割预测图应用调色板上色方法 对于VOC(Pascal Visual Object Classes)数据集中的语义分割任务,其生成的预测图通常是一个灰度图像或者整数值矩阵,其中每个像素值代表该位置所属的类别标签。为了使这些预测图更具可视化效果并便于理解,可以利用颜色映射技术将其转换为彩色图像。 以下是实现这一目标的具体方式: #### 使用固定调色板 一种常见的方式是定义一个固定的调色板 (Color Palette),它包含了与每种类别相对应的颜色。通过将预测图中的每一个类别的索引替换为其对应的颜色值来完成着色过程[^1]。 ```python import numpy as np from PIL import Image def apply_color_map(image, colormap): """ 将给定的colormap应用于输入image。 参数: image: 输入的numpy数组形式的预测图(单通道)。 colormap: 颜色调色板列表,长度等于可能的最大类别数加一。 返回: colored_image: 彩色化后的图像作为numpy数组返回。 """ r = np.zeros_like(image).astype(np.uint8) g = np.zeros_like(image).astype(np.uint8) b = np.zeros_like(image).astype(np.uint8) for label_index in range(len(colormap)): idx = image == label_index r[idx] = colormap[label_index][0] g[idx] = colormap[label_index][1] b[idx] = colormap[label_index][2] rgb_stack = np.stack([r,g,b], axis=2) return rgb_stack # 示例Colormap voc_colormap = [ [0, 0, 0], [128, 0, 0], [0, 128, 0], ... ] # 加载模型预测结果 predicted_mask = ... # 假设这是从模型得到的结果,形状(H,W), dtype=np.int32 # 应用color map到mask上面 colored_mask = apply_color_map(predicted_mask, voc_colormap) # 转换为Image对象以便保存或显示 result_img = Image.fromarray(colored_mask) ``` 上述代码片段展示了如何创建一个函数`apply_color_map()`用于接收一张预测掩码以及相应的色彩表,并输出带有颜色标注的新图片。这里需要注意的是,实际操作过程中应当确保所使用的色彩表覆盖所有可能出现的分类标签。 #### 结合深度学习框架的功能 如果是在TensorFlow/Keras 或 PyTorch这样的现代机器学习库中工作,则可以直接借助它们内置的一些工具简化流程。比如,在PyTorch中有专门处理张量间变换的方法可以帮助更高效地执行此类任务;而在Keras/Tensorflow里也可以找到类似的解决方案。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值