色彩空间设置ycbcr和rgb,rgb转ycbcr程序

  色彩空间设置ycbcr和rgb,rgb转ycbcr程序

  摘要:本文主要介绍了python语言在RGB和YCbCr颜色空间之间的转换,以及RGB和YCbCr颜色空间的概念之间的关系,包括内容灰度值和亮度的关系,RGB颜色空间和颜色控制的关系,YCBCR颜色空间及其与RGB的转换关系。有需要的朋友可以参考一下。

  00-1010前言:1、灰度值与亮度的关系2、RGB颜色空间与颜色控制3、YCbCr颜色空间及其与RGB的变换关系

  

目录

  人们如何感知或理解颜色是一个非常复杂的问题。本文不讨论如何从生物学或心理学的角度分析颜色,而是讨论数值如何影响颜色。本文主要介绍了RGB和YCbCr颜色空间的概念和转换之间的关系。

  

前言:

  人类可以从灰度图像中获得理解场景所需的大部分信息,因此观看黑白电视机不会严重影响人们对视频中场景的理解。图像的亮度与像素值成正比。如果需要增加图像的亮度,比如逐渐由黑变白,可以增加单通道灰度图像的像素值。一般用8位来保存灰度图像的每个像素值,像素值的范围是0-255。

  下面的例子展示了灰度图像的像素值增加时亮度的变化过程,假设图像初始像素值为0:

  以上是lena图像像素值增加时肤色的变化。代码的实现相对简单。读图,然后不断增加图像每个像素值的偏移量:

  将numpy作为np导入

  将matplotlib.pyplot作为plt导入

  导入图像

  image=imageio.imread(lena.jpg )

  #设置每个周期的像素增加量。

  shift=6*np.ones(shape=(64,64))

  图表()

  对于(1,17):范围内的I

  情节子情节(4,4,I)

  plt.imshow(image/255,cmap=gray ,vmin=0,vmax=1)

  plt.axis(“关”)

  图像=图像偏移

  

1、灰度值和亮度的关系

  RGB模型在硬件设备中应用广泛,通过叠加R(红)、G(绿)、B(蓝)可以形成更多的颜色。RGB颜色空间与后面要介绍的YCbCr颜色空间和HSV颜色空间之间存在线性变换关系,所以只要你有RGB图像,就可以得到其他颜色空间的图像。

  在一幅图像中,R、G、B分别作为三个通道。如果任意两个通道的值为0,图像的颜色将由非零的通道控制。

  比如:

  实现上面的效果需要三个步骤:

  (1)创建3通道空图像(2)将单通道图像添加到3通道空图像的R通道(3)将3通道图像的R通道的像素值连续增加偏移量# 1:创建3通道空图像。

  =np.zeros(shape=(64,64,3))

  r=imageio.imread(lena.jpg)/2

  # 2:将单通道图像添加到3通道空图像的R通道

  image[:0]=image[:0]

  shift=4*np.ones(shape=(64,64))

  图表()

  对于(1,17):范围内的I

  情节子情节(4,4,I)

  plt.imshow(image/255,vmin=0,vmax=1)

  plt.axis(“关”)

  # (3)增加对3通道图像的R通道像素值的偏移

  image[:0]=image[:0] shift

  但是因为最终图像的颜色是三个R\G\B的叠加,而实际上并不是只有其中一个,所以很难控制最终图像的颜色,所以我们需要其他的颜色空间。

  

2、RGB颜色空间与颜色控制

  YCbCr色彩空间中的y是亮度通道,Cb是蓝色分量,Cr是红色分量。它通常用于电视系统。比如早期的黑白电视机用的是彩电信号线,所以亮度值可以单独使用。这个功能在RGB色彩空间中无法实现,因为

  我们不能仅仅使用RGB中某个通道作为亮度信号来使用。

  由于YCbCr经常和YUV颜色空间比较相似,所以二者容易被认为是从属或者等价关系,按照维基百科的说法:YUV 是模拟信号,而YCbCr是数字信号。

  YCbCr和RGB存在线性的变换关系,本文介绍的变换矩阵来自ITU.BT-601,所规定的变换矩阵Trans形式如下:

  

  实现rgb2ycbcr()函数只需要两个步骤:(1)创建变换矩阵Trans;(2)遍历图像每个像素点,并对三个通道分别进行矩阵计算。

  下面的代码展示了如何实现从RGB空间到YCBCR变换:

  

def rgb2ycbcr(rgb_image):

      """convert rgb into ycbcr"""

      if len(rgb_image.shape)!=3 or rgb_image.shape[2]!=3:

          raise ValueError("input image is not a rgb image")

      rgb_image = rgb_image.astype(np.float32)

      # 1:创建变换矩阵,和偏移量

      transform_matrix = np.array([[0.257, 0.564, 0.098],

                                   [-0.148, -0.291, 0.439],

                                   [0.439, -0.368, -0.071]])

      shift_matrix = np.array([16, 128, 128])

      ycbcr_image = np.zeros(shape=rgb_image.shape)

      w, h, _ = rgb_image.shape

      # 2:遍历每个像素点的三个通道进行变换

      for i in range(w):

          for j in range(h):

              ycbcr_image[i, j, :] = np.dot(transform_matrix, rgb_image[i, j, :]) + shift_matrix       

      return ycbcr_image

  如果想要求逆变换,只需要根据矩阵求逆法则进行就可以了,需要注意的是:逆变换时偏移矩阵也需要左乘变换矩阵Trans的逆!逆变换只需要将rgb2ycbcr中的transform_matrix求逆即可,再次强调:shift_matrix也需要乘以transform_matrix的逆,而不是直接减去shift_matrix!

  

def ycbcr2rgb(ycbcr_image):

      """convert ycbcr into rgb"""

      if len(ycbcr_image.shape)!=3 or ycbcr_image.shape[2]!=3:

          raise ValueError("input image is not a rgb image")

      ycbcr_image = ycbcr_image.astype(np.float32)

      transform_matrix = np.array([[0.257, 0.564, 0.098],

                                   [-0.148, -0.291, 0.439],

                                   [0.439, -0.368, -0.071]])

      transform_matrix_inv = np.linalg.inv(transform_matrix)

      shift_matrix = np.array([16, 128, 128])

      rgb_image = np.zeros(shape=ycbcr_image.shape)

      w, h, _ = ycbcr_image.shape

      for i in range(w):

          for j in range(h):

              rgb_image[i, j, :] = np.dot(transform_matrix_inv, ycbcr_image[i, j, :]) - np.dot(transform_matrix_inv, shift_matrix)

      return rgb_image.astype(np.uint8)

  所需要的包以及绘图代码如下,绘图用到的就是上面定义的两个函数。首先将rgb转为ycbcr,在从ycbcr转为rgb:

  

import numpy as np

  import imageio

  import matplotlib.pyplot as plt

  rgb_image = imageio.imread("lena.jpg")

  ycbcr_image = rgb2ycbcr(rgb_image)

  cycle_image = ycbcr2rgb(ycbcr_image)

  images = [rgb_image, ycbcr_image, cycle_image]

  titles = ["orignal", "ycbcr", "cycle"]

  for i in range(1, len(images)+1):

      plt.subplot(1, 3, i)

      plt.title(titles[i-1])

      plt.imshow(images[i-1]/255)

  下图中左边是原始的rgb图像,中间是转换得到的ycbcr空间图像,右边是再次转回rgb空间的图像:

  

  最后,对比了opencv提供的标准库的转换效果:

  

import cv2

  rgb_image = imageio.imread("lena.jpg")

  ycrcb_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2YCR_CB)

  cycle_image = cv2.cvtColor(ycbcr_image, cv2.COLOR_YCR_CB2RGB)

  images = [rgb_image, ycrcb_image, cycle_image]

  titles = ["orignal", "ycrcb", "cycle"]

  for i in range(1, len(images)+1):

      plt.subplot(1, 3, i)

      plt.title(titles[i-1])

      plt.imshow(images[i-1]/255)

  opencv得到的结果如下:

  

  原始rgb效果和cycle(重构)效果很接近,而中间结果不一致是因为opencv采用的是ycrcb,而不是ycbcr。

  到此这篇关于python实现RGB与YCBCR颜色空间转换的文章就介绍到这了,更多相关python颜色空间转换内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: