Python raw格式图像转png格式

raw数据的读取有rawpy,numpy和逐元素读取等方法,一般在raw数据上进行深度学习神经网络的研究需要先将raw转换成数组方式才能输入到模型中进行训练。先介绍两种读取raw数据为数组并将之转为png图片的方法:

1、使用rawpy来读取raw数据

注意raw数据有很多种不同后缀名,如:.raw、.dng、.arw等。raw数据直接来源于sensor,不同公司的sensor是不一样的,他们的数据后缀名也就不一样了。下面以.dng为例,其他也一样的:

import numpy as np
import imageio
import rawpy
import sys
import os
import cv2

def extract_bayer_channels(raw):

    ch_B  = raw[1::2, 1::2]
    ch_Gb = raw[0::2, 1::2]
    ch_R  = raw[0::2, 0::2]
    ch_Gr = raw[1::2, 0::2]

    return ch_R, ch_Gr, ch_B, ch_Gb


if __name__ == "__main__":

    raw_file = "raw.dng"
    print("Converting file " + raw_file)

    if not os.path.isfile(raw_file):
        print("The file doesn't exist!")
        sys.exit()
    
    raw = rawpy.imread(raw_file)
    raw_image = raw.raw_image
    del raw
	
	"""# extract_bayer_channels将raw数据按4通道提取,至于为何是4通道这里就不介绍了
    raw_image = raw_image.astype(np.float32)
    print(np.max(raw_image))
    ch_R, ch_Gr, ch_B, ch_Gb = extract_bayer_channels(raw_image)
    # 拼合四通道一起
    out = np.stack((R, Gr, Gb, B))"""
	
	# raw数据一般是16位,有效位可能为16,14,12,10等。常见位12位
    png_image = raw_image.astype(np.uint16)
    new_name = raw_file.replace(".dng", ".png")
    imageio.imwrite(new_name, png_image)

numpy读取raw数据的方式是:numpy.fromfile('a.raw')

2、以二进制读raw数据然后逐元素取值

一般raw数据是12位有效的,不管是rawpy,还是numpy。它们读取raw数据都是将16位全部读进来,默认低四位位无效位且全部为0,可是这样会增大像素值的范围。有效位12位的话,那么像素值范围应该是0~4095,而不丢弃无效的4个0的话,像素值的范围就会变成0-65535了。以二进制读取则可以避免:

# -*- coding:utf8 -*-

import numpy as np
import cv2
import os
import imageio

def oneimg2png(root_dir, out_path):
    filelist = os.listdir(root_dir)
    
    # filelist.sort(key=lambda x: int(x.split('_')[5]))
    
    for file in filelist:
    	# shape为raw数据的分辨率乘积
        bayer = np.zeros(shape=2073600, dtype='uint16')
        file_path = os.path.join(root_dir, file)
        with open(file_path, "rb") as f:
            for i in range(0, len(f.read()), 2):
                f.seek(i)
                raw = f.read(2)
                a1 = int((raw[0] / 16) % 16)
                a2 = int(raw[0] % 16)
                a3 = int((raw[1] / 16) % 16)
                a4 = int(raw[1] % 16)
                # 两个字节对应一个像素点,我的数据有效位为12位,高低位顺序为a3 a4 a1 a2,
                # a2位低四位且是无效位全为0,所以抛掉不用
                value = a3 * 256 + a4 * 16 + a1 * 1
                # bayer[int(i / 2)] = value / 4096 * 1024
                bayer[int(i / 2)] = value

        bayer = bayer.reshape(1080, 1920)
        print("bayer max:{} bayer min:{}".format(np.max(bayer), np.min(bayer)))
        new_name = file_path.replace(".raw", ".png")

        new_name = os.path.basename(new_name)
        imageio.imwrite(out_path + '/' + new_name, bayer)

        f.close()

    print("raw finished")

if __name__ == '__main__':
    _ = oneimg2png(root_dir='放有raw数据的文件夹路径', out_path='输出png图片的文件夹路径')

你可能感兴趣的:(图片格式转换)