本文主要是介绍《数字图像处理》-实验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: # 如果没有获取到视频帧则返回 falsebreakhsv = 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 编解码的程序。
四、上机代码
- 上机练习
- 程序练习
- 练习:运行程序并查看结果
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 npcapture = cv2.VideoCapture("giphy.gif")
while True:ret, frame = capture.read()if ret is False: # 如果没有获取到视频帧则返回 falsebreakhsv = 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
运行结果为:
- JPEG 图像压缩编码
提高部分:根据上机指导中 JPEG 编码原理的介绍,编写实现 JPEG 编解码的程序。
代码部分:
import cv2
import numpy as npdef 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)
运行结果:
这篇关于《数字图像处理》-实验6 彩色图像模型及图像编码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!