利用Python将YUV格式文件批量转为BMP保存相对应文件夹下

利用python的tkinter模块选择要转化的yuv格式文件夹,遍历文件并转化格式,如果直接从yuv转rgb,cv2.COLOR_YUV2RGB_Y422会遇到通道不对的情况,所以在此先转NV12格式,再转RGB格式,此处定义三个函数,但这边用来yuv转nv12和nv12转rgb函数,完整代码(含调试注释)如下:

import numpy as np
import cv2
from PIL import Image
import os
import tkinter as tk
from tkinter import filedialog

root=tk.Tk()
root.withdraw()


# 指定输入YUV文件夹和输出BMP文件夹
input_folder = filedialog.askdirectory(title="input folder")
# output_folder = filedialog.askdirectory(title="output folder")

# 设置图像宽度和高度
width = 1920
height = 1536

# 定义YUV到RGB的转换函数
def yuv_to_rgb(yuv_frame, width, height):
    Y = yuv_frame[:width*height]
    U = yuv_frame[width*height:width*height + (width//2)*(height//2)]
    V = yuv_frame[width*height + (width//2)*(height//2):]

    Y = np.reshape(Y, (height, width))
    U = np.reshape(U, (height//2, width//2)).repeat(2, axis=0).repeat(2, axis=1)
    V = np.reshape(V, (height//2, width//2)).repeat(2, axis=0).repeat(2, axis=1)

    YUV = np.dstack((Y, U, V)).astype(np.uint8)
    # RGB = cv2.cvtColor(YUV, cv2.COLOR_YUV2RGB_I420)
    RGB = cv2.cvtColor(YUV, cv2.COLOR_YUV2RGB)
    return RGB

# 定义YUV到NV12的转换函数
def yuv_to_nv12(yuv_data,width, height):
    Y = yuv_data[:width*height]
    U = yuv_data[width*height:width*height + (width//2)*(height//2)]
    V = yuv_data[width*height + (width//2)*(height//2):]

    # 将Y、U、V分量重新排列以创建NV12数据
    UV = np.empty((height, width), dtype=np.uint8)
    UV[::2, ::2] = U.reshape((height//2, width//2))
    UV[1::2, ::2] = V.reshape((height//2, width//2))

    # 创建NV12数据
    nv12_data = np.dstack((Y.reshape((height, width)), UV))
    return nv12_data

# 定义NV12到BMP的转换函数
def nv12_to_bmp(nv12_data, width, height):
    # Convert NV12 to BGR
    yuv = np.frombuffer(nv12_data, dtype=np.uint8)
    bgr = cv2.cvtColor(yuv.reshape((int(1.5 * height), width)), cv2.COLOR_YUV2BGR_NV12)
    return bgr
    # cv2.imwrite(output_path, bgr)

# 遍历输入文件夹中的所有文件
for root, dirs, files in os.walk(input_folder):
    # print (root, dirs, files)
    # quit()
    for file in files:
        if file.endswith(".yuv"):
            # 构建输入文件的完整路径
            input_file_path = os.path.join(root, file)
            # print(input_file_path)
            # quit()
            # 构建输出文件的完整路径,将文件后缀改为.bmp
            output_file_path = os.path.join(root, os.path.splitext(file)[0] + ".bmp")
            # print(output_file_path)
            # quit()
            # 读取YUV文件
            with open(input_file_path, 'rb') as f:
                yuv_data = np.frombuffer(f.read(), dtype=np.uint8)
                # YUV转NV12
                nv12_frame = yuv_to_nv12(yuv_data, width, height)
                # print("nv12_frame:",nv12_frame)
                
                # NV12转BMP
                bmp_frame = nv12_to_bmp(yuv_data, width, height)
                # print("bmp_frame:",nv12_frame)

                # 将YUV转换为RGB
                # rgb_frame = yuv_to_rgb(yuv_data, width, height)
                # rgb_frame.save(output_file_path, 'bmp')

                # cv2.imwrite(output_file_path,rgb_frame)
                # print(f"Converted {input_file_path} to {output_file_path}")
                cv2.imwrite(output_file_path,bmp_frame)
                print(f"Converted {input_file_path} to {output_file_path}")
                

print("Conversion complete.")


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值