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?
Most of cases, cv2 method is faster than pil one.
We can use the concatenate() function of NumPy to concatenate the matrices of the images along different axes. For example, let's use the zeros() function of NumPy to create two images with different colors and then combine them horizontally using the concatenate() function.
OpenCV uses BGR image format. So, when we read an image using cv2. imread() it interprets in BGR format by default. We can use cvtColor() method to convert a BGR image to RGB and vice-versa.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With