AMINE DZ
AMINE DZ

Reputation: 25

How to Display Colored Y Cb Cr Channels in Python OpenCV?

I understand how to convert a BGR image to YCrCb format using cvtColor() and separate different channels using split() in OpenCV. However, these channels are displayed as grayscale images:

imgYCrCB = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
Y, Cr, Cb = cv2.split(imgYCrCB)
cv2.imshow("Y", Y)
cv2.imshow("Cr", Cr)
cv2.imshow("Cb", Cb)
cv2.waitKey(0)

This code give these results:

Gray images:
enter image description here

I would like to display Cb and Cr channels in color like this image:
enter image description here

How can I do it?

Upvotes: 1

Views: 1806

Answers (2)

Rotem
Rotem

Reputation: 32094

The trick for getting the false colors effect for displaying Cb and Cr is relatively simple:

  • For Cb false colors:
    Fill Y and Cr with value 128, and convert back to BGR.
  • For Cr false colors:
    Fill Y and Cb with value 128, and convert back to BGR.
  • Y is kept in Grayscale format.

Value 128 applies middle gray for Y.
When Cb=128, there are no "blue tones" (Cb is "neutralized").
When Cr=128, there are no "red tones" (Cr is "neutralized").


Code sample:

import cv2
import numpy as np

img = cv2.imread('rgb.png')  # Read input image in BGR format

imgYCrCB = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)  # Convert RGB to YCrCb (Cb appiles V, and Cr applies U).

Y, Cr, Cb = cv2.split(imgYCrCB)

# Fill Y and Cb with 128 (Y level is middle gray, and Cb is "neutralized").
onlyCr = imgYCrCB.copy()
onlyCr[:, :, 0] = 128
onlyCr[:, :, 2] = 128
onlyCr_as_bgr = cv2.cvtColor(onlyCr, cv2.COLOR_YCrCb2BGR)  # Convert to BGR - used for display as false color

# Fill Y and Cr with 128 (Y level is middle gray, and Cr is "neutralized").
onlyCb = imgYCrCB.copy()
onlyCb[:, :, 0] = 128
onlyCb[:, :, 1] = 128
onlyCb_as_bgr = cv2.cvtColor(onlyCb, cv2.COLOR_YCrCb2BGR)  # Convert to BGR - used for display as false color


cv2.imshow('img', img)
cv2.imshow('Y', Y)
cv2.imshow('onlyCb_as_bgr', onlyCb_as_bgr)
cv2.imshow('onlyCr_as_bgr', onlyCr_as_bgr)
cv2.waitKey()
cv2.destroyAllWindows()

cv2.imwrite('Y.png', Y)
cv2.imwrite('onlyCb_as_bgr.png', onlyCb_as_bgr)
cv2.imwrite('onlyCr_as_bgr.png', onlyCr_as_bgr)

Y:
enter image description here

onlyCb_as_bgr:
enter image description here

onlyCr_as_bgr:
enter image description here

Upvotes: 2

fmw42
fmw42

Reputation: 53081

Here is a simple way to do that by combining channels using the channel, the channel inverted, and a mid-gray image in Python/OpenCV.

Input:

enter image description here

import cv2
import numpy as np 

# read image
img = cv2.imread('barn.jpg')
hh, ww = img.shape[:2]

# convert to YCbCr
YCrCb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)

# separate channels
Y, Cr, Cb = cv2.split(YCrCb)

# create a mid-gray constant image
gray = np.full((hh,ww), 128, dtype=np.uint8)

# invert Cr and Cb
Cr_inv = cv2.bitwise_not(Cr)
Cb_inv = cv2.bitwise_not(Cb)

# combine channels to get the Cr and Cb colorized images as if BGR
Cr_colored = cv2.merge([gray, Cr_inv, Cr])
Cb_colored = cv2.merge([Cb, Cb_inv, gray])
Y_colored = cv2.merge([Y, Y, Y])

# save results
cv2.imwrite('Y_colored.png', Y_colored)
cv2.imwrite('Cr_colored.png', Cr_colored)
cv2.imwrite('Cb_colored.png', Cb_colored)

# show results
cv2.imshow('Y_colored', Y_colored)
cv2.imshow('Cr_colored', Cr_colored)
cv2.imshow('Cb_colored', Cb_colored)
cv2.waitKey()

Y:

enter image description here

Cr:

enter image description here

Cb:

enter image description here

Upvotes: 0

Related Questions