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 tempfile模块学习笔记(临时文件)
May 25 Python
Python内置函数Type()函数一个有趣的用法
Feb 18 Python
详细介绍Python函数中的默认参数
Mar 30 Python
python使用pil生成图片验证码的方法
May 08 Python
python的dataframe转换为多维矩阵的方法
Apr 11 Python
Python线程同步的实现代码
Oct 03 Python
对python csv模块配置分隔符和引用符详解
Dec 12 Python
Python爬虫图片懒加载技术 selenium和PhantomJS解析
Sep 18 Python
利用pytorch实现对CIFAR-10数据集的分类
Jan 14 Python
如何完美的建立一个python项目
Oct 09 Python
python re模块和正则表达式
Mar 24 Python
Python一行代码实现自动发邮件功能
May 30 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
探讨file_get_contents与curl效率及稳定性的分析
2013/06/06 PHP
ThinkPHP中html:list标签用法分析
2016/01/09 PHP
利用PHP将图片转换成base64编码的实现方法
2016/09/13 PHP
PHP获取文本框、密码域、按钮的值实例代码
2017/04/19 PHP
JavaScript实现页面实时显示当前时间的简单实例
2013/07/20 Javascript
jquery中交替点击事件toggle方法的使用示例
2013/12/08 Javascript
JavaScript中的fontsize()方法使用详解
2015/06/08 Javascript
jQuery实现返回顶部功能
2016/02/23 Javascript
BootStrap智能表单实战系列(六)表单编辑页面的数据绑定
2016/06/13 Javascript
Bootstrap CSS布局之图像
2016/12/17 Javascript
Nodejs进阶:express+session实现简易登录身份认证
2017/04/24 NodeJs
解决Linux无法正常安装与卸载Node.js的方法
2018/01/19 Javascript
小程序实现订单倒计时功能
2019/04/23 Javascript
vue-cli3添加模式配置多环境变量的方法
2019/06/05 Javascript
JavaScript 实现轮播图特效的示例
2020/11/05 Javascript
详解React路由传参方法汇总记录
2020/11/29 Javascript
Python实现的二维码生成小软件
2014/07/11 Python
python的keyword模块用法实例分析
2015/06/30 Python
Python使用迭代器打印螺旋矩阵的思路及代码示例
2016/07/02 Python
json跨域调用python的方法详解
2017/01/11 Python
python中pandas.DataFrame排除特定行方法示例
2017/03/12 Python
使用python实现ANN
2017/12/20 Python
Python爬虫_城市公交、地铁站点和线路数据采集实例
2018/01/10 Python
Python实现简单文本字符串处理的方法
2018/01/22 Python
pandas使用之宽表变窄表的实现
2020/04/12 Python
瑞贝卡·明可弗包包官网:Rebecca Minkoff
2016/07/21 全球购物
Sephora丝芙兰马来西亚官方网站:国际化妆品购物
2018/03/15 全球购物
世界上最大的艺术和工艺用品商店:MisterArt.com
2018/07/13 全球购物
Solaris操作系统的线程机制
2015/07/28 面试题
公务员培训自我鉴定
2014/02/01 职场文书
小学生评语大全
2014/04/18 职场文书
致运动员加油稿
2015/07/21 职场文书
Go各时间字符串使用解析
2021/04/02 Golang
十个Python自动化常用操作,即拿即用
2021/05/10 Python
新手必备Python开发环境搭建教程
2021/05/28 Python
使用Spring处理x-www-form-urlencoded方式
2021/11/02 Java/Android