“This is the 14th day of my participation in the First Challenge 2022.

What is color mapping

In some computer vision applications, the output of the algorithm is a grayscale image. However, human eyes are more sensitive in perceiving changes in color images than in observing changes in gray images. Therefore, we often need to recolor gray image into the equivalent pseudo – color image.

Color mapping in OpenCV

To perform this color transformation, OpenCV includes multiple color maps to enhance the visualization. The cv2.applyColorMap() function applies the color map to the given image, for example, applying the cv2.colormap_HSV color map:

img_COLORMAP_HSV = cv2.applyColorMap(gray_img, cv2.COLORMAP_HSV)
Copy the code

OpenCV defines the color map as follows (you can call the corresponding color map directly with a number as an argument, similar to an alias) :

Color map name Serial number
COLORMAP_AUTUMN 0
COLORMAP_BONE 1
COLORMAP_JET 2
COLORMAP_WINTER 3
COLORMAP_RAINBOW 4
COLORMAP_OCEAN 5
COLORMAP_SUMMER 6
COLORMAP_SPRING 7
COLORMAP_COOL 8
COLORMAP_HSV 9
COLORMAP_HOT 11
COLORMAP_PINK 10
COLORMAP_PARULA 12

We can apply all the color maps to the same grayscale image and draw them in the same graph:

def show_with_matplotlib(color_img, title, pos) :
    img_RGB = color_img[:, :, ::-1]

    ax = plt.subplot(2.7, pos)
    plt.imshow(img_RGB)
    plt.title(title, fontsize=8)
    plt.axis('off')

# Load the image and convert it to grayscale image
gray_img = cv2.imread('12.png', cv2.IMREAD_GRAYSCALE)

# Color map list
colormaps = ["AUTUMN"."BONE"."JET"."WINTER"."RAINBOW"."OCEAN"."SUMMER"."SPRING"."COOL"."HSV"."HOT"."PINK"."PARULA"]

plt.figure(figsize=(12.5))
plt.suptitle("Colormaps", fontsize=14, fontweight='bold')

show_with_matplotlib(cv2.cvtColor(gray_img, cv2.COLOR_GRAY2BGR), "GRAY".1)

# Apply color mapping
for idx, val in enumerate(colormaps):
    show_with_matplotlib(cv2.applyColorMap(gray_img, idx), val, idx + 2)

plt.show()
Copy the code

The running result of the program is as follows:

In the figure above, you can see that all the predefined color maps are applied to the grayscale image to enhance the visualization.

Custom color mapping

Custom color mappings can be applied to images in a number of ways.

The first approach is to define a color map that maps 0 to 255 grayscale values to 256 colors. This can be done by creating an 8-bit color image of size 256 x 1 in order to store all the colors created. Then, the gray intensity of the image can be mapped to the defined color through the lookup table in the following way:

  1. usecv2.LUT()function
  2. usecv2.applyColorMap()function

Note that when creating an 8-bit color image of size 256 x 1 for image storage, if you intend to use cv2.lut (), you should create the image as follows:

lut = np.zeros((256.3), dtype=np.uint8)
Copy the code

If you intend to use cv2.cv2.applyColormap (), you should use:

lut = np.zeros((256.1.3), dtype=np.uint8)
Copy the code

The complete code is as follows:

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

def apply_rand_custom_colormap_values(im_gray) :
    lut = np.random.randint(255, size=(256.1.3), dtype=np.uint8)

    im_color = cv2.applyColorMap(im_gray, lut)
    return im_color

def apply_rand_custom_colormap_values2(im_gray) :
    Create a random LUT
    lut = np.random.randint(255, size=(256.3), dtype=np.uint8)

    # Apply custom color mapping using cv2.lut ()
    s0, s1 = im_gray.shape
    im_color = np.empty(shape=(s0, s1, 3), dtype=np.uint8)
    for i in range(3):
        im_color[..., i] = cv2.LUT(im_gray, lut[:, i])
    return im_color

def show_with_matplotlib(color_img, title, pos) :
    img_RGB = color_img[:, :, ::-1]

    ax = plt.subplot(1.5, pos)
    plt.imshow(img_RGB)
    plt.title(title, fontsize=8)
    plt.axis('off')


# Read the image and convert it to grayscale image
gray_img = cv2.cvtColor(cv2.imread('8.png'), cv2.COLOR_BGR2GRAY)

plt.figure(figsize=(12.2))
plt.suptitle("Custom colormaps providing all values", fontsize=14, fontweight='bold')

show_with_matplotlib(cv2.cvtColor(gray_img, cv2.COLOR_GRAY2BGR), "gray".1)

# Apply color mapping
custom_rand_1 = apply_rand_custom_colormap_values(gray_img)
custom_rand_2 = apply_rand_custom_colormap_values2(gray_img)
# You can create your own fixed value color map and apply it, similar to random creation, which will not be described here
# custom_values_1 = apply_custom_colormap_values(gray_img)
# custom_values_2 = apply_custom_colormap_values2(gray_img)

# visualization
show_with_matplotlib(custom_rand_1, "cv2.applyColorMap()".2)
show_with_matplotlib(custom_rand_2, "cv2.LUT()".3)

plt.show()
Copy the code

The second way to customize a color map is to provide just a few key colors and then interpolate those values to get all the colors you need to build your lookup table.

Write the build_lut() function to build a lookup table based on these key colors: Based on five predefined color points, call np.linespace() to calculate evenly spaced colors within each predefined interval of color points:

def build_lut(cmap) :
    lut = np.empty(shape=(256.3), dtype=np.uint8)

    max = 256
    Build a lookup table
    lastval, lastcol = cmap[0]
    for step, col in cmap[1:]:
        val = int(step * max)
        for i in range(3) : lastval, val - lastval)) lut[lastval:val, i] = np.linspace(lastcol[i], col[i], val - lastval) lastcol = col lastval = valreturn lut
Copy the code

Then apply the custom color mapping:

def show_with_matplotlib(color_img, title, pos) :
    # Channel conversion
    img_RGB = color_img[:, :, ::-1]

    ax = plt.subplot(2.3, pos)
    plt.imshow(img_RGB)
    plt.title(title, fontsize=8)
    plt.axis('off')

def apply_color_map_1(gray, cmap) :

    lut = build_lut(cmap)
    s0, s1 = gray.shape
    out = np.empty(shape=(s0, s1, 3), dtype=np.uint8)

    for i in range(3):
        out[..., i] = cv2.LUT(gray, lut[:, i])
    return out

def apply_color_map_2(gray, cmap) :

    lut = build_lut(cmap)
    lut_reshape = np.reshape(lut, (256.1.3))
    im_color = cv2.applyColorMap(gray, lut_reshape)
    return im_color

# Read the image and convert it to grayscale image
gray_img = cv2.cvtColor(cv2.imread('example.png'), cv2.COLOR_BGR2GRAY)

# Apply color mapping
custom_1 = apply_color_map_1(gray_img, ((0, (255.0.255)), (0.25, (255.0.180)), (0.5, (255.0.120)),
                                        (0.75, (255.0.60)), (1.0, (255.0.0))))

custom_2 = apply_color_map_1(gray_img, ((0, (0.255.128)), (0.25, (128.184.64)), (0.5, (255.128.0)),
                                        (0.75, (64.128.224)), (1.0, (0.128.255))))

custom_3 = apply_color_map_2(gray_img, ((0, (255.0.255)), (0.25, (255.0.180)), (0.5, (255.0.120)),
                                        (0.75, (255.0.60)), (1.0, (255.0.0))))

custom_4 = apply_color_map_2(gray_img, ((0, (0.255.128)), (0.25, (128.184.64)), (0.5, (255.128.0)),
                                        (0.75, (64.128.224)), (1.0, (0.128.255))))

# visualization
show_with_matplotlib(custom_1, "custom 1 using cv2.LUT()".2)
show_with_matplotlib(custom_2, "custom 2 using cv2.LUT()".3)
show_with_matplotlib(custom_3, "custom 3 using cv2.applyColorMap()".5)
show_with_matplotlib(custom_4, "custom 4 using using cv2.applyColorMap()".6)
Copy the code

In the image above, you can see the effect of applying two custom color maps to a grayscale image.

Displays custom color map legend

Finally, we can also provide legends when displaying custom color maps. To build the color map legend, write build_lut_image() :

def build_lut_image(cmap, height) :lut = build_lut(cmap) image = np.repeat(lut[np.newaxis, ...] , height, axis=0)

    return image
Copy the code

It first calls the build_lut() function to get the lookup table. Then, call np.repeat() to copy the lookup table multiple times (height). This is because the lookup table has a shape of (256, 3) and the output image has a shape of (height, 256, 3). To add new dimensions, we also need to use np.repeat() with np.newaxis() :

image = np.repeat(lut[np.newaxis, ...] , height, axis=0)
Copy the code

The running results are as follows:

In the figure above, you can see the effect of a legend that applies two custom color maps to a grayscale image and displays each color map.

A link to the

OpenCV color space details