Introduction
In the previous tutorial, we saw how to change between different color spaces. Now, in this tutorial we will see yet another functionality of OpenCV, related to colors – colormaps. The colormaps provide us with the ability to map the value of one color to another color’s value and change it accordingly. For example, we can map the value of color (255, 0, 0) which is blue to value (0, 0, 255) which is red and this can change all the blue pixels which have the value (255, 0, 0) to red ones. This could be particularly useful if we want to change the colors of an image.
However, for colorful images this could require a lot of effort to make the mapping. This is because we need to have a mapping for each combination of the three colors – red, green and blue. And this is a huge amount of combinations. It is far easier to work with grayscale images, which only have values from zero to 255. With this functionality, we can create the so-called pseudo colorization. We can make the grayscale image look colorful. However, we will not get quite the desired result. If we really want to colorize an old grayscale image, we will have to use deep learning and other machine learning approaches. We will see this in later tutorials.
Colorization using pre-defined colormaps
In the first example, we will see how to apply colorization using pre-defined colormaps. OpenCV comes with several such maps. We will take one grayscale image and apply on it some of them to see the results. Below is the code.
// Colorize grayscale image using predefined colormaps void colorizeGrayscaleImagePredefinedMap() { // Path to the input image std::string l_pathToInputImage{ "../Resources/youngster.jpg" }; // Create an object to hold the image data of the first image Mat l_image; // Read the image date from a file with no change to color scheme l_image = imread(l_pathToInputImage, IMREAD_COLOR); // Check if we have read the first image data correctly if (!l_image.data) { std::cout << "No image data \n"; return; } // Create the output image matrix Mat l_outputImage; // Colorize the image using the predefined color map applyColorMap(l_image, l_outputImage, COLORMAP_CIVIDIS); // Display the input image namedWindow("Input", WINDOW_NORMAL); cv::imshow("Input", l_image); // Display the result image namedWindow("Result", WINDOW_NORMAL); cv::imshow("Result", l_outputImage); }
Again, we load one image from a file. Notice that this time we use IMREAD_COLOR as a read mode in order to read the pixels in all three channels, to which we will apply the color mapping.
In order to apply a colormap, we call the function applyColorMap(). Its first argument is the input image matrix, the second arguments is the output matrix. The third argument is one enum, which defines what pre-defined colormaps to use. Check here the available values. It also shows each colormap’s colors.
Finally, we display the result. Here it is how it looks on my side. You can go ahead and experiment with each available colormap to see what results you will get.

You can also try to apply colormap to a colorful image. I did this. You can see the result below.

Colorization using user-defined colormaps
The provided pre-defined colormaps are a finite number. OpenCV also provide you with a way to define your own colormaps. We will use the overloaded version of the applyColorMap() function. Here is an example code on how to do it.
// Colorize grayscale image using user-defined colormaps void colorizeGrayscaleImageUserDefinedMap() { // Path to the input image std::string l_pathToInputImage{ "../Resources/youngBlood.jpg" }; // Create an object to hold the image data of the first image Mat l_image; // Read the image date from a file as a three channel image l_image = imread(l_pathToInputImage, IMREAD_COLOR); // Check if we have read the first image data correctly if (!l_image.data) { std::cout << "No image data \n"; return; } // Create the output image matrix Mat l_outputImage; // Create the colormap uchar l_data[] = { 0, 0, 0, // 0 3, 0, 0, // 1 6, 0, 0, // 2 9, 0, 0, // 3 12, 0, 0, // 4 15, 0, 0, // 5 18, 0, 0, // 6 21, 0, 0, // 7 24, 0, 0, // 8 27, 0, 0, // 9 30, 0, 0, // 10 33, 0, 0, // 11 36, 0, 0, // 12 39, 0, 0, // 13 42, 0, 0, // 14 45, 0, 0, // 15 48, 0, 0, // 16 51, 0, 0, // 17 54, 0, 0, // 18 57, 0, 0, // 19 60, 0, 0, // 20 0, 3, 0, // 21 0, 6, 0, // 22 0, 9, 0, // 23 0, 12, 0, // 24 0, 15, 0, // 25 0, 18, 0, // 26 0, 21, 0, // 27 0, 24, 0, // 28 0, 27, 0, // 29 0, 30, 0, // 30 3, 3, 0, // 31 3, 6, 0, // 32 3, 9, 0, // 33 3, 12, 0, // 34 3, 15, 0, // 35 3, 18, 0, // 36 3, 21, 0, // 37 3, 24, 0, // 38 3, 27, 0, // 39 3, 30, 0, // 40 6, 3, 0, // 41 6, 6, 0, // 42 6, 9, 0, // 43 6, 12, 0, // 44 6, 15, 0, // 45 6, 18, 0, // 46 6, 21, 0, // 47 6, 24, 0, // 48 6, 27, 0, // 49 6, 30, 0, // 50 9, 3, 0, // 51 9, 6, 0, // 52 9, 9, 0, // 53 9, 12, 0, // 54 9, 15, 0, // 55 9, 18, 0, // 56 9, 21, 0, // 57 9, 24, 0, // 58 9, 27, 0, // 59 9, 30, 0, // 60 18, 3, 0, // 61 18, 6, 0, // 62 18, 9, 0, // 63 18, 12, 0, // 64 18, 15, 0, // 65 18, 18, 0, // 66 18, 21, 0, // 67 18, 24, 0, // 68 18, 27, 0, // 69 18, 30, 0, // 70 30, 33, 0, // 71 30, 36, 0, // 72 30, 39, 0, // 73 30, 42, 0, // 74 30, 45, 0, // 75 30, 48, 0, // 76 30, 51, 0, // 77 30, 54, 0, // 78 30, 57, 0, // 79 30, 60, 0, // 80 30, 3, 18, // 81 30, 6, 21, // 82 30, 9, 24, // 83 30, 12, 27, // 84 30, 15, 30, // 85 30, 18, 33, // 86 30, 21, 36, // 87 30, 24, 39, // 88 30, 27, 42, // 89 30, 30, 45, // 90 30, 33, 48, // 91 30, 36, 51, // 92 30, 39, 54, // 93 30, 42, 57, // 94 30, 45, 60, // 95 30, 48, 63, // 96 30, 51, 66, // 97 30, 54, 69, // 98 30, 57, 72, // 99 30, 60, 75, // 100 54, 3, 18, // 101 54, 6, 21, // 102 54, 9, 24, // 103 54, 12, 27, // 104 54, 15, 30, // 105 54, 18, 33, // 106 54, 21, 36, // 107 54, 24, 39, // 108 54, 27, 42, // 199 60, 30, 45, // 110 60, 33, 48, // 111 60, 36, 51, // 112 60, 39, 54, // 113 60, 42, 57, // 114 60, 45, 60, // 115 60, 48, 63, // 116 60, 51, 66, // 117 60, 54, 69, // 118 60, 57, 72, // 119 60, 60, 75, // 120 54, 30, 18, // 121 54, 36, 21, // 122 54, 39, 24, // 123 54, 42, 27, // 124 54, 45, 30, // 125 54, 48, 33, // 126 54, 51, 36, // 127 54, 54, 39, // 128 54, 57, 42, // 129 60, 60, 45, // 130 90, 33, 48, // 131 90, 36, 51, // 132 90, 39, 54, // 133 90, 42, 57, // 134 90, 45, 60, // 135 90, 48, 63, // 136 90, 51, 66, // 137 90, 54, 69, // 138 90, 57, 72, // 139 90, 60, 75, // 140 120, 30, 60, // 141 120, 36, 66, // 142 120, 39, 72, // 143 120, 42, 78, // 144 120, 45, 84, // 145 120, 48, 90, // 146 120, 51, 96, // 147 120, 54, 108, // 148 120, 57, 120, // 149 128, 60, 45, // 150 128, 66, 48, // 151 128, 76, 51, // 152 128, 79, 54, // 153 128, 82, 57, // 154 128, 85, 60, // 155 128, 88, 63, // 156 128, 101, 66, // 157 128, 104, 69, // 158 128, 127, 72, // 159 128, 130, 75, // 160 130, 130, 60, // 161 130, 136, 66, // 162 130, 139, 72, // 163 130, 142, 78, // 164 130, 145, 84, // 165 130, 148, 90, // 166 130, 151, 96, // 167 130, 154, 108,// 168 130, 157, 120,// 169 148, 160, 45, // 170 148, 160, 48, // 171 148, 126, 51, // 172 148, 129, 54, // 173 148, 132, 57, // 174 148, 135, 60, // 175 148, 138, 63, // 176 148, 141, 66, // 177 148, 144, 69, // 178 148, 147, 72, // 179 148, 150, 75, // 180 150, 160, 60, // 181 150, 166, 66, // 182 150, 169, 72, // 183 150, 172, 78, // 184 150, 175, 84, // 185 150, 178, 90, // 186 150, 181, 96, // 187 150, 184, 108,// 188 150, 187, 120,// 189 168, 160, 75, // 190 168, 160, 78, // 191 168, 126, 81, // 192 168, 129, 84, // 193 168, 132, 87, // 194 168, 135, 90, // 195 168, 138, 93, // 196 168, 141, 96, // 197 168, 144, 99, // 198 168, 147, 122,// 199 168, 150, 125,// 200 180, 160, 60, // 201 180, 166, 66, // 202 180, 169, 72, // 203 180, 172, 78, // 204 180, 175, 84, // 205 180, 178, 90, // 206 180, 181, 96, // 207 180, 184, 108,// 208 180, 187, 120,// 209 196, 160, 75, // 210 196, 160, 78, // 211 196, 126, 81, // 212 196, 129, 84, // 213 196, 132, 87, // 214 196, 135, 90, // 215 196, 138, 93, // 216 196, 141, 96, // 217 196, 144, 99, // 218 196, 147, 122,// 219 196, 150, 125,// 220 200, 180, 60, // 221 200, 186, 66, // 222 200, 189, 72, // 223 200, 192, 78, // 224 200, 195, 84, // 225 200, 198, 90, // 226 200, 201, 96, // 227 200, 204, 108,// 228 200, 207, 120,// 229 216, 230, 120,// 230 216, 240, 120,// 231 216, 246, 120,// 232 216, 249, 122,// 233 216, 252, 122,// 234 216, 252, 132,// 235 216, 252, 132,// 236 216, 255, 145,// 237 216, 255, 148,// 238 216, 255, 156,// 239 216, 255, 160,// 240 230, 180, 60, // 241 230, 186, 66, // 242 230, 189, 72, // 243 230, 192, 78, // 244 230, 195, 84, // 245 230, 198, 90, // 246 230, 201, 96, // 247 230, 204, 108,// 248 230, 207, 120,// 249 236, 230, 150,// 250 236, 240, 150,// 251 236, 246, 150,// 252 242, 249, 162,// 253 242, 252, 162,// 254 242, 252, 172,// 255 }; Mat l_colorMap{ 256, 1, CV_8UC3, l_data }; // Colorize the image using the user-defined color map applyColorMap(l_image, l_outputImage, l_colorMap); // Display the input image namedWindow("Input", WINDOW_NORMAL); cv::imshow("Input", l_image); // Display the result image namedWindow("Result", WINDOW_NORMAL); cv::imshow("Result", l_outputImage); }
As with the previous example, we again load the image in IMREAD_COLOR mode. Then it is time to define the color mapping. We need to define three values for each grayscale level from zero to 255. As you can see, it is quite a long list. In my case, I have defined random numbers. You can define some numbers, which will make sense to you. From the defined data, we create one colormap matrix.
Once we are done with defining the colormap it is time to call the applyColorMap() function. As I said, we call its overloaded version, which will take the colormap matrix as a third argument. It will apply the colormapping to the grayscale image we provide. We will display the result. You can see what the result on my side was. It is quite random.

You can also apply this random colormap to a color image. See what I have got on my side.

Conclusion
In this tutorial, we saw how to use colormaps to apply colorization on images. The colorization, which we achieved, is not a real one. It is pseudo colorization. If you want to achieve a real colorization, you need to use machine learning. Nevertheless, you can achieve quite impressive results. Try on your side all the available pre-defined colormaps and create your own.
The code is again available on GitHub and as an archive below.
Next, we will see how to use color changing and thresholding.
OpenCV Training
Passionate developer, loving husband and caring father. As an introvert programming is my life. I work as a senior software engineer in a big international company. My hobbies include playing computer games (mostly World of Warcraft), watching TV series and hiking.