“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:
- use
cv2.LUT()
function - use
cv2.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