利用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爬取三国演义的实现方法
Sep 12 Python
使用Turtle画正螺旋线的方法
Sep 22 Python
python实现壁纸批量下载代码实例
Jan 25 Python
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
Apr 17 Python
解决python3 安装完Pycurl在import pycurl时报错的问题
Oct 15 Python
对pyqt5之menu和action的使用详解
Jun 20 Python
Python之虚拟环境virtualenv,pipreqs生成项目依赖第三方包的方法
Jul 23 Python
Python填充任意颜色,不同算法时间差异分析说明
May 16 Python
Python项目跨域问题解决方案
Jun 22 Python
python通过函数名调用函数的几种场景
Sep 23 Python
python logging模块的使用详解
Oct 23 Python
Python+OpenCV检测灯光亮点的实现方法
Nov 02 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中动态HTML的输出技术
2006/10/09 PHP
投票管理程序
2006/10/09 PHP
在php中判断一个请求是ajax请求还是普通请求的方法
2011/06/28 PHP
php将字符串转化成date存入数据库的两种方式
2014/04/28 PHP
PHP获取对象属性的三种方法实例分析
2019/01/03 PHP
Laravel 关联模型-关联新增和关联更新的方法
2019/10/10 PHP
让你的PHP,APACHE,NGINX支持大文件上传
2021/03/09 PHP
jquery 事件对象属性小结
2010/04/27 Javascript
Prototype源码浅析 String部分(一)之有关indexOf优化
2012/01/15 Javascript
javascript 兼容各个浏览器的事件
2015/02/04 Javascript
jQuery实现tab标签自动切换的方法
2015/02/28 Javascript
jquery实现浮动在网页右下角的彩票开奖公告窗口代码
2015/09/04 Javascript
Listloading.js移动端上拉下拉刷新组件
2016/08/04 Javascript
react性能优化达到最大化的方法 immutable.js使用的必要性
2017/03/09 Javascript
基于匀速运动的实例讲解(侧边栏,淡入淡出)
2017/10/17 Javascript
vue鼠标移入添加class样式,鼠标移出去除样式(active)实现方法
2018/08/22 Javascript
vue2.0项目集成Cesium的实现方法
2019/07/30 Javascript
使用js实现一个简单的滚动条过程解析
2019/09/10 Javascript
JS实现关闭小广告特效
2021/01/29 Javascript
javascript设计模式 ? 职责链模式原理与用法实例分析
2020/04/16 Javascript
vue+element-ui表格封装tag标签使用插槽
2020/06/18 Javascript
[49:07]VGJ.T vs Optic Supermajor小组赛D组 BO3 第二场 6.3
2018/06/04 DOTA
Python切片用法实例教程
2014/09/08 Python
python使用tcp实现局域网内文件传输
2020/03/20 Python
Python实现隐马尔可夫模型的前向后向算法的示例代码
2019/12/31 Python
澳大利亚家具和家居用品在线:BROSA
2017/11/02 全球购物
Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用?
2015/08/04 面试题
建筑行业的大学生自我评价
2013/12/08 职场文书
网上卖盒饭创业计划书范文
2014/02/07 职场文书
竞选部长演讲稿
2014/04/26 职场文书
党在我心中演讲稿
2014/09/02 职场文书
酒店销售经理岗位职责
2015/04/02 职场文书
浅析Python中的套接字编程
2021/06/22 Python
一次MySQL启动导致的事故实战记录
2021/09/15 MySQL
python基础之错误和异常处理
2021/10/24 Python
springboot + mongodb 通过经纬度坐标匹配平面区域的方法
2021/11/01 MongoDB