利用python读取YUV文件 转RGB 8bit/10bit通用


Posted in Python onDecember 09, 2019

注:本文所指的YUV均为YUV420中的I420格式(最常见的一种),其他格式不能用以下的代码。

位深为8bit时,每个像素占用1字节,对应文件指针的fp.read(1);

位深为10bit时,每个像素占用2字节,对应文件指针的fp.read(2);

然后使用 int.from_bytes() 方法将二进制转换为int型数字。

以下程序可以读8bit或10bit位深的YUV,需要指定从第几帧开始读、一共读多少帧。

它返回三个数组,其shape分别为:Y [frame,W,H] U [frame,W/2,H/2] V [frame,W/2,H/2]

当只读1帧时它返回:Y [W,H] U [W/2,H/2] V [W/2,H/2]

# -*- coding: utf-8 -*-
 
import math
from functools import partial
import numpy as np
import matplotlib.pyplot as plt
 
 
def readyuv420(filename, bitdepth, W, H, startframe, totalframe, show=False):
  # 从第startframe(含)开始读(0-based),共读totalframe帧
 
  uv_H = H // 2
  uv_W = W // 2
 
  if bitdepth == 8:
    Y = np.zeros((totalframe, H, W), np.uint8)
    U = np.zeros((totalframe, uv_H, uv_W), np.uint8)
    V = np.zeros((totalframe, uv_H, uv_W), np.uint8)
  elif bitdepth == 10:
    Y = np.zeros((totalframe, H, W), np.uint16)
    U = np.zeros((totalframe, uv_H, uv_W), np.uint16)
    V = np.zeros((totalframe, uv_H, uv_W), np.uint16)
 
  plt.ion()
 
  bytes2num = partial(int.from_bytes, byteorder='little', signed=False)
 
  bytesPerPixel = math.ceil(bitdepth / 8)
  seekPixels = startframe * H * W * 3 // 2
  fp = open(filename, 'rb')
  fp.seek(bytesPerPixel * seekPixels)
 
  for i in range(totalframe):
 
    for m in range(H):
      for n in range(W):
        if bitdepth == 8:
          pel = bytes2num(fp.read(1))
          Y[i, m, n] = np.uint8(pel)
        elif bitdepth == 10:
          pel = bytes2num(fp.read(2))
          Y[i, m, n] = np.uint16(pel)
 
    for m in range(uv_H):
      for n in range(uv_W):
        if bitdepth == 8:
          pel = bytes2num(fp.read(1))
          U[i, m, n] = np.uint8(pel)
        elif bitdepth == 10:
          pel = bytes2num(fp.read(2))
          U[i, m, n] = np.uint16(pel)
 
    for m in range(uv_H):
      for n in range(uv_W):
        if bitdepth == 8:
          pel = bytes2num(fp.read(1))
          V[i, m, n] = np.uint8(pel)
        elif bitdepth == 10:
          pel = bytes2num(fp.read(2))
          V[i, m, n] = np.uint16(pel)
 
    if show:
      print(i)
      plt.subplot(131)
      plt.imshow(Y[i, :, :], cmap='gray')
      plt.subplot(132)
      plt.imshow(U[i, :, :], cmap='gray')
      plt.subplot(133)
      plt.imshow(V[i, :, :], cmap='gray')
      plt.show()
      plt.pause(1)
      #plt.pause(0.001)
 
  if totalframe==1:
    return Y[0], U[0], V[0]
  else:
    return Y,U,V
 
 
if __name__ == '__main__':
  #y, u, v = readyuv420(r'F:\_commondata\video\176x144 qcif\football_qcif.yuv', 8, 176, 144, 1, 5, True)
  y, u, v = readyuv420(r'F:\_commondata\video\1920x1080 B\RitualDance_1920x1080_60fps_10bit_420.yuv', 10, 1920, 1080, 0, 5, True)
  print(y.shape,u.shape,v.shape)

以下程序将YUV转为RGB(只能读8bit位深的YUV),返回1个数组,其shape为: [frame,W,H,3]

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import matplotlib.pyplot as plt
 
 
def yuv2rgb(yuvfilename, W, H, startframe, totalframe, show=False, out=False):
  # 从第startframe(含)开始读(0-based),共读totalframe帧
  arr = np.zeros((totalframe,H,W,3), np.uint8)
  
  plt.ion()
  with open(yuvfilename, 'rb') as fp:
    seekPixels = startframe * H * W * 3 // 2
    fp.seek(8 * seekPixels) #跳过前startframe帧
    for i in range(totalframe):
      print(i)
      oneframe_I420 = np.zeros((H*3//2,W),np.uint8)
      for j in range(H*3//2):
        for k in range(W):
          oneframe_I420[j,k] = int.from_bytes(fp.read(1), byteorder='little', signed=False)
      oneframe_RGB = cv2.cvtColor(oneframe_I420,cv2.COLOR_YUV2RGB_I420)
      if show:
        plt.imshow(oneframe_RGB)
        plt.show()
        plt.pause(0.001)
      if out:
        outname = yuvfilename[:-4]+'_'+str(startframe+i)+'.png'
        cv2.imwrite(outname,oneframe_RGB[:,:,::-1])
      arr[i] = oneframe_RGB
  return arr
 
if __name__ == '__main__':
  video = yuv2rgb(r'D:\_workspace\akiyo_qcif.yuv', 176, 144, 0, 10, False, True)

用ffmpeg也可以,比如你需要将yuv的第8帧输出成一个png:

ffmpeg -s 176x144 -i akiyo_qcif.yuv -filter:v select="between(n\,8\,8)" out.png

以上这篇利用python读取YUV文件 转RGB 8bit/10bit通用就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用实例分析Python中method的参数传递过程
Apr 02 Python
python访问抓取网页常用命令总结
Apr 11 Python
Python栈算法的实现与简单应用示例
Nov 01 Python
浅谈python jieba分词模块的基本用法
Nov 09 Python
Python Flask-web表单使用详解
Nov 18 Python
Python编程使用*解包和itertools.product()求笛卡尔积的方法
Dec 18 Python
Python操作配置文件ini的三种方法讲解
Feb 22 Python
学习python可以干什么
Feb 26 Python
使用Python3 poplib模块删除服务器多天前的邮件实现代码
Apr 24 Python
python文件读取失败怎么处理
Jun 23 Python
Opencv中cv2.floodFill算法的使用
Jun 18 Python
python自动化八大定位元素讲解
Jul 09 Python
YUV转为jpg图像的实现
Dec 09 #Python
Pandas+Matplotlib 箱式图异常值分析示例
Dec 09 #Python
Python箱型图处理离群点的例子
Dec 09 #Python
Python实现非正太分布的异常值检测方式
Dec 09 #Python
python 实现检验33品种数据是否是正态分布
Dec 09 #Python
Python远程开发环境部署与调试过程图解
Dec 09 #Python
使用 Python 合并多个格式一致的 Excel 文件(推荐)
Dec 09 #Python
You might like
解析PHP中$_FILES的使用以及注意事项
2013/07/05 PHP
PHP获取当前url的具体方法全面解析
2013/11/26 PHP
ThinkPHP CURD方法之page方法详解
2014/06/18 PHP
PHP获取指定月份第一天和最后一天的方法
2015/07/18 PHP
php-beanstalkd消息队列类实例分享
2017/07/19 PHP
php中html_entity_decode实现HTML实体转义
2018/06/13 PHP
php+ajax 文件上传代码实例
2019/03/18 PHP
让你的博文自动带上缩址的实现代码,方便发到微博客上
2010/12/28 Javascript
js操作table示例(个人心得)
2013/11/29 Javascript
JavaScript中property和attribute的区别详细介绍
2015/03/03 Javascript
jQuery图片轮播插件——前端开发必看
2016/05/31 Javascript
jQuery模拟实现的select点击选择效果【附demo源码下载】
2016/11/09 Javascript
js,jq,css多方面实现简易下拉菜单功能
2017/05/13 Javascript
Iphone手机、安卓手机浏览器控制默认缩放大小的方法总结(附代码)
2017/08/18 Javascript
[js高手之路]图解javascript的原型(prototype)对象,原型链实例
2017/08/28 Javascript
纯js实现无缝滚动功能代码实例
2020/02/21 Javascript
Python读取sqlite数据库文件的方法分析
2017/08/07 Python
python+pandas生成指定日期和重采样的方法
2018/04/11 Python
pyqt5利用pyqtDesigner实现登录界面
2019/03/28 Python
python查找特定名称文件并按序号、文件名分行打印输出的方法
2020/04/24 Python
Python几种常见算法汇总
2020/06/02 Python
python中get和post有什么区别
2020/06/19 Python
python实现批处理文件
2020/07/28 Python
django下创建多个app并设置urls方法
2020/08/02 Python
如何利用python 读取配置文件
2021/01/06 Python
python 获取谷歌浏览器保存的密码
2021/01/06 Python
纽约家具、家居装饰和地毯店:ABC Carpet & Home
2017/06/21 全球购物
美国运动鞋和服装网上商店:YCMC
2018/09/15 全球购物
C有"按引用传递"吗
2016/09/06 面试题
LINUX下线程,GDI类的解释
2016/12/14 面试题
计算机专业毕业生推荐信
2013/11/25 职场文书
视光学专业自荐信
2014/06/24 职场文书
2014年9.18纪念日演讲稿
2014/09/14 职场文书
2014年教研组工作总结
2014/11/26 职场文书
农村婚庆主持词
2015/06/29 职场文书
解析mybatis-plus中的resultMap简单使用
2021/11/23 Java/Android