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 相关文章推荐
python中对list去重的多种方法
Sep 18 Python
python实现基于两张图片生成圆角图标效果的方法
Mar 26 Python
python实现将汉字转换成汉语拼音的库
May 05 Python
Python的Django中django-userena组件的简单使用教程
May 30 Python
Python求均值,方差,标准差的实例
Jun 29 Python
python批量图片处理简单示例
Aug 06 Python
python利用7z批量解压rar的实现
Aug 07 Python
python实现简单银行管理系统
Oct 25 Python
python写一个随机点名软件的实例
Nov 28 Python
使用Pandas将inf, nan转化成特定的值
Dec 19 Python
Python Print实现在输出中插入变量的例子
Dec 25 Python
PyQt5中多线程模块QThread使用方法的实现
Jan 31 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生成缩略图的函数代码(修改版)
2011/01/18 PHP
php数组的一些常见操作汇总
2011/07/17 PHP
php判断正常访问和外部访问的示例
2014/02/10 PHP
Discuz7.2版的faq.php SQL注入漏洞分析
2014/08/06 PHP
JavaScript 学习初步 入门教程
2010/03/25 Javascript
Javascript变量函数浅析
2011/09/02 Javascript
Javascript:为input设置readOnly属性(示例讲解)
2013/12/25 Javascript
基于Css3和JQuery实现打字机效果
2015/08/11 Javascript
jquery如何获取元素的滚动条高度等实现代码
2015/10/19 Javascript
Jquery时间轴特效(三种不同类型)
2015/11/02 Javascript
JavaScript使用链式方法封装jQuery中CSS()方法示例
2017/04/07 jQuery
Vue2.x Todo之自定义指令实现自动聚焦的方法
2019/01/08 Javascript
js数据类型转换与流程控制操作实例分析
2019/12/18 Javascript
node.js基于dgram数据报模块创建UDP服务器和客户端操作示例
2020/02/12 Javascript
JavaScript实现简单进度条效果
2020/03/25 Javascript
python中list常用操作实例详解
2015/06/03 Python
Python 获取当前所在目录的方法详解
2017/08/02 Python
Python+OpenCV人脸检测原理及示例详解
2020/10/19 Python
举例讲解Python常用模块
2019/03/08 Python
Python实现插入排序和选择排序的方法
2019/05/12 Python
python 实现多维数组转向量
2019/11/30 Python
使用python动态生成波形曲线的实现
2019/12/04 Python
tensorflow 实现打印pb模型的所有节点
2020/01/23 Python
纯css3实现的动画按钮的实例教程
2014/11/17 HTML / CSS
浅谈three.js中的needsUpdate的应用
2012/11/12 HTML / CSS
车间主管岗位职责
2013/11/14 职场文书
美发店5.1活动方案
2014/01/24 职场文书
广告业务员岗位职责
2014/02/06 职场文书
致跳远运动员加油稿
2014/02/11 职场文书
2014银行领导班子群众路线对照检查材料思想汇报
2014/09/17 职场文书
学生检讨书怎么写?
2014/10/10 职场文书
2016情人节宣传语
2015/07/14 职场文书
运动会新闻稿
2015/07/17 职场文书
2016中秋节晚会开场白
2015/11/26 职场文书
如何书写邀请函?
2019/06/24 职场文书
react如何快速设置文件路径别名
2021/04/28 Javascript