簡體   English   中英

將 MatplotLib 或自定義顏色圖應用於 OpenCV 圖像

[英]Apply MatplotLib or custom colormap to OpenCV image

OpenCV 的顏色圖數量有限。 MatplotLib 有更多的顏色圖,但是將這些顏色圖應用於給定的 OpenCV 圖像並不簡單。 使用 Python API 時如何將以下頁面中的 MatplotLib 顏色映射應用於 OpenCV 圖像? 這類似於將自定義顏色圖應用於給定圖像。

https://matplotlib.org/examples/color/colormaps_reference.html

對於 Python >= 2.7, cmapy以方便的方式打包此功能。 安裝它:

Python 2.7:

pip install cmapy

Python 3.x:

pip3 install cmapy

或者,對於 Anaconda(來自conda-forge ):

conda install -c conda-forge cmapy 

並像這樣使用它:

import cv2
import matplotlib.pyplot as plt
import cmapy

# Read image.
img = cv2.imread('imgs/woman.png')

# Colorize.
img_colorized = cv2.applyColorMap(img, cmapy.cmap('viridis'))

# Display
plt.imshow(img_colorized)
plt.show()

不同的顏色圖給出了這樣的東西:

此處查看所有可用的顏色圖。

免責聲明:我寫了 cmapy(因為我需要在另一個項目中使用此功能),並且在內部,它與其他答案幾乎相同。

在 OpenCV 的最新版本(從 3.3 開始)中,有一個applyColorMap的重載,它允許您提供自定義顏色圖(1 或 3 通道)。 我已經修改了verify.human的代碼以簡單地生成適合與此函數一起使用的顏色圖。

我已經采取了更多的機會來簡化代碼:

  • 當您將bytes參數設置為True時, ScalarMappable.to_rgba可以直接返回字節(范圍 0-255)。
  • 我們可以使用具有負步長的數組索引來移除 alpha 通道以及一步從 RGB 切換到 BGR

代碼:

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


def get_mpl_colormap(cmap_name):
    cmap = plt.get_cmap(cmap_name)

    # Initialize the matplotlib color map
    sm = plt.cm.ScalarMappable(cmap=cmap)

    # Obtain linear color range
    color_range = sm.to_rgba(np.linspace(0, 1, 256), bytes=True)[:,2::-1]

    return color_range.reshape(256, 1, 3)


image_gray = cv2.imread('cage.png', cv2.IMREAD_GRAYSCALE)
image_bgr = cv2.applyColorMap(image_gray, get_mpl_colormap('bwr'))

cv2.imshow('image with colormap', image_bgr)
cv2.waitKey()

回答我自己的問題,因為我沒有在 StackOverflow 上找到一個簡單的解決方案:

def apply_custom_colormap(image_gray, cmap=plt.get_cmap('seismic')):

    assert image_gray.dtype == np.uint8, 'must be np.uint8 image'
    if image_gray.ndim == 3: image_gray = image_gray.squeeze(-1)

    # Initialize the matplotlib color map
    sm = plt.cm.ScalarMappable(cmap=cmap)

    # Obtain linear color range
    color_range = sm.to_rgba(np.linspace(0, 1, 256))[:,0:3]    # color range RGBA => RGB
    color_range = (color_range*255.0).astype(np.uint8)         # [0,1] => [0,255]
    color_range = np.squeeze(np.dstack([color_range[:,2], color_range[:,1], color_range[:,0]]), 0)  # RGB => BGR

    # Apply colormap for each channel individually
    channels = [cv2.LUT(image_gray, color_range[:,i]) for i in range(3)]
    return np.dstack(channels)


image_gray = cv2.imread('./lena.jpg', cv2.IMREAD_GRAYSCALE)
image_bgr = apply_custom_colormap(image_gray, cmap=plt.get_cmap('bwr'))

cv2.imshow('image with colormap', image_bgr)
cv2.waitKey(0)

產生圖像:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM