《数字图像处理》-实验6 彩色图像模型及图像编码

一、上机目的

学习彩色图像处理、图像编码相关原理及编程实现方法

二、相关知识

 1、彩色图像的颜色空间

对于单色(灰度)图像而言,其每个像素的亮度用一个数值表示即可;而彩色图像的每 个像素包含了颜色信息,每个像素的光强度和色度须用 3 个数值描述。彩色图像的颜色空间 也称为颜色模型或彩色系统,用于对颜色进行描述和说明。常用的颜色空间包括 RGB、HIS、 HSV、YUV 等。

(1) RGB 颜色空间

白光通过玻璃棱镜会出现紫色到红色的连续彩色谱。光由多种色谱构成,在颜色空间中 理论上可以选取多种颜色。人眼中有大量对红、绿、蓝 3 种颜色敏感的锥状体细胞,因此, 我们常用红色(Red,R)、绿色(Green,G)、蓝色(Blue,B)组成的 RGB 颜色空间表达彩 色图像的信息。这 3 种原色的混合色基本覆盖了人类的色彩空间,从而满足了人类的色彩体 验。面向硬件设备的 RGB 颜色空间主要用于电视机、算机等电子系统感知、表示和显示图像。 例如,电视机通常使用红、绿、蓝三原色混合的加色,每种原色都会刺激眼睛的 3 种颜色受 体中的一种。

RGB 颜色空间基于三维直角坐标系,包括 R、G、B 3 个原始光谱分量,如图所示。RGB 颜色空间中的 R、G、B 3 个分量的值分别描述了红色、绿色、蓝色的亮度值。为了方便描述, 我们将 3 个分量都进行归一化处理,使得三元组中的每个数值均表示红色、绿色、蓝色三者 的比例。在图中,原点(0,0,0)代表黑色,点(1,1,1)代表白色,点(1,0,0)代表红色 (R),点(0,1,0)代表绿色(G),点(0,0,1)代表蓝色(B)。

(2)HIS 颜色空间

当描述物体颜色时,我们也常用 HSI 颜色空间,旨在接近人类视觉感知颜色的方式。HSI 颜色空间包含 3 个分量,分别是色调(Hue,H)、饱和度(Saturation,S)和亮度(Intensity, I),如下图所示。HSI 颜色空间双圆锥体的横截面称为色环,色环更加清晰地展示了色调和 饱和度两个参数,如图所示。色调 H 由角度表示,其反映了该颜色最接近哪个光谱波长。在 色环中,0°表示红色光谱,120°表示绿色光谱,240°表示蓝色光谱。饱和度 S 由色环的 圆心到颜色点的半径表示,距离越长表示饱和度越高,颜色越鲜明。在图中,亮度 I 由颜色 点到底部的距离表示。在 HSI 颜色空间中,底部表示黑色,顶部表示白色。

通俗来讲就是:

色调 H(Hue): 与光波的波长有关,它表示人的感官对不同颜色的感受,如红色、绿色、 蓝色等,它也可表示一定范围的颜色,如暖色、冷色等。

饱和度 S(Saturation): 表示颜色的纯度,纯光谱色是完全饱和的,加入白光会稀释 饱和度。饱和度越大,颜色看起来就会越鲜艳,反之亦然。

亮度 I(Intensity): 对应成像亮度和图像灰度,是颜色的明亮程度。

HSI 色彩空间和 RGB 色彩空间只是同一物理量的不同表示法,因而它们之间存在着 转 换关系。HIS 模型也称为 HLS (I 指 intensity)。

(3)HSV 模型

在图像处理中也常用 HSV 颜色空间,它比 RGB 更接近人们对彩色的感知经验。非常直 观地表达颜色的色调、鲜艳程度和明暗程度,方便进行颜色的对比。在 HSV 颜色空间下, 比 BGR 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。

HSV 中只有 Hue 一个通 道表示颜色。

HSV 表达彩色图像的方式由三个部分组成:

Hue(色调、色相)

Saturation(饱和度、色彩纯净度):饱和度表示颜色接近光谱色的程度。饱和度越高, 说明颜色越深,越接近光谱色饱和度越低,说明颜色越浅,越接近白色。饱和度为 0 表示纯 白色。取值范围为 0~100%,值越大,颜色越饱和。

Value(明度):决定颜色空间中颜色的明暗程度,明度越高,表示颜色越明亮,范围是 0-100%。明度为 0 表示纯黑色(此时颜色最暗)

HSV 的取值范围:原本输出的 HSV 的取值范围分别是 0-360, 0-1, 0-1;但是为了匹 配目标数据类型 OpenCV 将每个通道的取值范围都做了修改,于是就变成了 0-180,0-255, 0-255,并且同时解释道:为了适应 8bit 0-255 的取值范围,将 hue 通道 0-360 的取值 范围做了减半处理,这就是为什么 OpenCV 中 hue 通道的取值范围是 0-180;

HSV 对用户来说是一种比较直观的颜色模型。我们可以很轻松地得到单一颜色,即指定 颜色角 H,并让 V=S=1,然后通过向其中加入黑色和白色来得到我们需要的颜色。增加黑色 可以减小 V 而 S 不变,同样增加白色可以减小 S 而 V 不变。例如,要得到深蓝色,V=0.4 S=1 H=240 度。要得到浅蓝色,V=1 S=0.4 H=240 度。

RGB 颜色空间更加面向于工业,而 HSV 更加面向于用户,大多数做图像识别这一块的都 会运用 HSV 颜色空间,因为 HSV 颜色空间表达起来更加直观!

(4)YUV 模型

YUV 模型是电视信号系统所采用的颜色编码方式。这三个变量分别表示是像素的亮度 (Y)以及红色分量与亮度的信号差值(U)和蓝色与亮度的差值(V)。这种颜色模型主要用 于视频和图像的传输,该模型的产生与电视机的发展历程密切相关。由于彩色电视机在黑白 电视机发明之后才产生,因此用于彩色电视机的视频信号需要能够兼容黑白电视机。彩色电 视机需要三个通道的数据才能显示彩色,而黑白电视机只需要一个通道的数据即可,因此为 了使视频信号能够兼容彩色电视与黑白电视,将 RGB 编码方式转变成 YUV 的编码方式,其 Y 通道是图像的亮度,黑白电视只需要使用该通道就可以显示黑白视频图像,而彩色相机通过 将 YUV 编码转成 RGB 编码方式,便可以在彩色电视种显示彩色图像,较好的解决了同一个视 频信号兼容不同类型电视的问题。RGB 模型与 YUV 模型之间的转换关系如式所示,其中 RGB 取值范围均为 0-255。

(5)程序练习

A.不同颜色模型的转换

CvtColor 是 Opencv 里的颜色空间转换函数,可以实现 RGB 颜色向 HSV,HSI 等颜色空 间的转换,也可以转换为灰度图像。

cvtColor(input_image, flag),其中 flag 决定转换的类型

cvtColor()支持多种颜色空间之间的转换,其支持的转换类型和转换码如下:

1、RGB 和 BGR(opencv 默认的彩色图像的颜色 空间是 BGR)颜色空间的转换 cv::COLOR_BGR2RGB cv::COLOR_RGB2BGR cv::COLOR_RGBA2BGRA cv::COLOR_BGRA2RGBA

2、向 RGB 和 BGR 图像中增添 alpha 通道 cv::COLOR_RGB2RGBA cv::COLOR_BGR2BGRA

3、从 RGB 和 BGR 图像中去除 alpha 通道 cv::COLOR_RGBA2RGB cv::COLOR_BGRA2BGR

4、从 RBG 和 BGR 颜色空间转换到灰度空间 cv::COLOR_RGB2GRAY cv::COLOR_BGR2GRAY cv::COLOR_RGBA2GRAY cv::COLOR_BGRA2GRAY

5、从灰度空间转换到 RGB 和 BGR 颜色空间 cv::COLOR_GRAY2RGB cv::COLOR_GRAY2BGR cv::COLOR_GRAY2RGBA cv::COLOR_GRAY2BGRA

6、RGB 和 BGR 颜色空间与 BGR565 颜色空间之 间的转换 cv::COLOR_RGB2BGR565 cv::COLOR_BGR2BGR565 cv::COLOR_BGR5652RGB cv::COLOR_BGR5652BGR cv::COLOR_RGBA2BGR565 cv::COLOR_BGRA2BGR565 cv::COLOR_BGR5652RGBA cv::COLOR_BGR5652BGRA

7、灰度空间域 BGR565 之间的转换 cv::COLOR_GRAY2BGR555 cv::COLOR_BGR5552GRAY 8、RGB 和 BGR 颜色空间与 CIE XYZ 之间的转换 cv::COLOR_RGB2XYZ cv::COLOR_BGR2XYZ cv::COLOR_XYZ2RGB cv::COLOR_XYZ2BGR

9、RGB 和 BGR 颜色空间与 uma 色度(YCrCb 空 间)之间的转换 cv::COLOR_RGB2YCrCb cv::COLOR_BGR2YCrCb cv::COLOR_YCrCb2RGB cv::COLOR_YCrCb2BGR

10、RGB 和 BGR 颜色空间与 HSV 颜色空间之间 的相互转换 cv::COLOR_RGB2HSV cv::COLOR_BGR2HSV cv::COLOR_HSV2RGB cv::COLOR_HSV2BGR

11、RGB 和 BGR 颜色空间与 HLS 颜色空间之间 的相互转换 cv::COLOR_RGB2HLS cv::COLOR_BGR2HLS cv::COLOR_HLS2RGB cv::COLOR_HLS2BGR

12、RGB 和 BGR 颜色空间与 CIE Lab 颜色空间 之间的相互转换 cv::COLOR_RGB2Lab cv::COLOR_BGR2Lab cv::COLOR_Lab2RGB cv::COLOR_Lab2BGR

13、RGB 和 BGR 颜色空间与 CIE Luv 颜色空间 之间的相互转换 cv::COLOR_RGB2Luv cv::COLOR_BGR2Luv cv::COLOR_Luv2RGB cv::COLOR_Luv2BGR

14、Bayer 格式(raw data)向 RGB 或 BGR 颜 色空间的转换 cv::COLOR_BayerBG2RGB cv::COLOR_BayerGB2RGB cv::COLOR_BayerRG2RGB cv::COLOR_BayerGR2RGB cv::COLOR_BayerBG2BGR cv::COLOR_BayerGB2BGR cv::COLOR_BayerRG2BGR cv::COLOR_BayerGR2BGR

转换代码实例如下:
 

def color_space_demo(image):

gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

cv.imshow("gray", gray)

hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)

cv.imshow("hsv", hsv)

hls = cv.cvtColor(image, cv.COLOR_BGR2HLS)

cv.imshow("hls", hls)

yuv = cv.cvtColor(image, cv.COLOR_BGR2YUV)

cv.imshow("yuv", yuv)

ycrcb = cv.cvtColor(image, cv.COLOR_BGR2YCrCb)

cv.imshow("ycrcb", ycrcb)

练习:参考上面的转换代码,对比不同颜色空间下的图像显示效果。

B.提取某种颜色

Opencv 中可以用 CV2.inRange 提取某种颜色。

cv2.inRange(hsv, lower_red, upper_red):函数参数有三个:

hsv 指的是原图

lower_red 指的是图像中低于这个 lower_red 的值,图像值变为 0

upper_red 指的是图像中高于这个 upper_red 的值,图像值变为 0 而在 lower_red~ upper_red 之间的值变成 255

最后输出的图像是二值图。、

HSV 中 H、S、V 对照表

例程参考:
 

def extract_object_demo(): #将某种颜色的对象显示出来

   capture = cv.VideoCapture("blue.gif")

   while True:

      ret, frame = capture.read()

      if ret is False: # 如果没有获取到视频帧则返回 false

          break

      hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)

      lower_hsv = np.array([100, 43, 46]) # hsv 中 h,s,v 的最小值

      upper_hsv = np.array([124, 255, 255]) # hsv 中的 h,s,v 最大值

       # 提取指定范围颜色,保留指定范围颜色, 其余置为黑(0)

      mask = cv.inRange(hsv, lowerb=lower_hsv, upperb=upper_hsv) # 用 inRange 函数提取 指定颜色范围,这里对 hsv 来处理

      dst = cv.bitwise_and(frame, frame, mask = mask)

      cv.imshow("video", frame)

      cv.imshow("mask", mask)

      cv.imshow("mask1", dst)

      c = cv.waitKey(40)

      if c == 27:

         break

练习:运行并理解上述程序,查看运行效果,判断完成哪种颜色提取,尝试修改参数 完成面部颜色的提取。

2、JPEG 图像压缩编码

  JPEG(Joint Photographic Experts Group)是 JPEG 标准的产物,该标准由国际标准 化组织(ISO)制订,是面向连续色调静止图像的一种压缩标准。JPEG 格式是最常用的图像 文件格式,后缀名为.jpg 或.jpeg。

JPEG 编码主要基于分块编码和 DCT 变换实现,基本的编码原理及流程如下:

三、上机内容

(1)按照上面相关知识的介绍,通过编写或运行相应的程序实例掌握颜色空间相关知 识及程序实现方法,所有运行过的程序及运行结果截图保存到 word 文档中。

(2)提高部分:根据上机指导中 JPEG 编码原理的介绍,编写实现 JPEG 编解码的程序。

四、上机代码

  • 上机练习
  1. 程序练习
  1. 练习:运行程序并查看结果

A、不同颜色模型的转换

代码部分:

import cv2
import numpy as np
image = cv2.imread('fengjing.png')
cv2.imshow("src",image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", gray)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow("hsv", hsv)
hls = cv2.cvtColor(image, cv2.COLOR_BGR2HLS)
cv2.imshow("hls", hls)
yuv = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
cv2.imshow("yuv", yuv)
ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)
cv2.imshow("ycrcb", ycrcb)
cv2.waitKey(0)

运行截图:

 

B、提取某种颜色

代码部分:

import cv2
import numpy as np

capture = cv2.VideoCapture("giphy.gif")
while True:
    ret, frame = capture.read()
    if ret is False: # 如果没有获取到视频帧则返回 false
        break
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    lower_hsv = np.array([100, 43, 46]) # hsv 中 h,s,v 的最小值
    upper_hsv = np.array([124, 255, 255]) # hsv 中的 h,s,v 最大值
    # 提取指定范围颜色,保留指定范围颜色, 其余置为黑(0)
    mask = cv2.inRange(hsv, lowerb=lower_hsv, upperb=upper_hsv) # 用 inRange 函数提取
    #指定颜色范围,这里对 hsv 来处理
    dst = cv2.bitwise_and(frame, frame, mask = mask)
    cv2.imshow("video", frame)
    cv2.imshow("mask", mask)
    cv2.imshow("mask1", dst)
    c = cv2.waitKey(40)
    if c == 27:
        break

运行结果为:

  1. JPEG 图像压缩编码

提高部分:根据上机指导中 JPEG 编码原理的介绍,编写实现 JPEG 编解码的程序。

代码部分:

import cv2
import numpy as np

def dct_2d(block):
    return cv2.dct(np.float32(block))

def idct_2d(block):
    return cv2.idct(block)

def quantize(block, quant_matrix):
    return np.round(block / quant_matrix)

def dequantize(block, quant_matrix):
    return block * quant_matrix

# JPEG 量化矩阵
quant_matrix = np.array([[16, 11, 10, 16, 24, 40, 51, 61],
                         [12, 12, 14, 19, 26, 58, 60, 55],
                         [14, 13, 16, 24, 40, 57, 69, 56],
                         [14, 17, 22, 29, 51, 87, 80, 62],
                         [18, 22, 37, 56, 68, 109, 103, 77],
                         [24, 35, 55, 64, 81, 104, 113, 92],
                         [49, 64, 78, 87, 103, 121, 120, 101],
                         [72, 92, 95, 98, 112, 100, 103, 99]])

def process_image(img_path):
    # 读取图像
    img = cv2.imread(img_path)
    height, width, _ = img.shape

    # 转换到YCbCr颜色空间
    img_ycbcr = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
    y, cb, cr = cv2.split(img_ycbcr)

    # 对每个颜色通道进行处理
    for channel in [y, cb, cr]:
        # 分块处理
        for i in range(0, height, 8):
            for j in range(0, width, 8):
                # 提取8x8块
                block = channel[i:i+8, j:j+8]
                # DCT变换
                dct_block = dct_2d(block)
                # 量化
                quantized_block = quantize(dct_block, quant_matrix)
                # 反量化
                dequantized_block = dequantize(quantized_block, quant_matrix)
                # 逆DCT变换
                channel[i:i+8, j:j+8] = idct_2d(dequantized_block)

    # 合并通道
    img_reconstructed = cv2.merge([y, cb, cr])
    img_reconstructed = cv2.cvtColor(img_reconstructed, cv2.COLOR_YCrCb2BGR)

    # 显示原始图像和重构图像
    cv2.imshow('Original Image', img)
    cv2.imshow('Reconstructed Image', img_reconstructed)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# 测试代码
image_path = "11.jpg" # 替换为你的图片路径
process_image(image_path)

运行结果:

  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
对彩色图像进行图像压缩的传统图像压缩算法有以下几种: 1. 基于离散余弦变换的JPEG压缩算法。该算法将彩色图像转换为YCbCr颜色空间,并对亮度分量进行离散余弦变换(DCT)。接着,将DCT系数进行量化、熵编码和位流编码,以实现压缩。该算法已经成为图像压缩的标准之一,被广泛应用于数字图像传输、存储和处理中。 2. 基于小波变换的图像压缩算法。该算法使用小波变换将图像分解成不同尺度和方向的频带,然后对高频分量进行压缩。小波变换可以使得图像的高频分量更加稀疏,从而实现更好的压缩效果。 3. 基于向量量化的图像压缩算法。该算法将图像分成若干个小块,并将每个小块看作一个向量。然后使用聚类算法将这些向量映射到一组代码簇中,并将每个向量替换为其所属代码簇的中心。这样可以实现对图像数据的有损压缩,但是图像质量可能会受到影响。 4. 基于预测编码图像压缩算法。该算法根据图像数据的统计特性,使用预测模型来预测每个像素的值,并将预测误差进行编码。由于图像数据中的像素通常具有一定的相关性,因此预测编码可以实现很好的压缩效果。 以上就是对彩色图像进行图像压缩的传统图像压缩算法的介绍。当然,还有很多其他的图像压缩算法和方法,您可以根据具体的需求选择合适的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云边牧风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值