Splitting and Merging Image
Sometimes you will need to work separately on the B,G,R channels of a color image. In this case, you need to split the color image into multiple single channel images. In some situations, you may want to join single channel images into one color image. In this section we will see how can we achieve this task.
Splitting Image Channels
In OpenCV, we can split a given color image into three separate channels using split() function. It splits channels of the color image into individual grayscale images. The signature of the split() function is given below:
cv2.split(img,out)
The parameters of the above function are described as below:
Parameter |
Description |
img
|
Input color image with multiple channels..
|
Out
|
The output vector of arrays.
|
Code 1-1 shows an example of how we can use split() function the BGR image into B, G and R channels and then display it.
Code 1 – 1: Splitting color image into single channels
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | import cv2
import numpy as np
try:
path = r'F:\img\lena.jpg'
img = cv2.imread(path, cv2.IMREAD_COLOR)
B,G,R = cv2.split(img)
cv2.imshow('Original',img)
cv2.imshow('Blue',B)
cv2.imshow('Green',G)
cv2.imshow('Red',R)
cv2.waitKey(0)
cv2.destroyAllWindows()
except:
print('Unable to read image..')
|
Line 1 and 2: We start by importing OpenCV and numpy libraries.
Line 3: This lines defines a try block. The exception block (Line 13 and 14) is associated with this block. If any exception occurs, it throws it and code in exception block is executed.
Line 4: Define path of the image to read.
Line 5: Here we read a color image (see second parameter).
Line 6: The split() function is used to split the three channels of the image in the order blue, green and red. The function returns the image channels as tuple in the order (B, G and R).
Line 7-12: These lines help display each channel image.
The output obtained for the code shown above is shown in Figure 1.
Figure 1: Result of splitting the original image (left most) into three grayscale channels (blue, green and red channels).
Warning
cv2.split() is a costly operation (in terms of time). So use it only if necessary. Otherwise go for Numpy indexing.
Alternative Way of Splitting Color Images
Instead of using OpenCV’s split() function, we can split image channels to form a color image using Python. The following lines show how to split a color image using Numpy arrays.
Code 1 – 2: Splitting color image into single channel images using Numpy arrays
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import cv2
import numpy as np
try:
path = r'F:\img\lena.jpg'
img = cv2.imread(path, cv2.IMREAD_COLOR)
B = img[:,:,0]
G = img[:,:,1]
R = img[:,:,2]
cv2.imshow('Original',img)
cv2.imshow('Blue',B)
cv2.imshow('Green',G)
cv2.imshow('Red',R)
cv2.waitKey(0)
cv2.destroyAllWindows()
except Exception as e:
print(str(e))
print('Unable to read image.')
|
Code 1-2 is same as shown in Code 1-1 except lines 6-8 which actually read blue, green and red channels of the color image as explained below.
Line 6: We read the first channel, i.e. Blue channel of color image and write it to B variable. To read all pixels from the first channel we use img[:,:,0]. Here 1st “:” indicates all rows, 2nd parameter “:” indicates all columns and third values “0” indicates the channel index which is the first channel.
Line 7: Same way we read all rows and column from second channel by putting the third index to 1.
Line 8: Same way we read all rows and column from third channel by putting the third index to 2.
The output obtained after executing code shown in Code 1-2 is same as shown in Figure-1.
Merging Image Channels
Similarly, three separate single channel images can be merged to form a color image. We need to take care of the order of the channels. For instance, if we want to create an RGB image then we must provide the order of the channels as Red, Green and Blue. ,
An example of merging three single channels images to form a color image is shown in the following Code 1-3.
Code 1 – 3 : Splitting color image into single channel images using Numpy arrays
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | import cv2
import numpy as np
try:
path = r'F:\img\lena.jpg'
R = cv2.imread(r'F:\img\lenaR.jpg', cv2.IMREAD_GRAYSCALE)
G = cv2.imread(r'F:\img\lenaG.jpg', cv2.IMREAD_GRAYSCALE)
B = cv2.imread(r'F:\img\lenaB.jpg', cv2.IMREAD_GRAYSCALE)
out = cv2.merge([B,G,R])
cv2.imshow('Blue',B)
cv2.imshow('Green',G)
cv2.imshow('Red',R)
cv2.imshow('Merged Image',out)
cv2.waitKey(0)
cv2.destroyAllWindows()
except:
print('Unable to read image.')
|
Line 1 and 2: We start by importing OpenCV and numpy libraries.
Line 3: This lines defines a try block. The exception block (Line 15 and 16) is associated with this block. If any exception occurs, it throws it and code in exception block is executed.
Line 4: Define path of the image to read.
Line 5-7: Here we read three different grayscale images.
Line 6: We applied merge() function to merge the three images to form a color image. Since merge is expecting a list therefore we put the input images in square brackets []. Here we passed in the order blue, green and red. The function returns color produced after merging these input channels.
Line 7-12: These lines help display each channel image.
The result obtained for the code shown in code 1-3 is shown in Figure 2.
Figure 2: Result of merging three grayscale image. Right most is the produced after merging Blue, Green and Red channels.
Let us replace line # 6 with the following:
out = cv2.merge([R,G,B])
When we changed the order of the input images, red followed by green and blue, the output is also changed. The result obtained is shown in Figure 3. Now notice that merged image looks different. As mentioned before, the order of the channels during merging is important. Since, OpenCV reads image in order Blue, Green and Red channel order, therefore, providing the channels in this order produced correct image. However, if we change the order, we see the output is changed. It is important to keep in mind that the user has to select proper order of the input channels.
Figure 3: Result of merging three grayscale image. Right most is obtained by merging Blue, Green and Red channels.
We can also change a given grayscale image into color image by merging three channel individual images. The code in Code 1-4 shows an example of generating a blue image from a given one grayscale image.
Code 1 – 4 : Merging Image to form a color image
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | import cv2
import numpy as np
try:
path = r'F:\img\rect3.jpg'
img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
R = np.zeros(img.shape, dtype = np.uint8)
G = np.zeros(img.shape, dtype = np.uint8)
out = cv2.merge([img, G,R])
cv2.imshow('Out',BGR)
cv2.imshow('Input',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
except:
print('Unable to read image.')
|
Exception Handling
Exception handling is very helpful when working with any programming language. The program will not crash even there is an exception. We write our code in the try section, if there is not error it will execute smoothly. However, if there is an error in the try block, then it stops processing and jumps to the except block where we can handle the error. For example, in above code we handled the error by displaying an error message.
Line 1 and 2: We start by importing OpenCV and numpy libraries.
Line 4 : Define path of the image to read.
Line 5 : Read a single grayscale image.
Line 5 - 6 : We created two dark images using np.zeros() function. All pixels are set to zero and size is same as the input image. Also, we set the data type to uint8 with second parameter.
Line 7 : We applied merge() function to merge the three images to form a color image. Img is passed in as first parameter therefore, first channel represents blue. While other parameters have zero pixel values, therefore, the output shown blue as dominant color.
Line 9 - 10 : The original and color image are displayed.
The output obtained for this code is shown in Figure 4
Figure 4: Original image (left), merged image (right)
Here ordering is important. The original grayscale image is placed first, then green and then red. Since green and red channels have zero values for their pixels, therefore, the only channel with non zero values is the first one i.e. original grayscale image, therefore, the net impact is that it shows blue color.
Let us replace Line 8 with the following line:
out = cv2.merge ( [ G, R, img ] )
As we can see, the order of the input channels is changed. G and R have zero values. Img has higher values therefore, red channels has higher dominance. The output is shown in Figure 5.
Figure 5: Original image (left), merged image (right) with red channel being dominant