关于Ultra HDR Image的那些事

一、什么是Ultra HDR Image

2023年10月初,google正式发布了Android 14。该版本中引入了一个新的功能Ultra HDR Image,被誉为”图像技术的未来”。之前Android版本各手机厂商或许有自己的HDR图片技术,本文这里重点分析下Android14上google的实现方案。

7db5ea733aebf8f2aee6f37aa83db1d5.png

让我们先来看一组图片。上图中左边的图片为SDR(标准动态范围),右边的图片为HDR(高动态范围)。显而易见HDR图片更加的生动鲜艳,画面层次感表现的更为突出。Ultra HDR Image功能就是为用户提供了拍摄、查看HDR照片的功能。

8f7efb52277a5607f88b557b0f4dee31.png

Google Ultra HDR Image实际是使用两个8-bit位深的JPEG来还原真实拍摄场景的高动态范围。本文将此文件格式称为JPEG-R,该格式向后兼容JPEG。

二、Ultra HDR Image文件结构

Ultra HDR Image文件是基于传统JPEG文件格式,通过附加的metadata 信息及Gainmap图,最大程度上保留了拍摄场景的动态范围。

8716b920031ab7601d3e26b7da292e9c.png

图2.1 - Ultra HDR Image 文件结构

前面讲到Ultra HDR Image是由两个JPEG文件组成。其中第一个JPEG称为Primary image(主图),是一张普通的8bit SDR图片,存储着SDR图像数据。第二个JPEG称为Gainmap(增益图),Gainmap图存储着足以恢复原始高动态亮度的数据,可以简单理解为每个像素点处的亮度差。支持该格式的设备会将主图和增益图结合起来,在兼容的显示器上渲染出高动态范围的图像。

图2.1中绿色部分为Google GContainer,遵循XMP规范,并嵌入到主图文件中,其格式为RDF/XML。

f0594d7870af36b9d2209a1406ebdfa4.png

图2.2- Google GContainer

如图2.2所示,主图像在XMP中包含了Container:Directory元素,定义文件容器中后续媒体文件的顺序和属性。容器中每个文件在Container:Directory中都有一个相应的媒体项,媒体项描述文件容器中的位置及每个串联文件的基本属性。

933822a63754f73b3a7271efc24c81ff.png

图2.2 GContainer说明该图片有1个Primary图和1个Gainmap图,两个文件均为“image/jpeg”格式,Gainmap图文件长度为66171字节。

图2.1中红色部分为HDR Gain map metadata. 这部分数据说明了如何使用Gainmap图将主图像渲染到高动态范围。

5a571034a0ac4925aa13e7aa79d8cc22.png

图2.3- HDR Gain map metadata

2b8676f6e98c3a773e521f63c9c77454.png

上表中GainMapMin和GainMapMax是图像内容上像素值的增益范围,取决于图像内容。而HDRCapacityMin和HDRCapacityMax是显示时提升的增益范围,取决于显示设备和其他因素。XMP中存储的这几个值都是经过对数转换的。可能有人会问:为什么需要对数转换,这样有什么好处呢?这里就不得不提一个概念:”压缩范围”。在摄影中,现实世界场景的动态范围通常比 SDR 显示器所能呈现的动态范围更大。需要诸如范围压缩(也称为局部色调映射)之类的操作来减少图像的动态范围。减小图像中最大亮度边缘的大小,同时尽可能保留小亮度边缘(细节)的大小。如图2.4,对数曲线在像素值较低的区域斜率大,在像素值较高的区域斜率小。所以对数变换可以将图像低亮部分进行扩展,保留更多的细节;高亮部分压缩,减少高亮部分的细节。

1b52c9757daf15891df0b78883e1082f.png

图2.4- 对数曲线

图2.1中紫色部分为MPF数据,储存在主图像中App2字段,主要包含了文件容器中Primary图和Gainmap图的偏移及文件长度。

6b69bc3faad6c8c2b7cd0fa5b9e35dfe.png

图2.5- MPF

三、Ultra HDR Image编码

Android14上针对不同的场景,共提供了5个编码接口用来生成Ultra HDR Image。

4e24626152d805d970c16ea6ce25218a.png

图3.1- API-0

097f4cd84e9301670c1a9f66feabf521.png

图3.2- API-1

ca10f4b06b5b0abc3dc6652cf20aa46b.png

图3.3- API-2

dbcfa3b81442ad72814c1861c70ebd34.png

图3.4- API-3

410d90b8420d68b78fe25586ab5791f9.png

图3.5- API-4

调用方根据需要选择其中一个即可。在这里我们以API-0为例,详细剖析下编码流程。

ba42577614d58c2cad73c2acbcadb101.png

图3.6- API-0编码流程

JPEG-R编码主要有以下5个步骤:

a.相机Hal采集到HDR数据(P010)通过tonemap函数生成SDR数据(YUV420)

b. 通过HDR数据和SDR数据生成未压缩的gain map(亮度差)数据

c. gain map数据压缩成单通道JPEG文件(灰度图)

d. SDR数据压缩成Primary JPEG图

e.生成metadata信息,并将gainmap灰度图添加到Primary JPEG后面

上面5步中,c、d均为普通jpeg编码,e为文件流输出,这里就不在赘述。我们重点结合代码分析下前两步:

a.HDR->SDR:

从下图代码中可以看出tonemap操作实际是将每个像素点处的P010数据通过右移2位的操作,从10-bit映射到了8-bit范围,生成新的SDR数据(YUV420)。

08c863d26a07aac377e540d3be326505.png

图3.7- P010数据tonemap到YUV420代码

b. Gain map亮度差数据生成:

4b45423c3573ce51a1e5b64090633872.png

图3.8- gainmap 亮度差生成代码

sampleYuv420()函数是获取(x,y)坐标处归一化后的yuv数据。

e8b8a8f6d8827cf16c344ebe79e297d8.png

图3.9- sample420函数

srgbYuvToRgbFn()是通过公式将归一化得yuv数据转成rgb数据,需要注意得是这里的rgb数据是经过gamma编码的非线性数据。这里以P3色域的图片为例:

a5013ec0c07188486c09405a35e3111b.png

图3.10- srgbYuvToRgbFn函数

srgbInvOetfLUT()是通过光电转换函数将非线性的rgb数据转换成线性rgb数据。

4f3a3ccaf1ef09c39ca4384b5224e80b.png

图3.11- srgbInvOetfLUT函数

luminanceFn()是将归一化的线性rgb数据转换成对应的亮度值,在0.0到1.0的范围内。该值乘以kSdrWhiteNits表示的是(x,y)坐标处标准动态范围主图像的线性亮度,这里暂时用Ysdr(x,y)表示。

e5597d10eedaf45715eeb44b83330c9c.png

图3.12- luminanceFn函数

同理根据P010数据可以计算出(x,y)处高动态范围图像的线性亮度用Yhdr(x,y)表示。

根据(x,y)处的标准动态范围主图像线性亮度Ysdr(x,y)和高动态范围图像的线性亮度Yhdr(x,y),通过encodeGain函数生成(x,y)处的亮度差,并恢复到0~255范围。

9dff6730db5d23890fe8d2b30f7ef815.png

图3.13- encodeGain函数

所有像素点处的亮度差获取到后,编码成单通道的JPEG灰度图存储在primary JPEG文件后面。以上就是Native层Ultra HDR Image生成的全部过程。

下面通过一个简单的例子告诉你上层应用如何编码JPEG-R格式。

07e05061fed167981a4ba8a091cff003.png

图3.14- 上层应用编码实例

四、Ultra HDR Image解码

JPEG-R解码流程如下图所示:

39ff39757c1ded248951319d706052d7.png

图4.1- JPEG-R解码流程

JPEG-R格式图片解码时,首先解码primary JPEG(主图),然后判断该图片是否遵循JPEG-R格式标准包含Gainmap图。如果有,则解码Gainmap图并将gainmap存入主图Bitmap结构体中。代码如下:

0436273d1945558a49d90625cb27140b.png

图4.2- JPEG-R解码流程

图4.2中getAndroidGainmap()函数解析图片是否符合JPEG-R格式标准。如果是JPEG-R,继续解析获取XMP文件中gainmap图的metadata信息,保存在gainmapInfo中。同时保存出gainmap数据流。decodeGainmap()函数负责解码上一步获取到的gainmap数据流,并将解码后的数据保存在gainmap参数中。最后通过setGainmap()函数将gainmap数据保存到主图bitmap结构体中。Primary JPEG和Gainmap图的解码都是基本的jpeg解码流程,这里就不在赘述了。

以上就是Native层Ultra HDR Image的解码过程。下面一个例子告诉你上层应用该如何获取Gainmap数据:

380ec941092063f9f3f897202ce24ce8.png

五、Ultra HDR Image渲染

JPEG-R渲染时,每个坐标点的像素通过HDR/SDR ratio(亮度差)数据, 将标准动态范围数据还原到高动态范围。

d72134463dcee820ec2a700b650e3eba.png

这里的f可以认为是一个用于计算HDR数据的插值转换函数。相关代码如下:

2ce93ebc442f96f5fc800c470a03ac9d.png

图4.3- HDR数据还原

图4.3中trfn_apply_gain()函数使用对应坐标处的HDR/SDR ratio,计算出该坐标处的HDR数据,之后按正常流程渲染即可。

六、总结

Android14之前各厂商HDR技术、效果各不相同,因此社交平台很难适配各家的HDR图片。Ultra HDR Image的出现或许能改变这一困局,统一的HDR流程和效果对于三方应用的适配提供了便利。或许不久的将来,HDR图片效果就能出现在朋友圈、微博等社交平台。你别说,“图像技术的未来”还真有那味了。

Ultra HDR Image整个拍摄到显示的链路很长,它不是一篇文章能完整描述清楚的。本文侧重点主要在编解码模块。因为该技术较新,本人拙见,如有不当处,还望读者朋友海涵。

参考文献:

[1].https://developer.android.com/guide/topics/media/platform/hdr-image-format

[2].http://aospxref.com/android-14.0.0_r2/

超详细!Linux内核内存规整详解

Android logd日志简介及典型案例分析

OPPO在CLK大会上公布可编程内核技术,引领安卓流畅体验升级

f87ebd946efabfe9dcc54ba1de8e94e9.gif

长按关注内核工匠微信

Linux内核黑科技| 技术文章| 精选教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/146197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在test用户下创建test1表并插入数据,然后将tes1t表的查询权限授予test2用户

文章目录 1、以 test 用户登录2、创建 test1 表3、插入数据4、查看数据5、授予权限创建用户test2以 test 用户登录并授予权限:使用test2用户登录查询,测试结果 1、以 test 用户登录 首先,您需要以 test 用户登录到数据库 sqlplus test/1232…

[工业自动化-24]:西门子S7-15xxx编程 - 软件编程 - HMI编程的变量与变量映射

目录 一、HMI变量与连接 1.1 概述 1.2 HMI变量的类型:PLC变量与自主变量 二、HMI变量映射 2.1 场景映射方式 2.2 映射示例 2.3 映射步骤 2.4 如何为HMI添加映射关系 一、HMI变量与连接 1.1 概述 HMI只是显示设备,并非控制设备,因此…

腾讯云4核8G服务器配置价格表,轻量和CVM标准型S5实例

腾讯云4核8G服务器S5和轻量应用服务器优惠价格表,轻量应用服务器和CVM云服务器均有活动,云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元,5年6490.44元,轻量应用服务器4核8G12M带宽一年446元、529元15个月,腾讯云…

Docker Golang 开发环境搭建指南

Docker Golang 开发环境搭建指南 概述 在 Golang 开发中,搭建合适的开发环境是非常重要的。然而,由于 Golang 的跨平台特性,不同操作系统之间的配置差异可能会导致环境搭建过程变得复杂。为了简化这个过程并保持开发环境的一致性&#xff0…

Linux下向Github仓库推送

文章目录 Git 与 Github安装git在github下创建项目下载项目到本地Git三板斧第一板斧 git add第二板斧 git commit第三板斧 git push Git 与 Github Git是目前从开发人员到设计人员的版本控制技术。gitee是国内社交代码托管平台。这是一个你可以玩和实验的地方。在这里你可以找…

YoloV8改进策略:聚焦线性注意力重构YoloV8

文章目录 摘要论文《FLatten Transformer:使用聚焦线性注意力的ViT》1、简介2、相关工作2.1 Vision Transformer2.2 线性注意力3. 预备知识3.1. 视觉Transformer和自注意力3.2. 线性注意力4. 聚焦线性注意力4.1.聚焦能力4.2. 特征多样性4.3. 聚焦线性注意力模块5. 实验5.1. Ima…

注解方式优雅的实现 Redisson 分布式锁

1前言 日常开发中,难免遇到一些并发的场景,为了保证接口执行的一致性,通常采用加锁的方式,因为服务是分布式部署模式,本地锁Reentrantlock和Synchnorized这些就先放到一边了,Redis的setnx锁存在无法抱保证…

levelDB之基础数据结构-Slice

Slice是levelDB中用于操作字符串的数据结构,以字节为单位。 定义与实现 namespace leveldb {class LEVELDB_EXPORT Slice {public:// Create an empty slice.Slice() : data_(""), size_(0) {}// Create a slice that refers to d[0,n-1].Slice(const c…

创建具有负载平衡和集群的可扩展 Node.js 应用程序

创建具有负载平衡和集群的可扩展 Node.js 应用程序 负载平衡是提高应用程序性能、可扩展性和可用性的一项重要技术。当客户端向负载均衡器发出请求时,负载均衡器根据预定义的规则将请求分发到不同的实例。 可以使用cluster集群模块或 PM2 等工具根据负载均衡器的流…

[PHP]关联和操作MySQL数据库然后将数据库部署到ECS

在Mac电脑上使用VS Code进行PHP开发并关联操作MySQL数据库,然后将数据库部署到ECS。 1.安装PHP和MySQL 确保你的Mac上已经安装了PHP和MySQL。你可以使用Homebrew来安装它们: $ brew install php $ brew install mysql 安装mysql完成后记住这一句: …

在.net 6版本以上的web api中添加像.net 5一样的Startup.cs

Program.cs中: 第一步:在var builder WebApplication.CreateBuilder(args);的后面添加上: var startup new Startup(builder.Configuration); startup.ConfigureServices(builder.Services); 第二步:在var app builder.Build()…

城市网吧视频智能监控方案,实现视频远程集中监控

网吧环境较为复杂,电脑设备众多且人员流动性大,极易发生人员或消防事故,亟需改变,TSINGSEE青犀AI智能网吧视频监管方案可以帮助实现对网吧环境和用户活动的实时监控和管理。 1、视频监控系统 在网吧内部布置高清摄像头&#xff0…

设计模式 -- 适配器模式(Adapter Pattern)

适配器模式:属于结构型模式,结合了两个独立接口的功能,作为 两个不兼容的接口之间的桥梁 。 介绍 意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。主要…

【Shell脚本入门】

Shell中的特殊符号 1.$ 美元符号,用来表示变量的值。 如变量NAME的值为Mike,则使用$NAME就可以得到“Mike”这个值。2.# 井号,除了做为超级用户的提示符之外,还可以在脚本中做为注释的开头字母,每一行语句中&#xff…

WPF中可视化树和逻辑树的区别是什么

在WPF中,用户界面元素被组织成树形结构。这种结构主要分为两种:逻辑树(Logical Tree)和可视化树(Visual Tree)。它们在设计上各有特点和用途。 逻辑树(Logical Tree) 逻辑树是WPF中…

反转字符串中的单词

给你一个字符串 s ,请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意:输入字符串 s中可能会存在前导空格、尾随空格…

笔记54:门控循环单元 GRU

本地笔记地址:D:\work_file\DeepLearning_Learning\03_个人笔记\3.循环神经网络\第9章:动手学深度学习~现代循环神经网络 a a a a a a a

Bulk RNA-seq上下游分析

Bulk-RNA-seq上下游分析还是相对简单的,这次我以mouse为例,进行Bulk-RNA-seq上下游分析,并进行对应的图片绘制。 上游分析 1.软件准备 #安装所需软件 sudo apt install fastqc sudo apt install hisat2 sudo apt install cutadapt sudo ap…

快速幂:acwing 875. 快速幂

给定 n� 组 ai,bi,pi��,��,��,对于每组数据,求出 abiimodpi����mod�� 的值。 输入格式 第一行包…

腾讯云4核8G服务器性能如何多少钱一年?

腾讯云服务器4核8G配置优惠价格表,轻量应用服务器和CVM云服务器均有活动,云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元,5年6490.44元,轻量应用服务器4核8G12M带宽一年446元、529元15个月,腾讯云百科txybk.com分…