【问题标题】:OpenCV convert RGB array to YUV422 in PythonOpenCV在Python中将RGB数组转换为YUV422
【发布时间】:2020-03-28 22:49:04
【问题描述】:

我需要将 RGB uint8 720x480x3 numpy 数组转换为 YUV422 uint8 720x480x2 数组。如何使用 OpenCV 做到这一点?如果 OpenCV 不支持,还有其他 Python 框架可以吗?

【问题讨论】:

标签: python opencv


【解决方案1】:

OpenCV 不支持您在评论中发布的 RGB 到 YUV 转换公式。

您可以使用 NumPy“手动”实现转换:

  • 将 RGB (BGR) 拆分为 R、G 和 B 并转换为 float
  • 根据here 中描述的公式计算 Y、U、V。
  • 水平向下采样 U 和 V(水平调整一半)。
  • 四舍五入,剪辑到uint8 的范围并转换为np.uint8 类型。
  • 交错 U 和 V 通道。
  • 合并 U 和 UV 通道。

这是一个代码示例:

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))

【讨论】:

    猜你喜欢
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 2011-10-23
    相关资源
    最近更新 更多