Формула преобразования RGB в YUV, которую вы разместили в своем комментарии, не поддерживается OpenCV.
Вы можете осуществить преобразование "вручную", используя NumPy:
- Разделить RGB (BGR) на R, G и B и преобразовать в
float
. - Вычислить Y, U, V в соответствии с формулой, описанной здесь .
- Уменьшить выборку U и V по горизонтали (изменить размер по горизонтали на половину).
- Округлить, обрезать диапазон
uint8
и преобразование в тип np.uint8
. - Чередование каналов U и V.
- Объединение каналов U и УФ.
Вот пример кода:
import numpy as np
import cv2
# Prepare BGR input (OpenCV uses BGR color ordering and not RGB):
bgr = cv2.imread('chelsea.png')
bgr = cv2.resize(bgr, (150, 100)) # Resize to even number of columns
# Split channles, and convert to float
b, g, r = cv2.split(bgr.astype(float))
rows, cols = r.shape
# Compute Y, U, V according to the formula described here:
# https://developer.apple.com/documentation/accelerate/conversion/understanding_ypcbcr_image_formats
# U applies Cb, and V applies Cr
# Use BT.709 standard "full range" conversion formula
y = 0.2126*r + 0.7152*g + 0.0722*b
u = 0.5389*(b-y) + 128
v = 0.6350*(r-y) + 128
# Downsample u horizontally
u = cv2.resize(u, (cols//2, rows), interpolation=cv2.INTER_LINEAR)
# Downsample v horizontally
v = cv2.resize(v, (cols//2, rows), interpolation=cv2.INTER_LINEAR)
# Convert y to uint8 with rounding:
y = np.round(y).astype(np.uint8)
# Convert u and v to uint8 with clipping and rounding:
u = np.round(np.clip(u, 0, 255)).astype(np.uint8)
v = np.round(np.clip(v, 0, 255)).astype(np.uint8)
# Interleave u and v:
uv = np.zeros_like(y)
uv[:, 0::2] = u
uv[:, 1::2] = v
# Merge y and uv channels
yuv422 = cv2.merge((y, uv))