Python OpenCV的label2rgb实现

Python OpenCV的label2rgb实现,python,matlab,opencv,Python,Matlab,Opencv,OpenCV是否具有可视化标签的功能?例如,类似于matlabslabel2rgb() 我能找到的最接近的是:cv2.applyColorMap(cv2.equalizeHist(segments),cv2.COLORMAP\u JET) 然而,在标签数量从一帧到下一帧发生变化的视频分割中,这不是理想的方法。原因在于;一个框架将有两个标签(0和1-代表天空和地面),因此使用jet它可能会将这两个部分分别显示为深蓝色和红色。下一帧有3个标签(0,1,2-天空、地面和汽车),因此地面部分现在已从红色

OpenCV是否具有可视化标签的功能?例如,类似于matlabs
label2rgb()

我能找到的最接近的是:
cv2.applyColorMap(cv2.equalizeHist(segments),cv2.COLORMAP\u JET)

然而,在标签数量从一帧到下一帧发生变化的视频分割中,这不是理想的方法。原因在于;一个框架将有两个标签(0和1-代表天空和地面),因此使用jet它可能会将这两个部分分别显示为深蓝色和红色。下一帧有3个标签(0,1,2-天空、地面和汽车),因此地面部分现在已从红色变为黄色。因此,当你将其可视化时,相同的部分会不断改变颜色,而不是保持一致的颜色(红色)


因此,如果matlabs
label2rbg()
这样的函数存在,它将非常有用。

我喜欢在标签少于256个时使用
cv2.LUT
(因为它只适用于
uint8
)。如果标签超过256个,则始终可以使用
(标签%256).astype(np.uint8)
将其转换为256个值

然后使用标签,您只需调用:
rgb=cv2.LUT(标签,LUT)

剩下的唯一问题是为标签创建查找表(
lut
)。可以按如下方式使用matplotlib颜色贴图:

import numpy as np
import matplotlib.pyplot as plt
import cv2

def label2rgb(labels):
  """
  Convert a labels image to an rgb image using a matplotlib colormap
  """
  label_range = np.linspace(0, 1, 256)
  lut = np.uint8(plt.cm.viridis(label_range)[:,2::-1]*256).reshape(256, 1, 3) # replace viridis with a matplotlib colormap of your choice
  return cv2.LUT(cv2.merge((labels, labels, labels)), lut)
在许多情况下,最好让相邻标签的颜色大不相同。Rick Szelski在他的附录C2:伪彩色生成中给出了一个伪代码来实现这一点。我曾经使用过他的算法和它的变体,编写代码是相当简单的。下面是使用他的算法的示例代码:

import numpy as np
import cv2


def gen_lut():
  """
  Generate a label colormap compatible with opencv lookup table, based on
  Rick Szelski algorithm in `Computer Vision: Algorithms and Applications`,
  appendix C2 `Pseudocolor Generation`.
  :Returns:
    color_lut : opencv compatible color lookup table
  """
  tobits = lambda x, o: np.array(list(np.binary_repr(x, 24)[o::-3]), np.uint8)
  arr = np.arange(256)
  r = np.concatenate([np.packbits(tobits(x, -3)) for x in arr])
  g = np.concatenate([np.packbits(tobits(x, -2)) for x in arr])
  b = np.concatenate([np.packbits(tobits(x, -1)) for x in arr])
  return np.concatenate([[[b]], [[g]], [[r]]]).T

def labels2rgb(labels, lut):
  """
  Convert a label image to an rgb image using a lookup table
  :Parameters:
    labels : an image of type np.uint8 2D array
    lut : a lookup table of shape (256, 3) and type np.uint8
  :Returns:
    colorized_labels : a colorized label image
  """
  return cv2.LUT(cv2.merge((labels, labels, labels)), lut)

if __name__ == '__main__':
  labels = np.arange(256).astype(np.uint8)[np.newaxis, :]
  lut = gen_lut()
  rgb = labels2rgb(labels, lut)
这是彩色地图:


如果需要,您可以设置图像阈值,然后使用轮廓或斑点以及连接的组件获取并标记每个孤立区域。检查文档中的这些术语。删除对
cv2.equalizeHist
的调用,标签将不会跳转。然后你应该找到一个更好的颜色图来区分连续的标签(比如我使用的那个)。当然,塞利斯基在附录中有这个!我建议对色调值使用黄金比例(黄金角度)进行映射,以便每个连续标签的色调与之前的标签几乎“最大不同”。我也喜欢我的方法,但他妈的翻页是个好主意!