python视频转文本_python视频帧提取与转换

), [使用LCD12864屏幕播放电影变形金刚-预告](), 当然也可以用于格式转换,视频处理等功能。

本文提供的视频转换功能支持`8bit位图`,`2bit位图`,和`1bit位图`三种格式。三种格式的区别和文件格式见下文。

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库, 可以运行在Linux, Windows, Android和Mac-OS操作系统上. 它轻量级而且高效---由一系列 C 函数和少量 C++ 类构成, 同时提供了Python, Ruby, MATLAB等语言的接口, 实现了图像处理和计算机视觉方面的很多通用算法.本文主要使用了OpenCV的视频采集, 图像色域转换, 视频格式转换, 等功能.

## 准备工作

### 安装 **Python-OpenCV** 库

```bash

pip install opencv-python -i https://mirrors.ustc.edu.cn/pypi/web/simple

```

### 安装 **Numpy** 科学计算库

```bash

pip install numpy -i https://mirrors.ustc.edu.cn/pypi/web/simple

```

## 视频信息提取

### 打开视频文件

```python

# cap = cv2.VideoCapture(0) # 从摄像头捕获视频

cap = cv2.VideoCapture(VIDEO_NAME) # 打开视频文件

```

### 获取视频帧率

```python

VIDEO_FPS = cap.get(cv2.CAP_PROP_FPS)

VIDEO_FPS = int(round(VIDEO_FPS)) # 四舍五入

print("Video FPS:", VIDEO_FPS)

```

### 获取视频帧数

```python

VIDEO_FFRAME = cap.get(cv2.CAP_PROP_FRAME_COUNT)

VIDEO_FFRAME = int(round(VIDEO_FFRAME)) # 四舍五入

print("Video Frame Count:", VIDEO_FFRAME)

```

### 获取视频帧大小

```python

VIDEO_WIDTH = cap.get(cv2.CAP_PROP_FRAME_WIDTH)

VIDEO_HEIGHT = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)

VIDEO_WIDTH = int(round(VIDEO_WIDTH)) # 四舍五入

VIDEO_HEIGHT = int(round(VIDEO_HEIGHT)) # 四舍五入

print("Video Size: (", VIDEO_WIDTH, VIDEO_HEIGHT, ")")

print("LCD Size: (", LCD_WIDTH, LCD_HEIGHT, ")")

```

### 计算图像缩放比例

> 把原始视频缩放为LCD屏幕能容纳的最大分辨率

```python

VIDEO_WSCAL = LCD_WIDTH / VIDEO_WIDTH # 横向缩放比例

VIDEO_HSCAL = LCD_HEIGHT / VIDEO_HEIGHT # 纵向缩放比例

VIDEO_SCAL = min(VIDEO_WSCAL, VIDEO_HSCAL) # 等比缩放(以横向和纵向缩放中的最小值作为左后的缩放比例,以此保证缩放过后的分辨率不会超过LCD屏幕的大小)

LCD_WIDTH = int(VIDEO_WIDTH * VIDEO_SCAL) # 取整,忽略小数

LCD_HEIGHT = int(VIDEO_HEIGHT * VIDEO_SCAL)# 取整,忽略小数

print("Video Scaling Ratio: (", VIDEO_WSCAL, VIDEO_HSCAL, ")")

print("Resize Video Size To: (", LCD_WIDTH, LCD_HEIGHT, ")")

```

### 转换后的视频文件头信息

```c

typedef struct lcd_video_img_hdr_s

{

int32_t flag; //file flag, "LVIF",文件标志

int32_t video_width; //video width, 1920,原始视频的横向分辨率

int32_t video_height; //video height, 1080,原始视频的纵向分辨率

int32_t lcd_width; //lcd width, 128,新视频的横向分辨率

int32_t lcd_height; //lcd height, 64,新始视频的纵向分辨率

int32_t video_fps; //video fps, 25,视频的帧率

int32_t video_frame; //video frame count, 875,视频的帧数

int32_t pixel_bit; //每个像素点所占的bit,视频的色彩空间

} lcd_video_img_hdr_t;

```

![转换后的视频文件头信息](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113150257.png)

### 像素格式

#### 8bit位图

![8bit位图](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113153730.png)

#### 2bit位图

![2bit位图](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113153351.png)

#### 1bit位图

![1bit位图](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113153254.png)

### 视频旋转,灰度,缩放

```python

# frame = cv2.flip(frame, 0) # 旋转

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 灰度化

# frame = cv2.resize(frame, None, fx=VIDEO_SCAL, fy=VIDEO_SCAL, interpolation=cv2.INTER_CUBIC) # 改变大小,等比缩放

frame = cv2.resize(frame, (LCD_WIDTH, LCD_HEIGHT),

interpolation=cv2.INTER_CUBIC) # 改变大小,按尺寸缩放

```

### 循环处理视频帧

```python

while(cap.isOpened()):

ret, frame = cap.read()

if ret == True:

# frame = cv2.flip(frame, 0) # 旋转

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 灰度化

# frame = cv2.resize(frame, None, fx=VIDEO_SCAL, fy=VIDEO_SCAL, interpolation=cv2.INTER_CUBIC) # 改变大小,等比缩放

frame = cv2.resize(frame, (LCD_WIDTH, LCD_HEIGHT),

interpolation=cv2.INTER_CUBIC) # 改变大小,按尺寸缩放

# print("Img Size: ", frame.shape)

# print(frame.dtype)

# print(frame.shape[0], frame.shape[1])

# 显示视频帧

cv2.imshow(VIDEO_NAME, frame)

# 写入镜像文件

if LCD_IMAGE_PIXEL_BIT == 8: # 8位色彩空间,256色位图

LCD_IMAGE_FILE.write(bytearray(frame))

elif LCD_IMAGE_PIXEL_BIT == 1: # 1位色彩空间,黑白双色位图

frame = cv2.GaussianBlur(

frame, ksize=_DEFAULT_GAUSSIAN_BLUR_KERNEL, sigmaX=0) # 高斯模糊

_, frame = cv2.threshold(

frame, 0, 255, _DEFAULT_THRESHOLD_TYPE) # 二值化

# Time Consuming: 57 seconds

byten = 0

bytei = 0

frame.dtype = np.bool

arrya_x = math.ceil(LCD_WIDTH / 8)

array_y = LCD_HEIGHT # array_y = math.ceil(LCD_HEIGHT / 8)

byte_arry = np.zeros((arrya_x*array_y), dtype=np.uint8)

for y in range(LCD_HEIGHT): # range(frame.shape[0]):

for x in range(LCD_WIDTH): # range(frame.shape[1]):

# print(byte_arry[byten])

if ((x % 8) == 0) and (x != 0):

byte_arry[bytei] = byten

bytei += 1

byten = 0

byten = byten << 1

if frame[y][x] != False:

byten = byten | 1

else:

pass

# print(bytei, byten)

byte_arry[bytei] = byten

bytei += 1

byten = 0

# print(byte_arry.size, byten)

LCD_IMAGE_FILE.write(bytearray(byte_arry))

elif LCD_IMAGE_PIXEL_BIT == 2:# 2位色彩控件,黑白灰四色位图

# Time Consuming: 57 seconds

byten = 0

bytei = 0

frame.dtype = np.uint8

array_page = math.ceil(LCD_HEIGHT / LCD_IMAGE_COLOUR_DEPTH)

array_x = LCD_WIDTH

array_y = array_page

byte_arry = np.zeros((array_x*array_y), dtype=np.uint8)

for page in range(array_page):

for x in range(LCD_WIDTH):

byten = 0

for i in range(LCD_IMAGE_COLOUR_DEPTH):

y = (page * LCD_IMAGE_COLOUR_DEPTH) + i

if y >= LCD_HEIGHT:

col = 0

else:

col = lcdCvtGrayColor(

frame[y][x], LCD_IMAGE_COLOUR_DEPTH)

# print("x, y, page, col0 = ", x, y, page, col)

'''

BIT_MAP: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

Y_DOT : | 0 | 1 | 2 | 3 |

'''

bitmv = LCD_IMAGE_COLOUR_DEPTH - i - 1

# col = (col << (2 * bitmv))

col = col * math_pow(2, bitmv * 2)

# print("x, y, page, col1 = ", x, y, page, col)

byten = (byten + col)

byte_arry[bytei] = byten

# print("byte_arry.size, bytei, byten = ", byte_arry.size, bytei, byten)

bytei += 1

byten = 0

LCD_IMAGE_FILE.write(bytearray(byte_arry))

else:

pass

frmcnt += 1

# print("Frame Count:", frmcnt)

# 显示进度

print("#", end="", flush=True)

process_bar += 1

if process_bar >= 60: # 大于60换行

process_bar = 0

print("")

else:

break

if cv2.waitKey(1) & 0xFF == ord('q'):

break

# cv2.waitKey(1)

```

## 运行方法

使用LedSimulator工具打开转换后的bin格式视频文件,观看播放效果,同时也可以把bin格式视频文件导入到LCD192x96液晶屏上播放。

本文提供的LedSimulator工具仅支持192x96 2bit格式文件的播放,源代码请关注后续demo。

## 程序运行截图

![程序运行截图](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113155151.png)

![程序运行截图](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113155215.png)

![转换结果对比](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113154032.png)

![转换结果对比](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113154132.png)

![转换结果对比](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113154421.png)

## 项目内文件截图

![项目内文件截图](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113155325.png)

![项目内文件截图](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/PicGo20200113155407.png)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值