Python实现直播推流效果
作者:mind_programmonkey 发布时间:2023-10-06 12:43:29
首先给出展示结果,大体就是检测工业板子是否出现。采取检测的方法比较简单,用的OpenCV的模板检测。
大体思路
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 流媒体服务器
https://www.jb51.net/article/175121.htm
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://www.jb51.net/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实现直播推流效果网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://blog.csdn.net/Mind_programmonkey/article/details/102732555


猜你喜欢
- 最近在做后台管理系统的时候遇到要使用富文本编辑器。最后选择了ueditor,我的项目使用 vue+vuex+vue-router+webpa
- 本文实例讲述了Python操作mongodb数据库进行模糊查询操作。分享给大家供大家参考,具体如下:# -*- coding: utf-8
- 一、创建数据库标准1.表的必备三个字段:id、gmt_create、gmt_modified2.gmt_create是创建时间,gmt_mo
- 一、serialize()方法格式:var data = $("#formID").serialize();功能:将表单
- DataFrame对象本质上是带有行列索引的二维矩阵,所以欲对DataFrame对象进行转置操作,需要交换行列索引,同时使二维矩阵转置。首先
- 本篇文章教大家写一个非常简单的Select组件,想必很多人都写过Select,毕竟它太常用了,但是本篇文章的示例使用到了Vue的自定义指令,
- 本文实例为大家分享了Python管理Windows服务的具体代码,供大家参考,具体内容如下#!/usr/bin/python# encodi
- 本文实例为大家分享了python实现滑雪游戏的具体代码,供大家参考,具体内容如下# coding: utf-8# 滑雪小游戏import s
- 本篇博客介绍如何使用Python调用百度地图WEB服务API获取地点对应坐标值,现有一系列结构化地址数据(如:北京市海淀区上地十街十号),目
- 一、前言MySQL启动后,BufferPool就会被初始化,在你没有执行任何查询操作之前,BufferPool中的缓存页都是一块块空的内存,
- 404错误是指在服务器找不到指定的页面。404错误页面是可以自定义的。Smashing Magazine为我们挑选了40个有创意的404错误
- 本人python新手小白,记录学习过程中遇到的一些小问题。python 爬虫获取网页资源之前,联网是必须的,作为 python 中最常用的
- 本文实例讲述了Python函数的定义和作用域。分享给大家供大家参考,具体如下:定义函数默认参数: 可以向函数中添加默认参数,以便为在函数调用
- 在数据库的开发过程中,经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作。如果项目的SP较多,书写又没有一定的规范
- 1、简单的代码from matplotlib import pyplot as pltimport seaborn as snsimport
- Idea 2020 发布之后,官方终于支持了中文语言包但是,我下载后在插件市场无法找到官方的汉化包那要怎么解决这个问题呢?首先,查看你当前I
- MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理
- 下面通过文字说明和代码分析的方式给大家分享移动端图片上传之localResizeIMG先压缩后ajax无刷新上传,具体实现过程请看下文。现在
- Golang浮点数比较和运算会出现误差。浮点数储存至内存中时,2的-1、-2……-n次方不能精确的表示小数部分,所以再把这个数从地址中取出来
- 一、网络结构的可视化我们训练神经网络时,除了随着step或者epoch观察损失函数的走势,从而建立对目前网络优化的基本认知外,也可以通过一些