Apply MatplotLib or custom colormap to OpenCV image

混江龙づ霸主 提交于 2020-01-22 23:06:38

问题


OpenCV has a limited amount of color maps. MatplotLib has many more color maps, but it is not straightforward to apply these colormaps to given OpenCV images. How to apply MatplotLib color maps from the page below to OpenCV images when using the Python API? This is similar to applying a custom colormap to a given image.

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


回答1:


Answering my own question because I did not find an easy solution on 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)

Produces the image:




回答2:


For Python >= 2.7, cmapy packages this functionality in a convenient way. Install it with:

Python 2.7:

pip install cmapy

Python 3.x:

pip3 install cmapy

Or, for Anaconda (from conda-forge):

conda install -c conda-forge cmapy 

And use it like this:

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()

Different colormaps give something like this:

See all the available colormaps in action here.

Disclaimer: I wrote cmapy (because I needed this functionality for another project), and internally, it does pretty much the same as the other answers.




回答3:


In recent versions of OpenCV (starting with 3.3), there's an overload of applyColorMap, which allows you to provide a custom colormap (either 1 or 3 channel). I've modified verified.human's code to simply generate a colormap suitable to use with this function.

I've taken few more opportunities to simplify the code:

  • ScalarMappable.to_rgba can return bytes (in range 0-255) directly when you set bytes argument to True.
  • We can use array indexing with negative step size to remove the alpha channels as well as switch from RGB to BGR in one step

Code:

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()


来源:https://stackoverflow.com/questions/52498777/apply-matplotlib-or-custom-colormap-to-opencv-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!