将 16 位灰度 PNG 转换为 HEVC/x265

2023-12-26

我想将 12 位图像信号转换为 HEVC 以进行有效压缩。因为我需要能够重建原始 12 位信号,所以压缩需要是无损可逆的。目前我的数据为 16 位 PNG 文件。

我的第一次尝试是使用 ffmpeg:

ffmpeg -y -framerate 1 -i input.png -c:v libx265 -x265-params "lossless=1" output.mp4

不幸的是,输出是不可逆的。从mp4中提取图像时,像素值略有偏差。

ffmpeg -i output.mp4 -vframes 1 reconstructed.png

以下答案建议首先将输入转换为 YUV444 以避免 ffmpeg 出现意外行为:无损 x264 压缩 https://stackoverflow.com/questions/6701805/h264-lossless-coding/12303936#18506577

到目前为止,我未能成功将 16 位文件转换为 YUV、将其转换为 x256 并在解码时收到正确的重建。

有没有直接的方法将 16 位图像转换为 HEVC?


我找到了一个具有较小舍入误差的解决方案:

编码:

  • 基于以下帖子:如何将 png 渲染为 h.265 12 位视频? https://video.stackexchange.com/questions/25248/how-to-render-pngs-as-h-265-12-bit-video
    使用时可以使用以下编解码器参数:-x265-params lossless=1 -pix_fmt yuv444p12le用于有损 12 bpc 编码。

  • 通过反复试验,我意识到12位数据必须在高 12 位每个 16 位元素。 您需要将输入像素放大 16 倍才能将数据放入高位。
    (缩放 16 相当于将 uint16 元素左移 4)。
    要放大像素,您可以使用colorlevels视频过滤器:
    -vf colorlevels=rimax=0.0625:gimax=0.0625:bimax=0.0625

以下命令对单个帧进行编码:

 ffmpeg -i input.png -vf colorlevels=rimax=0.0625:gimax=0.0625:bimax=0.0625 -c:v libx265 -x265-params lossless=1 -pix_fmt yuv444p12le output.mkv

解码:

  • 为了进行解码,您需要将像素除以 16,以便将数据放入较低的 12 位中。
    (除以 16 相当于将 uint16 元素右移 4)。
    我找不到使用的解决方案colorlevels,所以我用了curves filter:
    -vf "curves=r='0/0 1.0/0.0625':g='0/0 1.0/0.0625':b='0/0 1.0/0.0625'"
  • 16 位 PNG 的合适像素格式是rgb48be.

以下命令解码单个帧(并除以 16):

ffmpeg -i output.mkv -vf "curves=r='0/0 1.0/0.0625':g='0/0 1.0/0.0625':b='0/0 1.0/0.0625'" -pix_fmt rgb48be reconstructed.png

差异:
之间的最大绝对差input.png and reconstructed.png is 4 levels.
造成差异的原因可能是 RGB 与 YUV 相互转换造成的舍入误差。


我使用以下 MATLAB 代码进行测试:

I = imread('peppers.png');

% Build 10 PNG images (used as input).
for i = 1:10
    J = insertText(I, [size(I,2)/2-18, size(I,1)/2-36], num2str(i), 'FontSize', 72);
    J = imnoise(im2double(J), 'gaussian', 0, 0.01); % Add some noise
    J = uint16(round(J*4095)); % Convert to 12 bits range (range [0, 4095])
    imwrite(J, sprintf('input%02d.png', i), 'fmt', 'png', 'BitDepth', 16, 'Mode', 'lossless'); % Write to PNG file
end

 %Encode video file using x265 codec, and 12 bits YUV444 format. 
[status, cmdout] = system('ffmpeg -y -i input%02d.png -vf colorlevels=rimax=0.0625:gimax=0.0625:bimax=0.0625 -c:v libx265 -x265-params lossless=1 -pix_fmt yuv444p12le output.mkv');
if (status ~= 0), disp(cmdout);end

% Decode output.mkv into 10 PNG image files
[status, cmdout] = system('ffmpeg -y -i output.mkv -vf "curves=r=''0/0 1.0/0.0625'':g=''0/0 1.0/0.0625'':b=''0/0 1.0/0.0625''" -pix_fmt rgb48be reconstructed%02d.png');
if (status ~= 0), disp(cmdout);end

% Compare input and output:
for i = 1:10
    I = imread(sprintf('input%02d.png', i));
    J = imread(sprintf('reconstructed%02d.png', i));
    max_abs_diff = max(max(max(imabsdiff(I, J))));
    disp(['max_abs_diff = ', num2str(max_abs_diff)]);
end

Update:

与...一起工作灰度 format:
使用灰度时,不需要将像素格式转换为 YUV。
从灰度转换为 YUV444 会将输入数据的大小乘以 3,因此最好避免转换。

以下命令对单个灰度帧进行编码:

 ffmpeg -i input.png -vf "curves=all='0/0 0.0625/1.0'" -c:v libx265 -x265-params lossless=1 -pix_fmt gray12le -bsf:v hevc_metadata=video_full_range_flag=1 output.mkv

以下命令解码单个灰度帧(并除以 16):

ffmpeg -i output.mkv -vf "curves=all='0/0 1.0/0.0625'" -pix_fmt gray16be reconstructed.png

最大绝对差为 2。


使用注意事项-bsf:v hevc_metadata=video_full_range_flag=1:

在H.265中,Y颜色通道的默认范围是“有限范围”。
对于 8 位,“有限范围”适用 [16, 235]。
对于 12 位,“有限范围”适用 [256, 3760]。
当8位使用“全范围”[0, 255]或12位使用[0, 4095]时,您需要在流的元数据中指定它。
使用 FFmpeg 设置元数据的方法是使用比特流过滤器 https://www.ffmpeg.org/ffmpeg-bitstream-filters.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 16 位灰度 PNG 转换为 HEVC/x265 的相关文章

  • Node.js:从 jpeg 图像到视频文件的实时转换

    我正在使用node js 并通过socket io 库接收实际上是jpeg 图像的数据块 这些图像是从远程网络摄像头捕获的实时视频帧 我被迫将视频作为 jpeg 帧进行流式传输 我正在寻找一种方法来动态转换视频文件 mpeg 4 或 mjp
  • 如何在 laravel 4 中使用 php-FFMpeg?

    我是 Laravel 4 的新手 我已经安装了php ffmpeg在我本地的 Laravel 设置中 但我需要有关如何在 Laravel 4 中使用此 ffmpeg 的帮助 假设你已经拥有ffmpeg安装在本地主机服务器上 然后在 Lara
  • 将网络摄像头从浏览器流式传输到 RTMP 服务器

    我正在尝试将一些内容从浏览器的网络摄像头实现流式传输到随机 RTMP 服务器 我让它工作到每 2 秒将 WEBM 我相信是 VP8 编码的电影片段发送到我的服务器的部分 但棘手的部分是从该部分将其发送到 RTMP 服务器 对 FFMPEG
  • RTSP 帧抓取会产生拖尾、像素化和损坏的图像

    我正在尝试使用以下命令从 RTSP 流中每秒捕获一帧 ffmpeg i rtsp XXX q v 1 vf fps fps 1 strftime 1 ZZZZ H M S jpg But some of the frames are sme
  • 使用 ffmpeg 处理流的解码数据时出错

    我正在使用以下命令 ffmpeg i video1a flv i video1b flv i video1c flv i video2a flv i video3a flv i video4a flv i video4b flv i vid
  • 在流 #1 中找不到编解码器 pcm_alaw 的标签,使用 ffmpeg 连接 2 个文件时容器当前不支持编解码器 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试连接两个文件 第一个文件包含音频和视频 第二个文件仅包含视频 我用以下ffmpeg命令 ffmpeg command ffmpe
  • 使用 ffmpeg 进行视频标准化

    无论如何 有没有使用 ffmpeg 脚本将视频亮度标准化为其完整的动态范围 我一直在尝试用 lutyuv 这样做 ffmpeg i input mp4 vf lutyuv y val minval 255 maxval minval 输出
  • 使用 Python 从原始帧创建 MPEG4 视频文件

    我有一个原始视频帧源 我可以在 Python 中访问它 我想用它创建一个 MPEG4 视频 并带有 MP3 背景音乐 Python 中有哪些类型的工具和库可用于此类任务 最好我想要一个 API 我可以为其提供输出文件名 然后将各个帧作为 2
  • ffprobe/ffmpg 静音检测命令

    我正在研究流静音检测 它正在 ffmpeg 中执行以下命令 ffmpeg i http mystream com stream af silencedetect n 50dB d 0 5 f null 2 gt log txt 我想获得日志
  • 为 iOS6.0 ARMv7 处理器构建 FFMPEG 库

    WARNING 我刚刚被另一位用户告知 在 iOS 上使用 FFMPEG 存在一些法律问题 请在此处留下链接http multinc com 2009 08 24 compatibility Between the iphone app s
  • 在 FFmpeg 中使用 -filter_complex amerge 时混合流

    我目前遇到 ffmpeg 及其过滤器之一的问题 我正在尝试将视频的 2 个音频流合并为一个 为此我尝试了这个命令 ffmpeg i home maniaplanet Videos ManiaPlanet 2014 08 21 20 09 1
  • 防止 ffmpeg 在降低视频分辨率的同时改变颜色强度

    我有一个用例 我需要缩小规模716x1280mp4 视频到358x640 原件的一半 我使用的命令是 ffmpeg i input mp4 vf scale 640 640 force original aspect ratio decre
  • C# 从视频文件的一部分中提取帧

    使用 AForge ffmpeg 包装器 您可以使用 VideoFileReader 类从视频中提取帧并将其保存为位图 请参阅以下示例 提取 avi 文件的帧 https stackoverflow com questions 178256
  • 将 H264 视频转换为原始 YUV 格式

    是否可以使用 ffmpeg 从 H264 编码视频创建原始 YUV 视频 我想用 matlab 打开视频并逐帧访问 Luma Cb 和 Cr 分量 是的 您可以 您只需指定像素格式即可 要获取格式的完整列表 ffmpeg pix fmts
  • 为什么没有 2 字节浮点并且已经存在实现?

    假设我真的内存不足并且想要更小的范围 类似于short vs int 着色器语言已经支持half对于半精度的浮点类型 不仅仅是来回转换使值在 1 和 1 之间 即返回一个像这样的浮点数 shortComingIn maxRangeOfSho
  • 使用 mkfifo 和传输流,这可能吗?

    我想执行一个 bash 脚本来执行以下操作 应用程序 ffmpeg 生成实时传输流 ts 文件 我需要处理这个实时流 执行解复用等 现在我知道这必须通过 FIFO 来完成 但这是我的任务 我需要重定向 ffmpeg 的输出以写入 fifo
  • 如何在Android项目中使用libffmpeg.so?

    我正在尝试在 Android 中创建一个屏幕录制应用程序 为此 我使用 FFmpeg 我已经创建了 libffmpeg so 文件 现在我想在 Android 项目中使用相同的方法来调用它的本机函数 我怎样才能做到这一点 本教程提供了有关此
  • H264 字节流到图像文件

    第一次来这里所以要温柔 我已经在给定的 H 264 字节流上工作了几个星期 一般注意事项 字节流不是来自文件 它是从外部源实时提供给我的 字节流使用 Android 的媒体编解码器进行编码 当将流写入扩展名为 H264的文件时 VLC能够正
  • 使用 ffmpeg 或 OpenCV 处理原始图像

    看完之后维基百科页面 http en wikipedia org wiki Raw image format原始图像格式 是任何图像的数字负片 为了查看或打印 相机图像传感器的输出具有 进行处理 即转换为照片渲染 场景 然后以标准光栅图形格
  • FFmpeg 不适用于 android 10,直接进入 onFailure(String message) 并显示空消息

    我在我的一个项目中使用 FFmpeg 进行视频压缩 在 Android 10 Google Pixel 3a 上 对于发送执行的任何命令 它会直接进入 onFailure String message 并显示空消息 所以我在我的应用程序 g

随机推荐

  • Java矩阵运行时错误

    练习信 给定一个 m x n 元素的矩阵 m 行 n 列 按螺旋顺序返回矩阵的所有元素 例如 给定以下矩阵 1 2 3 4 5 6 7 8 9 You should return 1 2 3 6 9 8 7 4 5 给定代码 public
  • 按住按钮时运行代码

    我是 Unity 和构建游戏的新手 我使用 2 个按钮 IncreaseButton DecreaseButton 我遇到的问题是按钮回调函数仅在用户单击按钮时调用一次 但在按住按钮时不会调用 如何让按钮在按住时重复调用 Code publ
  • 如何以编程方式为 Django 中的给定模型生成 CREATE TABLE SQL 语句?

    我需要以编程方式生成给定的 CREATE TABLE 语句不受管理的我的 Django 应用程序中的模型 managed False 由于我正在处理旧数据库 因此我不想创建迁移并使用sqlmigrate The manage py sql命
  • Discord.py 机器人可以不区分大小写吗?

    我现在正在制作一个不和谐的机器人 如果我使用大写字母 不使用大写字母 它不会响应 有没有办法让机器人检测消息 即使它们是大写 小写 还有一种方法可以让机器人对空格做同样的事情 如果我不小心忘记放空格 或者不小心将两个单词合并在一起 或者我是
  • 如何在 QTextEdit 中为 QTextFrame 或 QTextBlock 提供背景图像?

    我正在开发一个 IM 工具 作为它的一部分 我必须开发一个BubbleChatWidget所有消息项都有一个bubble like背景图像 我以为我可以实现我的目标QTextEidt 但我不知道如何给出 QTextFrame 或QTextB
  • 在 Git hook 中获取提交消息

    我想在 Git 提交之前检查提交消息 我使用预提交挂钩来执行此操作 但我找不到在中获取提交消息的方法 git 预提交脚本 我怎样才能得到它 In the pre commit hook the commit message usually
  • Firebase 控制台:如何指定通知的 click_action

    我实现了 Firebase 并测试了 Firebase 通知 当应用程序位于前台时 我没有问题 我实现了一项扩展的服务Firebase消息服务并处理消息和数据收到消息时 当应用程序在后台运行时 我遇到问题 我想发送一条通知 打开特定活动并执
  • 如何在 PHP 中获取当前日期和时间?

    哪个 PHP 函数可以返回当前日期 时间 时间将以您的服务器时间为准 一个简单的解决方法是使用以下命令手动设置时区date default timezone set http php net manual en function date
  • 将 Arraylist 作为参数传递给函数[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我有一个整
  • 错误:只有字符串可以转换为符号

    我不太精通 R 但最近安装了 ggpubr 包 因为想要制作配对箱线图 我尝试过使用 ggpaired question1 cond1 question1 q1 cond2 question1 q2 fill condition palet
  • Mysql DB 表行消失

    最近发生了一个非常奇怪的 对我来说 问题 在接受用户提交数据的应用程序中 以下情况随机发生 存储用户提交数据的数据库表中的行是disappearing 请注意除 INSERT 语句外 没有对数据库表发出 DELETE DROP TRUNCA
  • 逐列打印二维数组

    这个非常基本的代码逐行打印我的二维数组 public class scratchwork public static void main String args throws InterruptedException int test ne
  • VS2012 RC 中不识别外键

    经过昨天的大量帮助 我在 asp net4 beta 中遇到了一个已知错误 我升级到 VS2012 RC Express 4 5 现在 VS 在我的模型中报告了两个错误 这些错误以前是正常的 找不到类型或命名空间名称 ForeignKeyA
  • 带有多个可选搜索词的参数化查询

    我有一个包含大量数据的 Web 应用程序 以及一个包含多个字段 例如名称 状态 日期等 的搜索 过滤功能 我一直在对常规 非搜索 查询使用这样的参数化查询 id POST itemID db mysqli connect host user
  • 应用程序传输安全性已阻止明文 HTTP (http://) 资源加载,因为它不安全。

    据说临时异常可以通过应用程序的 Info plist 文件进行配置 根据其他答案 我将此条目添加到 info plist 中 但它没有帮助 更糟糕的是 在我更改 xml 文件后 当我尝试在 iPhone 上运行该应用程序而不是在模拟器上运行
  • 使用 Kendo Grid,如何更改工具栏中“创建”按钮上的措辞?

    我正在使用 Kendo 网格 我添加了 创建 来执行记录的内联添加 如何更改添加按钮上的措辞 目前它显示为 添加新记录 我想将其简化为仅读取 添加 并且我还想保留相同的图标 我的代码如下所示 reports kendoGrid dataSo
  • 如何根据另一个查找表/数据框自动插入一个数据框的值?

    我有一个数据框和一张查找表 我想要的是比较df dat value with df lookup threshold 如果value落入threshold范围 然后创建一个新列transfer in df dat使其值为 从线性插值tran
  • xcode 7 生成带有附加 CoreDataProperties 类别的核心数据实体

    我在 xcode 7 中有一个奇怪的新功能 当我生成新的 NSManagedObject 子类时 xcode 创建两个类 实体及其 CoreDataProperties 类别 其中包含完整的实现 下图是我的意思的例子 我找不到任何关于此的记
  • 如何在 Ruby 中使用 DateTime strptime 解析非英语日期?

    我正在尝试解析从 CMS 导出的日期 不幸的是 设置了瑞典语言环境 月份名称缩写为三个字符 这在 5 月和 10 月时有所不同 maj 与 May 以及 okt 与 Oct 我希望使用 DateTime strptime 并设置正确的区域设
  • 将 16 位灰度 PNG 转换为 HEVC/x265

    我想将 12 位图像信号转换为 HEVC 以进行有效压缩 因为我需要能够重建原始 12 位信号 所以压缩需要是无损可逆的 目前我的数据为 16 位 PNG 文件 我的第一次尝试是使用 ffmpeg ffmpeg y framerate 1