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 相关文章推荐
将Django框架和遗留的Web应用集成的方法
Jul 24 Python
Python中规范定义命名空间的一些建议
Jun 04 Python
Python实现Sqlite将字段当做索引进行查询的方法
Jul 21 Python
Python Web程序部署到Ubuntu服务器上的方法
Feb 22 Python
Python3 pip3 list 出现 DEPRECATION 警告的解决方法
Feb 16 Python
用uWSGI和Nginx部署Flask项目的方法示例
May 05 Python
python 实现手机自动拨打电话的方法(通话压力测试)
Aug 08 Python
python+rsync精确同步指定格式文件
Aug 29 Python
Python闭包与装饰器原理及实例解析
Apr 30 Python
python 实现分组求和与分组累加求和代码
May 18 Python
关于python scrapy中添加cookie踩坑记录
Nov 17 Python
手把手教你使用TensorFlow2实现RNN
Jul 15 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
dedecms中常见问题修改方法总结
2007/03/21 PHP
木翼下载系统中说明的PHP安全配置方法
2007/06/16 PHP
php+jquery编码方面的一些心得(utf-8 gb2312)
2010/10/12 PHP
PHP自动选择 连接本地还是远程数据库
2010/12/02 PHP
PHP统计当前在线用户数实例讲解
2015/10/21 PHP
php获取网站根目录物理路径的几种方法(推荐)
2017/03/04 PHP
PHP排序算法之冒泡排序(Bubble Sort)实现方法详解
2018/04/20 PHP
PHP示例演示发送邮件给某个邮箱
2019/04/03 PHP
Javascript读取cookie函数代码
2010/10/16 Javascript
jquery修改网页背景颜色通过css方法实现
2014/06/06 Javascript
浅谈Javascript中深复制
2014/12/01 Javascript
仿百度换肤功能的简单实例代码
2016/07/11 Javascript
node.js入门教程之querystring模块的使用方法
2017/02/27 Javascript
js放到head中失效的原因与解决方法
2017/03/07 Javascript
JS数组去重(4种方法)
2017/03/27 Javascript
基于Bootstrap表单验证功能
2017/11/17 Javascript
vue + typescript + 极验登录验证的实现方法
2019/06/27 Javascript
Vue 中使用 typescript的方法详解
2020/02/17 Javascript
vue 数据双向绑定的实现方法
2021/03/04 Vue.js
[01:32]2016国际邀请赛中国区预选赛CDEC战队教练采访
2016/06/26 DOTA
使用python实现扫描端口示例
2014/03/29 Python
Python多线程编程(六):可重入锁RLock
2015/04/05 Python
基于python的七种经典排序算法(推荐)
2016/12/08 Python
详解Django+Uwsgi+Nginx的生产环境部署
2018/06/25 Python
Python生成MD5值的两种方法实例分析
2019/04/26 Python
Python两台电脑实现TCP通信的方法示例
2019/05/06 Python
python实现按行分割文件
2019/07/22 Python
Python队列RabbitMQ 使用方法实例记录
2019/08/05 Python
Python内置类型性能分析过程实例
2020/01/29 Python
纯css3实现图片翻牌特效
2015/03/10 HTML / CSS
英国高档百货连锁店:John Lewis
2017/11/20 全球购物
New Balance比利时官方网站:购买鞋子和服装
2021/01/15 全球购物
报纸媒体创意广告词
2014/03/17 职场文书
婚前协议书怎么写
2014/04/15 职场文书
优秀毕业生找工作自荐信
2014/06/23 职场文书
两行代码解决Jupyter Notebook中文不能显示的问题
2021/04/24 Python