利用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将xml和xsl转换为html的方法
Mar 10 Python
Python多线程编程简单介绍
Apr 13 Python
Python读大数据txt
Mar 28 Python
Python3.6简单反射操作示例
Jun 14 Python
Python使用matplotlib绘制三维图形示例
Aug 25 Python
将string类型的数据类型转换为spark rdd时报错的解决方法
Feb 18 Python
python实现图片转字符小工具
Apr 30 Python
基于树莓派的语音对话机器人
Jun 17 Python
利用python numpy+matplotlib绘制股票k线图的方法
Jun 26 Python
python 定时器每天就执行一次的实现代码
Aug 14 Python
Python高级特性 切片 迭代解析
Aug 23 Python
OpenCV灰度化之后图片为绿色的解决
Dec 01 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中的CMS的涵义
2007/03/11 PHP
PHP采用curl模仿用户登陆新浪微博发微博的方法
2014/11/07 PHP
PHP版本常用的排序算法汇总
2015/12/20 PHP
javascript 添加和移除函数的通用方法
2009/10/20 Javascript
JS 图片缩放效果代码
2010/06/09 Javascript
Bootstrap表格和栅格分页实例详解
2016/05/20 Javascript
js实现table添加行tr、删除行tr、清空行tr的简单实例
2016/10/15 Javascript
Vue制作Todo List网页
2017/04/26 Javascript
使用html+js+css 实现页面轮播图效果(实例讲解)
2017/09/21 Javascript
bootstrap实现二级下拉菜单效果
2017/11/23 Javascript
JS和JQuery实现雪花飘落效果
2017/11/30 jQuery
详解基于Node.js的HTTP/2 Server实践
2018/05/31 Javascript
原生JS实现获取及修改CSS样式的方法
2018/09/04 Javascript
使用elementUI实现将图片上传到本地的示例
2018/09/04 Javascript
在angularJs中进行数据遍历的2种方法
2018/10/08 Javascript
vue.js高德地图实现热点图代码实例
2019/04/18 Javascript
小程序跳转到的H5页面再跳转回跳小程序的方法
2020/03/06 Javascript
解决vue+router路由跳转不起作用的一项原因
2020/07/19 Javascript
python每次处理固定个数的字符的方法总结
2013/01/29 Python
win7安装python生成随机数代码分享
2013/12/27 Python
Python构造函数及解构函数介绍
2015/02/26 Python
python实现2048小游戏
2015/03/30 Python
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
如何在sae中设置django,让sae的工作环境跟本地python环境一致
2017/11/21 Python
浅谈Python的list中的选取范围
2018/11/12 Python
对Python模块导入时全局变量__all__的作用详解
2019/01/11 Python
python re库的正则表达式入门学习教程
2019/03/08 Python
详解向scrapy中的spider传递参数的几种方法(2种)
2020/09/28 Python
DKNY品牌官网:纽约大都会时尚风格
2016/10/20 全球购物
四种会话跟踪技术
2015/05/20 面试题
幼儿园植树节活动总结
2014/07/04 职场文书
党的群众路线教育实践活动对照检查材料范文
2014/09/24 职场文书
师德师风学习材料
2014/12/19 职场文书
女性励志书籍推荐
2019/08/19 职场文书
导游词之扬州大明寺
2019/10/09 职场文书
《废话连篇——致新手》——chinapizza
2022/04/05 无线电