Python实现直播推流效果


Posted in Python onNovember 26, 2019

首先给出展示结果,大体就是检测工业板子是否出现。采取检测的方法比较简单,用的OpenCV的模板检测。

Python实现直播推流效果

大体思路

  • opencv读取视频
  • 将视频分割为帧
  • 对每一帧进行处理(opencv模板匹配)
  • 在将此帧写入pipe管道
  • 利用ffmpeg进行推流直播

中间遇到的问题

在处理本地视频时,并没有延时卡顿的情况。但对实时视频流的时候,出现了卡顿延时的效果。在一顿度娘操作之后,采取了多线程的方法。

opencv读取视频

def run_opencv_camera():
 video_stream_path = 0 
 # 当video_stream_path = 0 会开启计算机 默认摄像头 也可以为本地视频文件的路径
 cap = cv2.VideoCapture(video_stream_path)

 while cap.isOpened():
 is_opened, frame = cap.read()
 cv2.imshow('frame', frame)
 cv2.waitKey(1)
 cap.release()

OpenCV模板匹配

模板匹配就是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中每一个可能的位置,比较各处与模板是否相似,当相似度足够高时,就认为找到了目标。

def template_match(img_rgb):
 # 灰度转换
 img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
 # 模板匹配
 res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
 # 设置阈值
 threshold = 0.8
 loc = np.where(res >= threshold)
 if len(loc[0]):
 # 这里直接固定区域
 cv2.rectangle(img_rgb, (155, 515), (1810, 820), (0, 0, 255), 3)
 cv2.putText(img_rgb, category, (240, 600), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
 cv2.putText(img_rgb, Confidence, (240, 640), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
 cv2.putText(img_rgb, Precision, (240, 680), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
 cv2.putText(img_rgb, product_yield, (240, 720), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
 cv2.putText(img_rgb, result, (240, 780), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 5)
 return img_rgb

FFmpeg推流

在Ubuntu 14 上安装 Nginx-RTMP 流媒体服务器

import subprocess as sp
rtmpUrl = ""
camera_path = ""
cap = cv.VideoCapture(camera_path)
# Get video information
fps = int(cap.get(cv.CAP_PROP_FPS))
width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
# ffmpeg command
command = ['ffmpeg',
 '-y',
 '-f', 'rawvideo',
 '-vcodec','rawvideo',
 '-pix_fmt', 'bgr24',
 '-s', "{}x{}".format(width, height),
 '-r', str(fps),
 '-i', '-',
 '-c:v', 'libx264',
 '-pix_fmt', 'yuv420p',
 '-preset', 'ultrafast',
 '-f', 'flv', 
 rtmpUrl]
# 管道配置
p = sp.Popen(command, stdin=sp.PIPE)
# read webcamera
while(cap.isOpened()):
 ret, frame = cap.read()
 if not ret:
 print("Opening camera is failed")
 break
 # process frame
 # your code
 # process frame
 # write to pipe
 p.stdin.write(frame.tostring())

说明:rtmp是要接受视频的服务器,服务器按照上面所给连接地址即可。

多线程处理

python mutilprocessing多进程编程 https://3water.com/article/134726.htm

def image_put(q):
 # 采取本地视频验证
 cap = cv2.VideoCapture("./new.mp4")
 # 采取视频流的方式
 # cap = cv2.VideoCapture(0)
 # cap.set(cv2.CAP_PROP_FRAME_WIDTH,1920)
 # cap.set(cv2.CAP_PROP_FRAME_HEIGHT,1080)
 if cap.isOpened():
 print('success')
 else:
 print('faild')
 while True:
 q.put(cap.read()[1])
 q.get() if q.qsize() > 1 else time.sleep(0.01)
def image_get(q):
 while True:
 # start = time.time()
 #flag += 1
 frame = q.get()
 frame = template_match(frame)
 # end = time.time()
 # print("the time is", end-start)
 cv2.imshow("frame", frame)
 cv2.waitKey(0)
 # pipe.stdin.write(frame.tostring())
 #cv2.imwrite(save_path + "%d.jpg"%flag,frame)
# 多线程执行一个摄像头
def run_single_camera():
 # 初始化
 mp.set_start_method(method='spawn') # init
 # 队列
 queue = mp.Queue(maxsize=2)
 processes = [mp.Process(target=image_put, args=(queue, )),
   mp.Process(target=image_get, args=(queue, ))]
 [process.start() for process in processes]
 [process.join() for process in processes]
def run():
 run_single_camera() # quick, with 2 threads
 pass

说明:使用Python3自带的多线程模块mutilprocessing模块,创建一个队列,线程A从通过rstp协议从视频流中读取出每一帧,并放入队列中,线程B从队列中将图片取出,处理后进行显示。线程A如果发现队列里有两张图片,即线程B的读取速度跟不上线程A,那么线程A主动将队列里面的旧图片删掉,换新图片。

全部代码展示

import time
import multiprocessing as mp
import numpy as np
import random
import subprocess as sp
import cv2
import os
# 定义opencv所需的模板
template_path = "./high_img_template.jpg"
# 定义矩形框所要展示的变量
category = "Category: board"
var_confidence = (np.random.randint(86, 98)) / 100
Confidence = "Confidence: " + str(var_confidence)
var_precision = round(random.uniform(98, 99), 2)
Precision = "Precision: " + str(var_precision) + "%"
product_yield = "Product Yield: 100%"
result = "Result: perfect"
# 读取模板并获取模板的高度和宽度
template = cv2.imread(template_path, 0)
h, w = template.shape[:2]
# 定义模板匹配函数
def template_match(img_rgb):
 # 灰度转换
 img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
 # 模板匹配
 res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
 # 设置阈值
 threshold = 0.8
 loc = np.where(res >= threshold)
 if len(loc[0]):
 # 这里直接固定区域
 cv2.rectangle(img_rgb, (155, 515), (1810, 820), (0, 0, 255), 3)
 cv2.putText(img_rgb, category, (240, 600), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
 cv2.putText(img_rgb, Confidence, (240, 640), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
 cv2.putText(img_rgb, Precision, (240, 680), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
 cv2.putText(img_rgb, product_yield, (240, 720), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
 cv2.putText(img_rgb, result, (240, 780), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 5)
 return img_rgb
# 视频属性
size = (1920, 1080)
sizeStr = str(size[0]) + 'x' + str(size[1])
# fps = cap.get(cv2.CAP_PROP_FPS) # 30p/self
# fps = int(fps)
fps = 11
hz = int(1000.0 / fps)
print ('size:'+ sizeStr + ' fps:' + str(fps) + ' hz:' + str(hz))
rtmpUrl = 'rtmp://localhost/hls/test'
# 直播管道输出
# ffmpeg推送rtmp 重点 : 通过管道 共享数据的方式
command = ['ffmpeg',
 '-y',
 '-f', 'rawvideo',
 '-vcodec','rawvideo',
 '-pix_fmt', 'bgr24',
 '-s', sizeStr,
 '-r', str(fps),
 '-i', '-',
 '-c:v', 'libx264',
 '-pix_fmt', 'yuv420p',
 '-preset', 'ultrafast',
 '-f', 'flv',
 rtmpUrl]
#管道特性配置
# pipe = sp.Popen(command, stdout = sp.PIPE, bufsize=10**8)
pipe = sp.Popen(command, stdin=sp.PIPE) #,shell=False
# pipe.stdin.write(frame.tostring())
def image_put(q):
 # 采取本地视频验证
 cap = cv2.VideoCapture("./new.mp4")
 # 采取视频流的方式
 # cap = cv2.VideoCapture(0)
 # cap.set(cv2.CAP_PROP_FRAME_WIDTH,1920)
 # cap.set(cv2.CAP_PROP_FRAME_HEIGHT,1080)
 if cap.isOpened():
 print('success')
 else:
 print('faild')
 while True:
 q.put(cap.read()[1])
 q.get() if q.qsize() > 1 else time.sleep(0.01)
# 采取本地视频的方式保存图片
save_path = "./res_imgs"
if os.path.exists(save_path):
 os.makedir(save_path)
def image_get(q):
 while True:
 # start = time.time()
 #flag += 1
 frame = q.get()
 frame = template_match(frame)
 # end = time.time()
 # print("the time is", end-start)
 cv2.imshow("frame", frame)
 cv2.waitKey(0)
 # pipe.stdin.write(frame.tostring())
 #cv2.imwrite(save_path + "%d.jpg"%flag,frame)
# 多线程执行一个摄像头
def run_single_camera():
 # 初始化
 mp.set_start_method(method='spawn') # init
 # 队列
 queue = mp.Queue(maxsize=2)
 processes = [mp.Process(target=image_put, args=(queue, )),
   mp.Process(target=image_get, args=(queue, ))]
 [process.start() for process in processes]
 [process.join() for process in processes]
def run():
 run_single_camera() # quick, with 2 threads
 pass
if __name__ == '__main__':
 run()

总结

以上所述是小编给大家介绍的Python实现直播推流效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
使用go和python递归删除.ds store文件的方法
Jan 22 Python
wxpython中利用线程防止假死的实现方法
Aug 11 Python
Python语言实现机器学习的K-近邻算法
Jun 11 Python
python 获取网页编码方式实现代码
Mar 11 Python
python实现图片处理和特征提取详解
Nov 13 Python
Python实现字符型图片验证码识别完整过程详解
May 10 Python
实例详解Python装饰器与闭包
Jul 29 Python
Python列表切片常用操作实例解析
Dec 16 Python
在Python中使用K-Means聚类和PCA主成分分析进行图像压缩
Apr 10 Python
Python run()函数和start()函数的比较和差别介绍
May 03 Python
python如何正确使用yield
May 21 Python
python异步的ASGI与Fast Api实现
Jul 16 Python
Python利用matplotlib绘制约数个数统计图示例
Nov 26 #Python
创建Shapefile文件并写入数据的例子
Nov 26 #Python
python使用opencv在Windows下调用摄像头实现解析
Nov 26 #Python
使用Python实现 学生学籍管理系统
Nov 26 #Python
python redis 批量设置过期key过程解析
Nov 26 #Python
python3 tkinter实现添加图片和文本
Nov 26 #Python
使用Rasterio读取栅格数据的实例讲解
Nov 26 #Python
You might like
解决PHP在DOS命令行下却无法链接MySQL的技术笔记
2010/12/29 PHP
PHP中配置IIS7实现基本身份验证的方法
2015/09/24 PHP
php读取出一个文件夹及其子文件夹下所有文件的方法示例
2017/06/15 PHP
php 获取xml接口数据的处理方法
2018/05/31 PHP
Jquery + Ajax调用webService实例代码(asp.net)
2010/08/27 Javascript
基于jquery异步传输json数据格式实例代码
2013/11/23 Javascript
一个奇葩的最短的 IE 版本判断JS脚本
2014/05/28 Javascript
Egret引擎开发指南之发布项目
2014/09/03 Javascript
Javascript中判断对象是否为空
2015/06/10 Javascript
jQuery实现瀑布流布局详解(PC和移动端)
2020/09/01 Javascript
如何使用jquery修改css中带有!important的样式属性
2016/04/28 Javascript
jQuery 获取多选框的值及多选框中文的函数
2016/05/16 Javascript
jQuery操作dom实现弹出页面遮罩层(web端和移动端阻止遮罩层的滑动)
2016/08/25 Javascript
seajs模块之间依赖的加载以及模块的执行
2016/10/21 Javascript
Vue.js实现一个漂亮、灵活、可复用的提示组件示例
2017/03/17 Javascript
微信小程序组件 marquee实例详解
2017/06/23 Javascript
Vue2.0 http请求以及loading展示实例
2018/03/06 Javascript
JS document form表单元素操作完整示例
2020/01/13 Javascript
Vue如何基于vue-i18n实现多国语言兼容
2020/07/17 Javascript
echarts实现获取datazoom的起始值(包括x轴和y轴)
2020/07/20 Javascript
[00:36]我的中国心——Serenity vs Fnatic
2018/08/21 DOTA
分享15个最受欢迎的Python开源框架
2014/07/13 Python
使用Python生成XML的方法实例
2017/03/21 Python
Python线程下使用锁的技巧分享
2018/09/13 Python
python常用函数与用法示例
2019/07/02 Python
Python 导入文件过程图解
2019/10/15 Python
Pycharm连接远程服务器过程图解
2020/04/30 Python
如何设置Java的运行环境
2013/04/05 面试题
上课睡觉检讨书
2014/01/28 职场文书
2014三八妇女节活动总结
2014/03/01 职场文书
优秀班主任经验交流材料
2014/06/02 职场文书
2014物价局民主生活会对照检查材料思想汇报
2014/09/24 职场文书
乡镇党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
校园环境卫生倡议书
2015/04/29 职场文书
文明礼貌主题班会
2015/08/14 职场文书
phpQuery解析HTML乱码问题(补充官网未列出的乱码解决方案)
2021/04/01 PHP