1.读入照片
控制输出的标志定义
1
2
3
4
5
6
7
8
9
10
11
|
clc ; close all ; clear
YES = 1; NO = 0;
%YES表示输出该文件,请用户配置
yuv444_out_txt = 1;
yuv444_out_yuv = 0;
yuv422_out_txt = 0;
yuv422_out_yuv = 0;
yuv420_out_txt = 0;
yuv420_out_yuv = 1;
|
1
2
3
4
5
6
7
|
filename = 'Koala.jpg' ;
filestr = filename(1: findstr (filename, '.jpg' )-1);
filepath = [ '.\' filestr ' out\']
mkdir (filepath);
filestr = [filepath filestr];
RGBimg = imread (filename);
figure ;imshow(RGBimg);
|
1)读入的照片由filename 配置,这里照片必须放在该目录下。如:filename = 'Koala.jpg'
2)filename找到字符串的起始位置。findstr('Koala.jpg','.jpg') = 6,所以就可以取到去掉后缀名的文件名
3)得到一个 .\文件名out\的目录
4)创建该目录
5)filestr = 目录+文件名,用于后面的数据输出,方便输出到 .\文件名out\目录下。这里 filestr = '.\Koalaout\Koala'
2. 调用matlab函数将rgb转换成yuv
1
2
|
YUVimg = rgb2ycbcr(RGBimg); %%% rgb -> yuv
figure ;imshow((YUVimg));
|
3.分别取出YUV
Y,U,V数据保留矩阵存储方式,方便后面的4:2:2,4:2:0采样,更加直观
1
2
3
4
5
6
7
8
9
10
11
12
|
[imgHeight imgWidth imgDim] = size (YUVimg); %%
len = imgHeight*imgWidth*imgDim;
yuvimout = zeros (1,len);
Y = YUVimg(:,:,1); % Y 矩阵
U = YUVimg(:,:,2); % U 矩阵
V = YUVimg(:,:,3); % V 矩阵
Yvec = reshape (YUVimg(:,:,1)',1,[]); % 矩阵整理成行向量
Uvec = reshape (YUVimg(:,:,2)',1,[]);
Vvec = reshape (YUVimg(:,:,3)',1,[]);
yuvimout(1:3:len) = Yvec;
yuvimout(2:3:len) = Uvec;
yuvimout(3:3:len) = Vvec;
|
注意:reshape矩阵时,需要对结果做转置,保证是按行来将矩阵整理成行向量的
4.输出YUV444的数据到文件
1
2
3
4
5
6
7
8
9
10
11
12
|
%%
% 输出图像的yuv数据到 .txt
%
if yuv444_out_txt == YES
filename = [filestr '_444.txt' ];
fid= fopen (filename, 'w' );
fprintf (fid, '%02x\n' ,yuvimout);
fclose (fid);
disp ( 'yuv444_out_txt YES' );
else
disp ( 'yuv444_out_txt NO' );
end
|
在本例中:filename = [filestr '_444.txt'] = '.\Koalaout\Koala_444.txt'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
%%
% 输出图像的yuv数据到 .yuv
% 四个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
%
% 存放的码流:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
%
% 映射的像素: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
if yuv444_out_yuv == YES
filename = [filestr '_444.yuv' ];
fid= fopen (filename, 'wb' );
fwrite (fid,yuvimout, 'uint8' );
fclose (fid);
disp ( 'yuv444_out_yuv YES' );
else
disp ( 'yuv444_out_yuv NO' );
end
|
5.将 YUV4:4:4 转成 YUYV 4:2:2 packed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
%%
% YUV4:4:4 -->> YUYV 4:2:2
% 四个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
%
% 存放的码流:[Y0 U0] [Y1 V1] [Y2 U2] [Y3 V3]
%
% 映射的像素: [Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3]
%%%
len = imgHeight*imgWidth+imgHeight*imgWidth/2+imgHeight*imgWidth/2;
yuv422out = zeros (1,len);
yuv422sampY = Y;
yuv422sampU = U(:,1:2: size (U,2));
yuv422sampV = V(:,2:2: size (V,2));
yuv422out(1:2:len) = reshape (yuv422sampY',1,[]); %%% 注意要转置
yuv422out(2:4:len) = reshape (yuv422sampU',1,[]);
yuv422out(4:4:len) = reshape (yuv422sampV',1,[]);
|
说明:
1)4:2:2模式是保留所有的Y,U,V是每间隔1列抽取抽样一个点,如代码中所示。
2)YUYV 4:2:2 packed 即像素值是 YU/YV 交替存储的模式。存放的码流:[Y0 U0] [Y1 V1] [Y2 U2] [Y3 V3]
输出数据到文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
%%
% 输出图像的yuv422数据到 .txt
%
if yuv422_out_txt == YES
filename = [filestr '_422.txt' ];
fid= fopen (filename, 'w' );
fprintf (fid, '%02x\n' ,yuv422out);
fclose (fid);
disp ( 'yuv422_out_txt YES' );
else
disp ( 'yuv422_out_txt NO' );
end
% output yuyv422 to .yuv file
if yuv422_out_yuv == YES
filename = [filestr '_422yuyv.yuv' ];
fid= fopen (filename, 'wb' );
fwrite (fid,yuv422out, 'uint8' );
fclose (fid);
disp ( 'yuv422_out_yuv YES' );
else
disp ( 'yuv422_out_yuv NO' );
end
|
6. 将 YUV4:4:4 转成 YV12 4:2:0 planar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
%%
% YUV4:4:4 -->> YUYV 4:2:0
% output yuyv422 to .yuv file
% 第一行四个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
% 第二行四个像素为:[Y4 U4 V4] [Y5 U5 V5] [Y6 U6 V6] [Y7 U7 V7]
% 4:2:0 采样
% 第一行采样像素为:[Y0 U0 ] [Y1 ] [Y2 U2 ] [Y3 ]
% 第二行采样像素为:[Y4 V4] [Y5 ] [Y6 V6] [Y7 ]
% 420yv12 planar 的存储码流: [Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7] [V4 V6] [U0 U2]
% 映射的像素: [Y0 U0 V4] [Y1 U0 V4] [Y2 U2 V6] [Y3 U2 V6]
% [Y4 U0 V4] [Y5 U0 V4] [Y6 U2 V6] [Y7 U2 V6]
%%%
len = imgHeight*imgWidth+imgHeight*imgWidth/4+imgHeight*imgWidth/4;
yuv420out = [];
yuv420sampY = Y;
yuv420sampU = U(1:2: size (U,1),1:2: size (U,2));
yuv420sampV = V(2:2: size (V,1),1:2: size (V,2));
%%%yuv420out = [y v u] % yuv420 yv12 format
yuv420out = [yuv420out reshape (yuv420sampY',1,[])]; %Y 注意要转置
yuv420out = [yuv420out reshape (yuv420sampV',1,[])]; %V
yuv420out = [yuv420out reshape (yuv420sampU',1,[])]; %U
|
说明:
1)yuv420sampU = U(1:2:size(U,1),1:2:size(U,2)); 从图片的第一行开始 每间隔1行 和 每间隔1列 采样一个U
2)yuv420sampV = V(2:2:size(V,1),1:2:size(V,2)); 从图片的第二行开始 每间隔1行 和 每间隔1列 采样一个V
数据数据到文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
%%
% 输出图像的yuv422数据到 .txt
%
if yuv420_out_txt == YES
filename = [filestr '_420.txt' ];
fid= fopen (filename, 'w' );
fprintf (fid, '%02x\n' ,yuv420out);
fclose (fid);
disp ( 'yuv420_out_txt YES' );
else
disp ( 'yuv420_out_txt NO' );
end
% output yuyv420 to .yuv file
if yuv420_out_yuv == YES
filename = [filestr '_420yv12.yuv' ];
fid= fopen (filename, 'wb' );
fwrite (fid,yuv420out, 'uint8' );
fclose (fid);
disp ( 'yuv420_out_yuv YES' );
else
disp ( 'yuv420_out_yuv NO' );
end
|
观察命令输出,并等待关闭
1
2
3
4
|
disp ( '---program run susseed---' );
disp ( '---press any key to close all figure---' );
system ( 'pause' );
close all ;
|
打开输出的yuv文件查看图片
参考
1
|
http: //www.cnblogs.com/xkfz007/archive/2012/07/31/2616806.html
|
1
|
http: //www.xuebuyuan.com/1541892.html
|
1
|
http: //www.fourcc.org/yuv.php
|
代码链接:
1
|
http: //pan.baidu.com/s/1pLMRcmB
|