How to encode Grayscale, SobelX and SobelY in one RGB image using OpenCV?

Viewed 593

I have an RGB image. I want to save it as a new image where Grayscale, SobelX and SobelY would be saved in R, G and B channels of a new image. How to do such thing in OpenCV?

In other words, say we had RBG image, we wanted to create a new RGB (or BGR does not matter) image which would contain in its channels Grayscale values (in B), sobelX (in R) sobelY (in G). Main problem is that we need to somehow quantize\normalise Sobel to 0-256 values... How to do such thing?

Thanks to @Rabbid79 ended up with:

%matplotlib inline
from matplotlib import pyplot as plt
import cv2
import numpy as np
!wget "https://helpx.adobe.com/content/dam/help/en/stock/how-to/visual-reverse-image-search/jcr_content/main-pars/image/visual-reverse-image-search-v2_intro.jpg" -O dt.jpg

src = cv2.imread('./dt.jpg', cv2.IMREAD_GRAYSCALE)
def show(im):
  plt.imshow(im)
  plt.show()

show(src)
sobelx = cv2.Sobel(src, cv2.CV_64F, 1, 0)
sobely = cv2.Sobel(src, cv2.CV_64F, 0, 1)

abs_grad_x = cv2.convertScaleAbs(sobelx)
abs_grad_y = cv2.convertScaleAbs(sobely)
grad = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)
show(grad)
b = cv2.GaussianBlur(src,(3,3),0)
laplacian = cv2.Laplacian(b,cv2.CV_64F)
l_dst = cv2.convertScaleAbs( laplacian  );
show(l_dst)
dest = np.dstack([src, l_dst, grad]).astype(np.uint8)
show(dest)
1 Answers

Load the image as gray scale image (IMREAD_GRAYSCALE):

gray = cv2.imread(image_name, cv2.IMREAD_GRAYSCALE)

Create a sobel-X respectively sobel-Y

sobelx = cv2.convertScaleAbs((cv2.Sobel(gray, cv2.CV_64F, 1, 0)))
sobely = cv2.convertScaleAbs((cv2.Sobel(gray, cv2.CV_64F, 0, 1)))

Create an empty numpy array with the size of the source image and assign the gray scale, sobel-X and sobel-Y to the channels of the target image:

dest = np.empty((gray.shape[0], gray.shape[1], 3), np.uint8)
dest[:,:,0] = gray
dest[:,:,1] = sobelx
dest[:,:,2] = sobely

Or merge the images:

dest = cv2.merge((gray, sobelx, sobely))

Respectively use numpy.dstack:

dest = np.dstack([gray, sobelx, sobely]).astype(np.uint8)

All together:

gray   = cv2.imread(image_name, cv2.IMREAD_GRAYSCALE)
sobelx = cv2.convertScaleAbs((cv2.Sobel(gray, cv2.CV_64F, 1, 0)))
sobely = cv2.convertScaleAbs((cv2.Sobel(gray, cv2.CV_64F, 0, 1)))
dest   = np.dstack([gray, sobelx, sobely]).astype(np.uint8)
Related