在 RGB 图像上绘制多类语义分割透明叠加

Ass*_*f b 4 python opencv image-processing computer-vision semantic-segmentation

我有语义分割掩码的结果(值在 0-1 之间,需要 otsu 阈值来确定什么是阳性),我想直接在 RGB 图像上绘制,每个预测类在 RGB 图像上具有不同的随机颜色。

我使用以下内容绘制具有单一颜色的单个蒙版。是否有一个包或简单的策略可以为多类做到这一点?

fig, ax = plt.subplots(nrows=nrows, ncols=ncols, figsize=(5, 5))
  ax.imshow(image, cmap='gray')
  ax.axis('off')
  mask = (fused_mosaic[..., channel]*255).astype('uint8')
  ret3,th3 = cv2.threshold(mask,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
  fig, ax = image_show(full_im)
  ax.imshow(mask>ret3, alpha=0.3)
Run Code Online (Sandbox Code Playgroud)

我正在寻找这样的东西,只是没有盒子和标签的简单。我尝试使用detectron2(在示例中生成此注释的包,但它们需要一些我无法弄清楚的奇怪元数据对象)。 在此处输入图片说明

谢谢

Mar*_*ell 9

Scikit-image有一个label2rgb()根据标签通道着色的内置函数:

#!/usr/bin/env python3

from skimage import io
from skimage import color
from skimage import segmentation
import matplotlib.pyplot as plt

# URL for tiger image from Berkeley Segmentation Data Set BSDS
url=('http://www.eecs.berkeley.edu/Research/Projects/CS/vision/bsds/BSDS300/html/images/plain/normal/color/108073.jpg')

# Load tiger image from URL
tiger = io.imread(url)

# Segment image with SLIC - Simple Linear Iterative Clustering
seg = segmentation.slic(tiger, n_segments=30, compactness=40.0, enforce_connectivity=True, sigma=3)

# Generate automatic colouring from classification labels
io.imshow(color.label2rgb(seg,tiger))
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 当然 - 让您自己寻找更简单的解决方案。 (2认同)

ray*_*ica 5

通过上面的对话,您有一个整数 ID 的 2D NumPy 数组,其中该数组中的每个元素确定所述像素的类 ID,从而为您提供语义分割输出。

我建议您分三个阶段进行此操作。

  1. 创建一个 RGB 颜色图,其大小N x 4为其中N是分段中输出类的总数。因此,每个类i都会分配一个 RGBA 颜色像素值,您将使用该值对输出进行着色。

  2. 展平输入整数 NumPy 数组,使其成为我们可以用来索引 (1) 的 1D NumPy 数组

  3. 最后索引到 (1) 中的 RGB 颜色图。这将创建一个(R x C) x 42D NumPy 数组,其中包含将语义标签映射到颜色的输出彩色图像。当然,我们需要将其恢复到原始输入维度,因此请重新调整该数组的形状,以便R x C x 4您可以显示它。最后,因为我们现在有一个图像的 Alpha 通道,所以您可以将其显示在原始图像的顶部。


步骤#1 - 生成颜色图

matplotlib有一套很好的工具可以为您生成此颜色图。您可以使用cm此模块。首先,决定您想要使用什么颜色图来实现您的目的。它们的完整列表可以在这里找到: https: //matplotlib.org/3.1.1/tutorials/colors/colormaps.html。我将选择 Viridis,因为这是当前在matplotlib.

假设系统中的类总数为N,首先生成颜色图,然后创建一个从 0 到 1 的线性间隔数组,其中的N元素从该颜色图的开头到结尾统一创建颜色。另请注意,这将生成一个N x 4颜色图,最后一列是 Alpha 通道。这对于以后来说极其重要。具体来说,此方法会将标签为 0 的任何像素着色为属于颜色图的下端,并且由于这是语义分割输出,标签 0 应该对应于背景,因此我们应该将该标签的 alpha 通道设置为 0做到透明。其余的颜色我们可以设置为您想要的 alpha,在代码中为 0.3。

from matplotlib import cm
import numpy as np
N = ... # You define this here
colours = cm.get_cmap('viridis', N)  # Change the string from 'viridis' to whatever you want from the above link
cmap = colours(np.linspace(0, 1, N))  # Obtain RGB colour map
cmap[0,-1] = 0  # Set alpha for label 0 to be 0
cmap[1:,-1] = 0.3  # Set the other alphas for the labels to be 0.3
Run Code Online (Sandbox Code Playgroud)

步骤#2 - 获取语义分割输出并找到合适的颜色

这很简单。假设fused_mosaic是我们之前讨论的二维整数数组,展平该数组并索引您的颜色图:

output = cmap[fused_mosaic.flatten()]
Run Code Online (Sandbox Code Playgroud)

步骤#3 - 重塑为所需的输出

这又是直截了当的:

R, C = fused_mosaic.shape[:2]
output = output.reshape((R, C, -1))
Run Code Online (Sandbox Code Playgroud)

output现在将包含语义分割图中每个对象的 RGBA 渲染图像。然后您最终可以使用它并将其显示在您的图像之上。使用您的代码,这将是:

fig, ax = image_show(full_im)  # Don't know what this does but it's from your code
ax.imshow(output)
Run Code Online (Sandbox Code Playgroud)

为了将一切联系在一起,这就是我最终要做的:

## Step #1
from matplotlib import cm
import numpy as np
N = ... # You define this here
colours = cm.get_cmap('viridis', N)  # Change the string from 'viridis' to whatever you want from the above link
cmap = colours(np.linspace(0, 1, N))  # Obtain RGB colour map
cmap[0,-1] = 0  # Set alpha for label 0 to be 0
cmap[1:,-1] = 0.3  # Set the other alphas for the labels to be 0.3

## Step #2
output = cmap[fused_mosaic.flatten()]

## Step #3
R, C = fused_mosaic.shape[:2]
output = output.reshape((R, C, -1))

## Overlay
fig, ax = image_show(full_im)  # Don't know what this does but it's from your code
ax.imshow(output)
Run Code Online (Sandbox Code Playgroud)