opencv python merge different channel images into one

14,308

Solution 1

As OpenCV 3.x stored image as numpy array, we can simply average each image and add them together, provided that the height and width of the images are exactly the same.

img_1 = cv2.imread('./imagesStackoverflow/sat_1_331-442.png')
img_2 = cv2.imread('./imagesStackoverflow/sat_2_331-442.png')
img_3 = cv2.imread('./imagesStackoverflow/sat_3_331-442.png')
img_4 = cv2.imread('./imagesStackoverflow/sat_4_331-442.png')

no_img = 4
img = img_1/no_img + img_2/no_img + img_3/no_img + img_4/no_img

To get a quick result, I manually edited the size of the four images to 442(h) x 331(w) pixels.

enter image description here Below is the merged image, with 3 channels.

enter image description here

To merge 11 images, you may just extend the code as:

img = img_1/no_img + img_2/no_img + img_3/no_img + ... + img_11/no_img

Solution 2

First, you need to carefully consider the number of channels that you have so that you can create a useful image. In the example below I assume that you have three channels (Red, Green, and Blue) which could be combined into an RGB image.

import numpy as np
import cv2

"""Read each channel into a numpy array. 
Of course your data set may not be images yet.
So just load them into three different numpy arrays as neccessary"""
a = cv2.imread('chanel_1.jpg', 0)
b = cv2.imread('chanel_2.jpg', 0)
c = cv2.imread('chanel_3.jpg', 0)

"""Create a blank image that has three channels 
and the same number of pixels as your original input"""
needed_multi_channel_img = np.zeros((a.shape[0], a.shape[1], 3))

"""Add the channels to the needed image one by one"""
needed_multi_channel_img [:,:,0] = a
needed_multi_channel_img [:,:,1] = b
needed_multi_channel_img [:,:,2] = c

"""Save the needed multi channel image"""
cv2.imwrite('needed_multi_channel_img.png',needed_multi_channel_img)

Solution 3

I've been trying this for 2 days straight and one thing that I failed to understand was that the merge function of opencv takes a tuple, not 3 different arguments.

image = cv2.imread(image_file, 1)
R, G, B = cv2.split(image)
output_image = cv2.merge ( (R, G, B) )

Solution 4

What do you mean by merge ? They are all grayscale images, so they are basically the same channel in grayscale color space. Some information are doomed to be lost when you try to blend or add the images. Try the above two methods using functions in OpenCV or Pillow.

mul1 = ImageChops.add(img1, img2, scale=2)
mul2 = ImageChops.add(img3, img4, scale = 2)
mul3 = ImageChops.add(mul1, mul2, scale = 2)

mul3.show()

using Add

R1 = img1.convert('RGBA').resize([456,512])
R2 = img2.convert('RGBA').resize([456,512])
R3 = img3.convert('RGBA')
R4 = img4.convert('RGBA')

S1 = ImageChops.blend(R1,R2,0.5)
S2 = ImageChops.blend(R3,R4,0.5)
S3 = ImageChops.blend(S1,S2,0.5)
S3.show()

Using Blend

Share:
14,308
U.Swap
Author by

U.Swap

I used to do full-time Freelancing, Reason: Corporate IT Industries doesn't suite my solace by any stretch of the imagination! About my skills: Experienced Android Developer, Web Developer, Code Hacker, Freelancer & Entrepreneur, Certified Computer Vision Analyst. Achievements: Developed an simple 16-bit operating system,now approaching towards creating 32-bit protected mode kernel. Good understanding of operating system internals and also Linux kernel internals. Tried developing several different kinds of Linux Device Drivers. Also recently developed Linux distribution X-Dev Linux. Have good hands on practice on Java and python. Also have good experience in android application development since last 3 years. Have good hands on practice in C and ALP while operating system development. Assisted in many research oriented as well as commercial computer vision and data science projects. Assisted in research regarding security in TCP/IP stack implemented in Linux Kernel. Where You can find me: LinkedIN BitBucket Instagram Upwork Facebook

Updated on July 14, 2022

Comments

  • U.Swap
    U.Swap almost 2 years

    I have few satellite images each of them represents one channel of main satellite image, these are 11 images in total, each are labled with different channel, all images are in .tiff format with grayscale colorspace, now i simply want's to merge these images into one, to represent all channels into one image, so is this possible, remeber here, I don't want to concat images , which can be done using this:

    vis = np.concatenate((img1, img2), axis=1)
    

    I want to merge all of them into one single image , without distorting the data contained within, few channel images are attached below. enter image description here enter image description here enter image description here enter image description here

    Any help is appreciated.