简介YUV_Viewer是一款面向图像处理、视频编码开发者与初学者的YUV格式数据查看工具可打开并显示采集到的YUV422与YUV420图像数据帮助用户直观理解亮度与色度采样比例差异适用于调试视频处理算法、检查图像质量或开展编码实验。资源包为rar格式共16个文件约553KB包含3个h头文件、2个cpp源文件、2个yuv示例数据、2个txt说明文档以及rc、ico、vcproj、sln、exe、rc2、suo等工程与可执行文件覆盖从源码到运行程序的完整结构。其中yuv示例文件可直接用于验证显示效果工程文件便于二次开发与学习YUV数据处理原理。目前已有381人学习下载适合需要快速查看YUV数据、对比色彩空间转换效果或研究YUV文件读取流程的读者参考使用。1. 拿到 YUV_Viewer 之后为什么我劝你先别急着双击如果你手头有一堆.yuv裸流文件用普通看图软件打开要么黑屏、要么花屏、要么直接报错那 YUV_Viewer 就是冲着这个场景来的。它解决的核心问题很具体把没有文件头、没有色彩空间标记、没有分辨率和帧率信息的原始 YUV 数据按你指定的参数正确渲染成可视图像。做视频编解码、图像算法、摄像头调试、ISP 调优的从业者几乎绕不开查看 YUV 文件这一步。但我要先泼一盆冷水这类工具不是双击就能用的参数填错一个出来的画面就是绿的、紫的、斜的、或者干脆只有半张脸。这篇笔记按「它是什么、怎么配、怎么排错、怎么进阶」的顺序拆一遍新手能照着跑通熟手能直接看参数边界和踩坑记录。2. YUV_Viewer 的渲染逻辑与参数选型先搞懂它怎么读你的文件2.1 裸流没有元数据所有信息都得你喂给它YUV 文件本质上就是像素数据的顺序堆叠它不像 PNG 或 JPEG 那样在文件头里写好了宽、高、色彩格式。YUV_Viewer 打开文件时第一步是问你或读配置三件事分辨率、像素格式、帧数或帧偏移。这三者缺一不可而且必须和文件实际内容严格一致。常见做法是先用文件大小反推。比如一个文件大小是1920 × 1080 × 1.5 × N字节那大概率是 1920×1080 的 YUV420PN 就是帧数。这个 1.5 是 YUV420 的每像素平均字节数Y 分量占 1 字节U 和 V 各占 0.25 字节因为 4 个 Y 共享一组 UV。如果你按 YUV422 去读每像素平均 2 字节算出来的帧数就对不上画面会错位。我一般会先跑一条命令确认文件尺寸和整除关系# 查看文件字节数 ls -l sample.yuv # 假设输出 3110400 字节1920*1080*1.5 3110400 # 说明正好是 1 帧 YUV420P没有多余数据 python3 -c print(1920*1080*1.5)逻辑说明ls -l拿到精确字节数然后用分辨率乘以每像素字节数去验证。如果能整除说明格式判断大概率正确如果除不尽要么分辨率不对要么像素格式不对要么文件里混了别的数据。参数上1920和1080是宽高1.5是 YUV420P 的系数YUV422P 是 2YUV444P 是 3NV12 也是 1.5 但 UV 交织排列渲染路径不同。2.2 像素格式选错颜色就全乱了YUV_Viewer 支持的格式通常包括 YUV420PI420、YUV422P、YUV444P、NV12、NV21 等。选错格式的典型表现是画面能出来但颜色偏绿或偏紫或者图像被横向拉伸成两倍宽。原因在于色度分量的采样方式不同。YUV420P 的 U、V 平面是宽高各减半的如果你按 YUV444P 去读工具会把原本紧凑排列的 U 平面当成完整分辨率来解析结果就是色度信息错位颜色映射全乱。NV12 和 YUV420P 的区别在于 UV 是交织存储的NV12 是UVUVUV...I420 是UUU...VVV...。选错的话色度平面会呈现周期性条纹。选型建议如果你是从 FFmpeg 命令行导出的默认-pix_fmt yuv420p就是 I420如果是从 Android Camera2 或某些硬件编码器出来的NV21 和 NV12 更常见。拿不准的时候先用小分辨率文件试比如 176×144 的 QCIF一帧才 38016 字节试错成本低。2.3 帧偏移和步长多帧文件里定位你关心的那一帧很多 YUV 文件是连续多帧拼接的YUV_Viewer 一般提供帧索引或偏移量输入。这里有个容易翻车的点帧偏移的单位是帧还是字节。有的工具让你填字节偏移有的让你填帧序号。填错的话你看到的可能是上一帧的下半部分拼上下一帧的上半部分画面出现水平撕裂。我一般会先算一帧的字节数然后按帧序号乘以这个值去定位# 计算 YUV420P 单帧字节数并定位第 n 帧 width, height 1920, 1080 frame_size width * height * 3 // 2 # YUV420P frame_index 10 offset_bytes frame_index * frame_size print(f第 {frame_index} 帧起始字节偏移: {offset_bytes})逻辑说明width * height * 3 // 2是 YUV420P 单帧大小frame_index从 0 开始。参数上如果你要看的帧在文件中间直接填这个偏移量如果工具只接受帧序号就填frame_index。注意有些工具帧序号从 1 开始先拿第 0 帧和第 1 帧对比确认。3. 从零跑通一次查看分辨率、格式、帧定位的实操步骤3.1 准备一个已知参数的测试文件不要拿来源不明的 YUV 文件开始先自己生成一个参数完全可控的。用 FFmpeg 从一张 PNG 转一帧 YUV420P# 生成一帧 1920x1080 的 YUV420P 裸流 ffmpeg -i input.png -pix_fmt yuv420p -f rawvideo -s 1920x1080 -frames:v 1 test_1920x1080_yuv420p.yuv # 确认文件大小 ls -l test_1920x1080_yuv420p.yuv # 预期 3110400 字节逻辑说明-pix_fmt yuv420p指定输出像素格式-f rawvideo表示不封装容器、直接输出裸流-frames:v 1只取一帧。参数上-s指定分辨率必须和输入源一致或显式缩放。生成后文件大小应该正好是1920×1080×1.5 3110400字节如果对不上说明 FFmpeg 做了额外处理检查输入图像尺寸和-s是否匹配。3.2 在 YUV_Viewer 里填参数并渲染打开 YUV_Viewer按以下顺序操作选择文件指向刚才生成的test_1920x1080_yuv420p.yuv设置分辨率宽 1920高 1080选择像素格式YUV420P或 I420帧偏移0点击渲染或打开如果一切正常你应该看到和原始 PNG 几乎一致的画面。颜色可能有轻微偏差因为 RGB 转 YUV 是有损的但整体结构和色调应该正确。常见做法是先用小图验证。比如生成一个 64×64 的 YUV420P文件大小是64×64×1.5 6144字节渲染出来应该是一个清晰的 64×64 图像。小图的好处是即使格式选错你也能一眼看出是颜色问题还是排列问题。3.3 多帧文件的帧浏览与导出对于多帧 YUVYUV_Viewer 通常支持上一帧、下一帧或跳转到指定帧。操作逻辑是先确认单帧字节数然后用帧序号乘以单帧字节数得到偏移。如果你要批量导出某几帧为 PNG可以用 FFmpeg 配合# 从 YUV420P 裸流中提取第 10 到第 20 帧输出为 PNG ffmpeg -f rawvideo -pix_fmt yuv420p -s 1920x1080 -i multi_frame.yuv \ -vf selectbetween(n,10,20) -vsync 0 -frames:v 11 frame_%03d.png逻辑说明-f rawvideo告诉 FFmpeg 输入是裸流-pix_fmt yuv420p和-s必须和文件实际参数一致。select滤镜按帧序号筛选n从 0 开始。-vsync 0防止帧率同步导致丢帧。参数上between(n,10,20)表示第 10 到第 20 帧共 11 帧-frames:v 11限制输出数量。如果输出帧数不对检查select表达式和-vsync设置。提示FFmpeg 读裸流时如果分辨率或像素格式填错它不会报错而是直接按错误参数解析输出花屏图像。所以先用单帧文件验证参数再处理多帧。4. 避坑与排查YUV_Viewer 使用中常见的五个翻车现场4.1 画面全绿或全紫现象渲染出来的图像整体偏绿或偏紫但轮廓还能看出来。原因UV 平面顺序搞反了。YUV420P 是 Y、U、V 顺序NV21 是 Y、V、U 顺序。如果你把 NV21 当 NV12 读或者把 I420 的 U 和 V 对调颜色就会反向映射绿色和紫色是最典型的偏移结果。解决确认文件来源。Android Camera2 默认输出 NV21FFmpeg 默认 yuv420p 是 I420。在 YUV_Viewer 里切换格式选项NV12 和 NV21 都试一下哪个颜色正常就用哪个。4.2 图像被横向拉伸或压缩现象画面比例明显不对人脸变宽或变窄。原因分辨率填错了。比如实际是 1280×720你填了 1920×1080工具会按 1920 的宽度去解析每行像素导致行与行之间错位视觉上就是拉伸。解决用文件大小反推。文件字节数 ÷ 1.5 ÷ 帧数得到像素总数再结合常见分辨率640×480、1280×720、1920×1080去匹配。如果文件只有一帧直接文件字节数 ÷ 1.5就是像素数开方后按 16:9 或 4:3 去猜。4.3 只有上半部分有图像下半部分是花屏或黑屏现象画面上半部分正常下半部分乱码。原因帧偏移填错了。你定位到了某一帧的中间位置工具从那里开始按一帧的大小去读读到的就是半帧当前帧加半帧下一帧。解决确认偏移量是帧序号还是字节偏移。如果是字节偏移必须是单帧字节数的整数倍。用offset % frame_size 0检查不等于 0 就说明偏移不对。4.4 打开文件直接报错或闪退现象YUV_Viewer 加载文件时崩溃或提示无法读取。原因文件太大工具一次性读入内存导致溢出或者文件路径包含中文或特殊字符工具的文件接口没做编码处理。解决先用split命令切出前几帧再试# 切出前 10 帧每帧 3110400 字节 split -b 31104000 multi_frame.yuv first_10_frames.yuv逻辑说明-b 31104000表示每 31104000 字节切一个文件正好是 10 帧。参数上3110400是单帧字节数乘以 10 得到切分大小。切完后用 YUV_Viewer 打开小文件如果能正常渲染说明是文件大小问题后续可以分批查看。4.5 颜色正常但细节模糊或块状明显现象画面整体色调对但边缘有马赛克或模糊。原因色度采样格式选成了 YUV420P但实际文件是 YUV444P 或 YUV422P。YUV420P 的色度分辨率只有亮度的四分之一细节颜色会丢失。如果你把高色度采样文件按 420 读色度信息被欠采样边缘就会出现色块。解决检查文件来源。如果是从专业采集卡或某些编码器出来的可能是 YUV422P 甚至 YUV444P。用文件大小反推YUV422P 每像素 2 字节YUV444P 每像素 3 字节。按对应格式重新渲染细节应该会恢复。5. 进阶技巧用脚本批量验证 YUV 参数并自动匹配5.1 写一个参数自检脚本当你手头有几十个 YUV 文件、来源各异时逐个手动试参数效率太低。我一般会写一个 Python 脚本根据文件大小和常见分辨率、格式组合自动列出可能的参数匹配import os def guess_yuv_params(filepath): size os.path.getsize(filepath) candidates [] resolutions [(640,480),(1280,720),(1920,1080),(3840,2160),(176,144),(352,288)] formats {YUV420P: 1.5, YUV422P: 2.0, YUV444P: 3.0, NV12: 1.5, NV21: 1.5} for (w, h) in resolutions: for fmt, ratio in formats.items(): frame_size int(w * h * ratio) if frame_size 0: continue if size % frame_size 0: frames size // frame_size candidates.append((w, h, fmt, frames)) return candidates # 用法 for c in guess_yuv_params(sample.yuv): print(f分辨率: {c[0]}x{c[1]}, 格式: {c[2]}, 帧数: {c[3]})逻辑说明os.path.getsize拿到文件字节数然后遍历常见分辨率和像素格式计算单帧大小检查是否能整除。size % frame_size 0表示文件大小正好是整数帧这是强匹配信号。参数上resolutions列表可以根据你的实际场景增删formats字典里的系数是每像素平均字节数。输出结果按匹配度排序通常第一个就是正确答案。5.2 用 FFmpeg 做渲染结果比对YUV_Viewer 渲染出来的画面你可以用 FFmpeg 再渲染一遍做交叉验证。如果两者一致说明参数正确如果不一致说明其中一个工具的参数理解有偏差。# 用 FFmpeg 将 YUV 转为 PNG 作为参考 ffmpeg -f rawvideo -pix_fmt yuv420p -s 1920x1080 -i test.yuv -frames:v 1 ref.png # 然后用 YUV_Viewer 打开同一个文件肉眼比对逻辑说明FFmpeg 的-pix_fmt和-s是权威参数如果 YUV_Viewer 出来的画面和ref.png一致说明你的参数填对了。参数上-frames:v 1只输出第一帧方便快速比对。如果 FFmpeg 报错说数据不足说明文件大小和参数不匹配回到第 3 章重新算。5.3 我踩过的一个典型坑字节序与平面顺序有一次我拿到一个文件按 YUV420P 读出来颜色始终不对换了 NV12 和 NV21 也不行。后来发现这个文件是 YUV420P 但 U 和 V 平面是反的也就是所谓的 YV12。YV12 和 I420 的区别就是 U、V 顺序对调。YUV_Viewer 如果没有 YV12 选项可以先用 I420 打开然后用 FFmpeg 做一次 UV 交换再查看# 将 YV12 转为 I420交换 U 和 V 平面 ffmpeg -f rawvideo -pix_fmt yuv420p -s 1920x1080 -i input.yv12 \ -vf shuffleplanes0:2:1 -pix_fmt yuv420p -f rawvideo output_i420.yuv逻辑说明shuffleplanes0:2:1表示输出平面顺序为第 0 平面Y、第 2 平面V、第 1 平面U实际上就是把 U 和 V 对调。参数上0:2:1是平面索引Y 永远是 0U 和 V 根据格式不同可能是 1 和 2 或 2 和 1。转换后再用 YUV_Viewer 打开output_i420.yuv颜色应该就正常了。从那以后我每次拿到新的 YUV 文件都强制先跑一遍参数自检脚本再用 FFmpeg 转一帧 PNG 做基准最后才用 YUV_Viewer 打开。这套流程多花两分钟但能省掉半小时的瞎猜。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?