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图片的文件夹路径')
<think>好的,我现在需要帮助用户解决如何用PythonRAW文件换为PNG的问题。用户提到了使用Pillow或OpenCV库,所以我要先回忆这两个库的相关功能。 首先,RAW图像文件通常指的是未经处理的传感器数据,每个相机厂商可能有不同的格式,比如CR2、NEF等。不过有时候用户说的RAW也可能指原始的二进制图像数据,没有头文件信息,这就需要明确宽度、高度、通道数等信息才能正确解析。 接下来,我需要确认用户提到的RAW具体指哪种格式。如果是相机生成的RAW文件(如.CR2),可能需要使用专门的库,比如rawpy。但用户可能是指普通的原始数据文件,比如二进制文件,这时候可能需要用Pillow或OpenCV来处理。 查看用户提供的引用,引用[1]提到了PIL(即Pillow)可以处理打开、保存图像,引用[2]和[3]提到了OpenCV的相关操作。引用[4]提到PNG支持透明通道而JPG不支持,这可能与换时的参数设置有关。 步骤一:读取RAW数据。假设用户的RAW文件是二进制格式,没有元数据,所以需要用户提供宽度、高度、通道数和数据类型。例如,使用NumPy从二进制文件读取数据,然后重塑为图像数组。 步骤二:换为Pillow图像。使用Pillow的Image.fromarray方法,需要注意数据类型和通道顺序,比如RGB还是BGR。可能需要调整通道顺序,尤其是使用OpenCV时,因为OpenCV默认是BGR。 步骤三:保存为PNG。Pillow的save方法可以直接保存为PNG,同时可以处理透明通道,如果有的话。 另外,如果使用OpenCV,读取二进制数据后,可能需要换颜色空间,然后使用cv2.imwrite保存,注意OpenCV的通道顺序是BGR,保存PNG时需要调整。 还需要考虑错误处理,比如文件是否存在、参数是否正确,以及如何处理不同的位深度,比如16位的RAW文件可能需要换为8位才能保存为PNG。 用户可能需要示例代码,所以需要分别用Pillow和OpenCV写出两种方法,并注明注意事项,比如参数需要用户自己提供,因为RAW没有元数据。 最后,生成相关问题,比如处理不同位深的RAW、处理元数据、批量换等。</think>### Python实现RAWPNG格式的方法 以下提供两种基于Pillow和OpenCV的实现方案,需要特别注意RAW格式没有标准元数据,需手动指定图像参数: #### 方案一:使用Pillow库(推荐) ```python import numpy as np from PIL import Image # 参数需根据RAW文件实际情况指定 width = 1920 # 图像宽度 height = 1080 # 图像高度 channels = 3 # 通道数(3=RGB,4=RGBA) dtype = np.uint8 # 数据类型 # 读取RAW二进制数据 with open('input.raw', 'rb') as f: raw_data = np.frombuffer(f.read(), dtype=dtype) # 重塑为图像矩阵 image_array = raw_data.reshape((height, width, channels)) # 创建并保存PNG(自动处理通道顺序) Image.fromarray(image_array, 'RGB').save('output.png') ``` #### 方案二:使用OpenCV库 ```python import cv2 import numpy as np width = 1920 height = 1080 channels = 3 # 读取二进制数据 with open('input.raw', 'rb') as f: raw_data = np.frombuffer(f.read(), dtype=np.uint8) # OpenCV需要BGR通道顺序 bgr_array = raw_data.reshape((height, width, channels))[:, :, ::-1] cv2.imwrite('output.png', bgr_array) ``` ### 关键参数说明(必须明确) 1. **width/height**:图像分辨率 2. **channels**:颜色通道数量 3. **dtype**:常见类型有`np.uint8`(8位)、`np.uint16`(16位) 4. **通道顺序**:Pillow使用RGB,OpenCV默认使用BGR ### 注意事项 1. 16位RAW需要换:`image_array = (raw_data.astype(np.float32) / 256).astype(np.uint8)` 2. 单通道灰度使用`'L'`模式:`Image.fromarray(image_array, 'L')` 3. RAW文件可能包含元数据,需用`rawpy`处理专业相机RAW文件[^1]
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值