11

this is sort of an ongoing challenge for me. I'm trying to combine two 3 RGB images into a single 6 channel TIFF image using openCV.

So far my code is as follows:

import cv2
import numpy as np

im1 = cv2.imread('im1.jpg')
im2 = cv2.imread('im2.jpg')

merged = np.concatenate((im1, im2), axis=2) # creates a numpy array with 6 channels 

cv2.imwrite('merged.tiff', merged)

I've also tried using openCV's split() and merge() methods and get the same results

import cv2
import numpy as np

im1 = cv2.imread('im1.jpg')
im2 = cv2.imread('im2.jpg')

b1,g1,r1 = cv2.split(im1)
b2,g2,r2 = cv2.split(im2)

merged = cv2.merge((b1,g1,r1,b2,g2,r2))

cv2.imwrite('merged.tiff', merged)

When I run the imwrite() function I get the following error:

OpenCV Error: Assertion failed (image.channels() == 1 || image.channels() == 3 || image.channels() == 4) in cv::imwrite_, file C:\builds\master_PackSlaveAddon-win32-vc12-static\opencv\modules\imgcodecs\src\loadsave.cpp, line 455
Traceback (most recent call last):
  File "", line 1, in 
cv2.error: C:\builds\master_PackSlaveAddon-win32-vc12-static\opencv\modules\imgcodecs\src\loadsave.cpp:455: error: (-215) image.channels() == 1 || image.channels() == 3 || image.channels() == 4 in function cv::imwrite_ 

Both images are identical in dimensions (900X1200). I'm thinking that openCV can't write more than 4 channels (RGBA) to a tiff image and I'm having no luck with finding an alternative way to encode this image.

I'm flirting with the idea of creating my own function to write the binary data with appropriate headers but that is way deeper than I want to go.

Is there another function in openCV that I can use that will work, or another library that can write this numpy array to tiff with 6 channels?

1 Answer 1

8

The OpenCV uses libpng, libtiff, etc modules internally to write RGB images, As various image representation formats like jpg, png, etc. assume the fact that the input array must be a single channel, 3 channel or 4 channel. The assumption is made to optimize the disk size of image. But the same assumption would be violated in 6-channel matrix.

So you may use a serialization library like pickle, it can be used in general to serialize any Python Object and in this case you want to serialize a numpy matrix, so it will work fine, However You won't be able to take the advantage of compression techniques used by png or jpg format.

import numpy as np
import pickle

arr = np.ones((1000, 1000, 6), dtype=np.uint8) * 255

with open("arr_dump.pickle", "wb") as f_out:
    pickle.dump(arr, f_out)

with open("arr_dump.pickle", "rb") as f_in:
    arr_new = pickle.load(f_in)
    print arr_new.shape

However if you are concerned with the size of the file, and want to use the memory optimization of tiff or png, etc. then I would recommend you to split your 6-channel image to various channels and create 2 new 3-channel matrices and use imwrite on them to save, and while reading, read both images and combine them to 6-channel image.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.