ISP之提取.DNG格式中的RAW(Bayer)数据
最近在研究ISP算法,需要一些测试RAW图的二进制数据,突然发现有些手机的拍照模式可以选择RAW格式数据输出,但是这些RAW格式实际上是将Bayer格式的数据连同一些其他信息,如黑电平、拍摄时的曝光时长、白平衡、Bayer图像尺寸、CCM矩阵等一起打包的数据。
不同品牌的相机的RAW格式打包文件的后缀名都不同,如佳能是.CR2、尼康是.NEF、索尼是.ARW等。
DNG(数字负片)也是一种打包的RAW格式,是一种比较新的统一原始数据标准。目前所有单反相机、苹果、华为、小米、一加等手机厂商都已经支持DNG格式输出拍照原始图像数据(DNG)。
为了解析处DNG格式的二进制Bayer数据(如RGGB),使用以下Python脚本:
需要rawpy、numpy、exifread第三方库包,使用pip install安装即可
import rawpy
import numpy as np
import exifread
#HUAWEI Mate30:12bit blacklevel:256
#origin size1(X1):(width,heigt)=7296X5472 BayerPattern:BGGR
#origin size2(广角):(width,heigt)=4608X3456 BayerPattern:RGGB
#origin size3(X3):(width,heigt)=3264X2448 BayerPattern:RGGB
#1/2 clip size:(width,heigt)=3648X2736
# 指定DNG文件路径
dng_path = "dngimagepath.dng"
#读取DNG文件标签信息
with open(dng_path, 'rb') as f:
# Read the metadata
tags = exifread.process_file(f) #读取所有的tag
for tag in tags.keys():
print(tag, tags[tag])
# Get the black level tag value
black_level = tags['Image BlackLevel'].values[0]
print(black_level)
f.close()
# 打开DNG文件
with rawpy.imread(dng_path) as raw:
# 提取原始的Bayer模式数据
bayer_data = raw.raw_image.copy()
# 将Bayer数据转换为numpy数组
bayer_array = np.array(bayer_data)
#bayer_array_clip=bayer_array[0:2736,0:3648] #若需要裁剪
bayer_array_clip=bayer_array
"""
# 获取红色通道
red_channel = bayer_array[0::2, 0::2]
# 获取绿色通道
green_channel_1 = bayer_array[0::2, 1::2]
green_channel_2 = bayer_array[1::2, 0::2]
# 将两个绿色通道取平均
green_channel = (green_channel_1 + green_channel_2) / 2
# 获取蓝色通道
blue_channel = bayer_array[1::2, 1::2]
"""
bayer_array_clip=bayer_array_clip.astype(np.int32)
# bayer_array_clip=bayer_array_clip-black_level #减去黑电平black_level
# bayer_array_clip[bayer_array_clip<0]=0 #减去黑电平后钳位
dst=bayer_array_clip.astype(np.uint16)
out_name="./image.raw"
dst.tofile(out_name)
参考
DNG 文件解析 - 知乎