cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
时间: 2023-10-27 20:53:54 浏览: 173
这段代码是使用OpenCV库中的cvtColor函数,将BGR格式的图像转换为YCrCb格式的图像。YCrCb是一种颜色空间,也称作YUV色彩空间,其中Y表示亮度(Luma),Cr和Cb表示颜色差(Chroma)。该函数的第一个参数是输入图像,第二个参数是转换的方式,这里是从BGR到YCrCb的转换。函数返回转换后的图像。
相关问题
cv2提取ycrcb图像的cr分量图
可以使用OpenCV中的cv2.split()函数来提取YCrCb图像的Cr分量图。
以下是一个简单的示例代码:
```
import cv2
# 读取图像
img = cv2.imread('image.jpg')
# 转换为YCrCb颜色空间
ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
# 提取Cr分量图
Y, Cr, Cb = cv2.split(ycrcb)
# 显示Cr分量图
cv2.imshow('Cr', Cr)
cv2.waitKey(0)
```
运行代码后,就可以看到Cr分量图像被显示出来了。
a)请对Lena彩色图(lena_color_256.tif)转为YUV420格式,并存储为lena_256x256.yuv,获得其文件大小(bytes)。 b)请读入lena_256x256.yuv文件,并显示其原图、亮度图、色度图(Cb,Cr)于同一窗口。 c)请分别对b)中的结果进行DCT8x8变换,并使用上述QY和QC量化矩阵进行相应量化。量化完要取整 Qr=(16 11 10 16 24 40 51 61 12 12 14 19 26 58 60 55 14 13 16 24 40 57 69 56 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 ) Qc=(17 18 24 47 99 99 99 99 18 21 26 66 99 99 99 99 24 26 56 99 99 99 99 99 47 66 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99) d)请使用Zig-Zag扫描法对c)中的结果进行扫描,并使用游程编码(RLC)方法对其进行编码。 e)请使用哈夫曼编码方式对d)中的结果进行熵编码,并存为lena_256x256.cmp文件,获得其文件大小。 f)比较lena_256x256.yuv与lena_256x256.cmp文件大小,计算压缩率。
a) 首先需要将Lena彩色图转为YUV420格式,可以使用一些图像处理软件实现,比如Photoshop或者ffmpeg命令行工具。假设已经将其转换为YUV420格式并保存为lena_256x256.yuv文件,可以使用python的os.path模块来获取文件大小,代码如下:
```
import os
file_size = os.path.getsize('lena_256x256.yuv')
print('lena_256x256.yuv的文件大小为:', file_size, 'bytes')
```
b) 可以使用opencv库来读取lena_256x256.yuv文件,并将其转换为RGB模式的图像,然后将其分离为Y、U、V三个通道的图像。代码如下:
```
import cv2
img = cv2.imread('lena_256x256.yuv', cv2.IMREAD_COLOR)
# 对图像进行重构,将YUV420格式的数据转换成RBG模式的图像
img = cv2.cvtColor(img, cv2.COLOR_YUV2BGR_I420)
# 分离出Y、U、V三个通道的图像
img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV_I420)
y, u, v = cv2.split(img_yuv)
# 将三个图像合并成一个窗口显示
height, width = y.shape
display_img = cv2.merge((y, u, v))
display_img = cv2.resize(display_img, (width*3, height))
cv2.imshow('Lena图像及其通道', display_img)
cv2.imshow('Lena原图', img)
cv2.imshow('Lena亮度图', y)
cv2.imshow('Lena色度图Cb', u)
cv2.imshow('Lena色度图Cr', v)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
c) 可以使用numpy库来实现DCT8x8变换和量化操作,代码如下:
```
import numpy as np
# DCT8x8变换
def dct_8x8(im):
n, m = im.shape
imf = np.zeros((n, m))
for i in range(0, n, 8):
for j in range(0, m, 8):
imf[i:i+8, j:j+8] = np.round(cv2.dct(im[i:i+8, j:j+8])/512)
return imf
# 量化操作
def quantize(im, qf):
n, m = im.shape
imq = np.zeros((n, m))
for i in range(0, n, 8):
for j in range(0, m, 8):
imq[i:i+8, j:j+8] = np.round(im[i:i+8, j:j+8]/(qf*1.0))
return imq
# 读取lena_256x256.yuv文件并转为YUV420格式
img = cv2.imread('lena_256x256.yuv', cv2.IMREAD_COLOR)
img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV_I420)
y, u, v = cv2.split(img_yuv)
# 对亮度图进行DCT8x8变换和量化
QY = 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],
[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]])
dct_y = dct_8x8(y)
yq = quantize(dct_y, QY)
# 对色度图进行DCT8x8变换和量化
QC = np.array([[17, 18, 24, 47, 99, 99, 99, 99],
[18, 21, 26, 66, 99, 99, 99, 99],
[24, 26, 56, 99, 99, 99, 99, 99],
[47, 66, 99, 99, 99, 99, 99, 99],
[99, 99, 99, 99, 99, 99, 99, 99],
[99, 99, 99, 99, 99, 99, 99, 99]])
dct_u = dct_8x8(u)
dct_v = dct_8x8(v)
uq = quantize(dct_u, QC)
vq = quantize(dct_v, QC)
```
d) 可以使用Zig-Zag扫描法对c)中的结果进行扫描,并使用游程编码(RLC)方法对其进行编码,代码如下:
```
# Zig-Zag扫描法
def zigzag(seq):
return np.concatenate([
np.diagonal(seq[::-1,:], i)[::(2*(i % 2)-1)] for i in range(1-seq.shape[0], seq.shape[0])
])
# 从Zig-Zag顺序还原
def zigzag_inv(seq, shape):
r, c = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]), indexing='ij')
s = r + c
zi = np.zeros_like(s)
zi[::2] = seq[:seq.shape[0]*seq.shape[1]//2]
zi[1::2] = seq[seq.shape[0]*seq.shape[1]//2:]
i = np.argsort(s.ravel())
return zi.ravel()[i].reshape(shape)
# 游程编码
def rlc(seq):
out = []
count = 0
for i in seq:
if i == 0:
count += 1
else:
out.append(count)
out.append(i)
count = 0
if count > 0:
out.append(count)
out.append(0)
return out
# 进行Zig-Zag扫描和游程编码
yq_zz = zigzag(yq)
uq_zz = zigzag(uq)
vq_zz = zigzag(vq)
y_code = rlc(yq_zz)
u_code = rlc(uq_zz)
v_code = rlc(vq_zz)
```
e) 可以使用哈夫曼编码方式对d)中的结果进行熵编码,并存为lena_256x256.cmp文件,可以使用huffman库实现,代码如下:
```
import huffman
# 构建哈夫曼编码树
def build_huffman_tree(code):
freqs = {}
for i in code:
if i in freqs:
freqs[i] += 1
else:
freqs[i] = 1
tree = huffman.build(freqs)
return tree
# 对码流进行哈夫曼编码
def huffman_encode(code, tree):
if code is None or tree is None:
return None
otp = ''
for i in code:
otp += tree[i]
return otp
# 保存哈夫曼编码后的数据到文件
def write_binary_file(data, filename):
with open(filename, 'wb') as f:
f.write(bytearray(data))
def compress():
# 对y,u,v三个通道分别构造哈夫曼编码树和编码码流
y_tree = build_huffman_tree(y_code)
u_tree = build_huffman_tree(u_code)
v_tree = build_huffman_tree(v_code)
y_zz_huffman = huffman_encode(y_code, y_tree)
u_zz_huffman = huffman_encode(u_code, u_tree)
v_zz_huffman = huffman_encode(v_code, v_tree)
# 将哈夫曼编码的数据保存到文件中
write_binary_file(y_zz_huffman.encode(), 'lena_256x256_y.cmp')
write_binary_file(u_zz_huffman.encode(), 'lena_256x256_u.cmp')
write_binary_file(v_zz_huffman.encode(), 'lena_256x256_v.cmp')
```
f) 可以计算压缩率并输出结果,代码如下:
```
# 计算压缩率
img_size = y.shape[0] * y.shape[1] * 3
cmp_size = os.path.getsize('lena_256x256_y.cmp') + os.path.getsize('lena_256x256_u.cmp') + os.path.getsize('lena_256x256_v.cmp')
compress_rate = 1 - cmp_size / img_size
print('压缩率为:', compress_rate)
```
完整代码如下:
阅读全文