How to convert a 1 channel image into a 3 channel with opencv2?

Question:

I’m really stumped on this one. I have an image that was [BGR2GRAY]’d earlier in my code, and now I need to add colored circles and such to it. Of course this can’t be done in a 1 channel matrix, and I can’t seem to turn the damned thing back into 3.

numpy.dstack() crashes everything

GRAY2BGR does not exist in opencv2

cv.merge(src1, src2, src3, dst) has been turned into cv2.merge(mv) where mv = "a vector of matrices", whatever that means.

Any ideas?

Opencv2.4.3 refmanual

Asked By: grenadier

||

Answers:

I cant say about python but I can tell you the C++ interface…

gray_image //you have it already
Mat im_coloured = Mat::zeros(gray_image.rows,gray_image.cols,CV_8UC3);

vector<Mat> planes;

for(int i=0;i<3;i++)
    planes.push_back(gray_image);

merge(planes,im_coloured);
Answered By: rotating_image

Here’s a way of doing that in Python:

img = cv2.imread("D:\img.jpg")
gray = cv2.cvtColor(img, cv.CV_BGR2GRAY)

img2 = np.zeros_like(img)
img2[:,:,0] = gray
img2[:,:,1] = gray
img2[:,:,2] = gray

cv2.circle(img2, (10,10), 5, (255,255,0))
cv2.imshow("colour again", img2)
cv2.waitKey()

Here’s the complete code for OpenCV3:

import cv2
import numpy as np
img = cv2.imread('10524.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = np.zeros_like(img)
img2[:,:,0] = gray
img2[:,:,1] = gray
img2[:,:,2] = gray
cv2.imwrite('10524.jpg', img2)
Answered By: b_m

It is the python equivalent:
imgray is a numpy array containing 1-channel image.

img2 = cv2.merge((imgray,imgray,imgray))
Answered By: Wajahat

Below I assume you don’t have 3-channel image in proper shape, so zeros_like function (used in answer above) will not be useful.

img2 = np.zeros( ( np.array(img).shape[0], np.array(img).shape[1], 3 ) )
img2[:,:,0] = img # same value in each channel
img2[:,:,1] = img
img2[:,:,2] = img

if img is numpy array then it can be shorten from np.array(img).shape to img.shape

Answered By: nosbor

I was using tensorflow when I needed this. Here’s my solution:

image = tf.expand_dims(image, -1)
x1 = image.shape[0]
x2 = image.shape[1]
image = tf.reshape(tf.broadcast_to(image, (x1, x2, 3)),  (x1, x2, 3))
Answered By: Marcel Klehr

Why is everybody using cv2.merge and low level array operations? Why not simply use cv2.cvtColor?

img = np.zeros((640, 480), np.uint8)  # create grayscale image
print(img.shape)
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)  # grayscale --> BGR
print(img.shape)

which outputs:

(640, 480)
(640, 480, 3)
Answered By: Mikel B
RGB = np.stack([gray, gray, gray], axis = -1)
Answered By: Ripon Kumar Saha

if use opencv-python, can use np.repeat function.

img = np.array([[1, 2], [1, 2]])
img2 = np.repeat(img[:, :, np.newaxis], 3, axis=2)
Answered By: rainy
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.