2

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)
DuckQueen
  • 772
  • 10
  • 62
  • 134
  • Do you know how to form those 3 things and just want to know how to assemble the 3 results? Which channel do you plan to use in making the Sobel images? Might I ask **why** you want to do this and what you plan to do with the result? – Mark Setchell Jul 05 '20 at 14:49
  • You can use [`cv2.merge()`](https://stackoverflow.com/questions/59669385/how-does-cv2-merger-g-b-works) – beaker Jul 05 '20 at 14:52
  • 1
    @MarkSetchell I think it'll look trippy! Perhaps it's only for saving the image, but even if it's a mistake and doesn't achieve what the OP intended, it will be fun and maybe even insightful. – beaker Jul 05 '20 at 14:55
  • 1
    @beaker I like your positive approach – Mark Setchell Jul 05 '20 at 15:15

1 Answers1

5

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)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174