LiveGBS国标GB/T28181视频流媒体平台

软件包下载

LiveGBS GB28181流媒体服务下载地址:https://www.liveqing.com/docs/download/LiveGBS.html#%E7%89%88%E6%9C%AC%E4%B8%8B%E8%BD%BD

选择windows版本的LiveGBS 信令服务LiveGBS流媒体服务,免费版授权周期为26天,届时需要手动更新软件服务

安装LiveGBS GB28281

解压下载好的软件包,分别启动LiveCMS.exeLiveSMS.exe,如果有默认端口被占用的情况可以修改对应的livecms.inilivesms.ini配置文件,这里我将LiveGBS的默认端口从10000修改为10005

成功启动后后台出现livecms和livesms的图标

Read More

paddleDetection-视频OCR

PPOCR_V4

安装百度最新ppocr_v4库,使用虚拟环境为py39_vio,本虚拟环境不可与人脸识别(py38_arcface)兼容(opencv版本不兼容)

1
pip install paddleocr --user -i https://mirror.baidu.com/pypi/simple

代码

cfg_utils.py新增cfg--ocr,设置True为开启,默认False

1
2
3
4
5
parser.add_argument(
"--ocr",
type=bool,
default=False,
help="use paddlepaddle-ocr")

pipeline.py

1
from python.visualize import visualize_box_mask, visualize_attr, visualize_pose, visualize_action, visualize_vehicleplate, visualize_vehiclepress, visualize_lane, visualize_vehicle_retrograde, visualize_ocr
1
2
3
class PipePredictor(object):  
def __init__(self, args, cfg, is_video=True, multi_camera=False):
self.ocr = args.ocr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def visualize_video(self,
image_rgb,
result,
collector,
frame_id,
fps,
entrance=None,
records=None,
center_traj=None,
do_illegal_parking_recognition=False,
illegal_parking_dict=None):
image = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
mot_res = copy.deepcopy(result.get('mot'))

if self.ocr:
lock.acquire() # 加锁,paddleOCR是线程不安全的
ocr_result = ocr.ocr(image, cls=True)[0]
lock.release()
ocr_boxes = [line[0] for line in ocr_result]
ocr_txts = [line[1][0] for line in ocr_result]
ocr_scores = [line[1][1] for line in ocr_result]

image = visualize_ocr(image, ocr_boxes, ocr_txts, ocr_scores)

visualize.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def visualize_ocr(im, boxes, texts, score):
if isinstance(im, str):
im = Image.open(im)
im = np.ascontiguousarray(np.copy(im))
im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR)
else:
im = np.ascontiguousarray(np.copy(im))

# 创建透明图层,为图像添加文字水印
im = Image.fromarray(im)
im = im.convert('RGBA')
im_canvas = Image.new('RGBA', im.size, (255, 255, 255, 0))

for i, res in enumerate(texts):
if boxes is not None:
box = boxes[i]
text = res
if text == "":
continue

text_scale = max(1.0, int(box[2][1] - box[1][1]))

draw = ImageDraw.Draw(im_canvas)
draw.text(
(box[0][0], box[0][1]),
text,
font=ImageFont.truetype(font_file, size=int(text_scale)),
fill=(255, 255, 0, 85)) # 第四位是透明度
try:
draw.rectangle(
((box[0][0], box[0][1]), (box[2][0], box[2][1])),
fill=None,
outline=(255, 255, 0),
width=1)
except ValueError:
pass

# 复合图层
im = Image.alpha_composite(im, im_canvas)
im = im.convert('RGB')
# 还原连续存储数组
im = np.ascontiguousarray(np.copy(im))
return im

Read More

paddleDetection:OpenCV检测框转中文

注:OpenCV不能直接显示中文,通过PIL转换会损失一部分算力性能

修改源码(可视化)

./deploy/python/visualize.py

增加导入字体库和字体文件

1
2
3
from PIL import Image, ImageDraw, ImageFile, ImageFont

font_file = '/exp/work/video/PaddleDetection/deploy/pipeline/SourceHanSansCN-Medium.otf'

visualize_attr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def visualize_attr(im, results, boxes=None, is_mtmct=False):
if isinstance(im, str):
im = Image.open(im)
im = np.ascontiguousarray(np.copy(im))
im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR)
else:
im = np.ascontiguousarray(np.copy(im))

line_inter = im.shape[0] / 40.
text_scale = max(0.5, im.shape[0] / 100.)
# 将nparray图像转PIL图像
im = Image.fromarray(im)

for i, res in enumerate(results):
print(i, res)
if boxes is None:
text_w = 3
text_h = 1
elif is_mtmct:
box = boxes[i] # multi camera, bbox shape is x,y, w,h
text_w = int(box[0]) + 3
text_h = int(box[1])
else:
box = boxes[i] # single camera, bbox shape is 0, 0, x,y, w,h
text_w = int(box[2]) + 3
text_h = int(box[3])
for text in res:
text_h += int(line_inter)
text_loc = (text_w, text_h)
# 写入
draw = ImageDraw.Draw(im)
draw.text(
text_loc,
text,
font=ImageFont.truetype(font_file, size=int(text_scale)), # 字体位置
fill=(0, 255, 255))
# 还原连续存储数组
im = np.ascontiguousarray(np.copy(im))
return im

Read More

arcface_paddle

环境

GPU(物理)

  • NVIDIA 3090*2

  • 显卡驱动 515.43.04

  • CUDA版本 11.7

  • CUDAtoolkit (cuda_11.7.0_515.43.04_linux)

  • cuDNN (v8.4.1)

  • paddlepaddle 多卡训练需要NCLL支持 (ncll v2.12.12 cuda11.7)

paddlepaddle版本

  • paddlepaddle-gpu==2.2.0rc0(虚拟环境cuda11.2)

python环境

  • CentOS7.9

  • anaconda3

  • python3.8

anaconda安装insightface

重要:pillow版本建议选择9.5 否则过高会导致安装insightface报错 (错误原因:pillow10移除了getsize方法,需要修改对应位置源码为getbboxgetlength

告警信息:

1
2
tools/test_recognition.py:627: DeprecationWarning: getsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use getbbox or getlength instead.
tw = font.getsize(text)[0]

环境安装

1
2
3
4
5
6
7
8
# .
conda install paddlepaddle-gpu==2.2.0rc0 cudatoolkit=11.2 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/ -c conda-forge
# insightface
pip install -r requirements.txt -i https://mirror.baidu.com/pypi/simple
# insightface/recongition/arcface_paddle/
pip install -r requirement.txt -i https://mirror.baidu.com/pypi/simple
# insightface-paddle
pip install insightface-paddle -i https://mirror.baidu.com/pypi/simple

Read More

paddleDetection前置

环境

GPU

  • NVIDIA 3090*2

  • 显卡驱动 515.43.04

  • CUDA版本 11.7

  • CUDAtoolkit (cuda_11.7.0_515.43.04_linux)

  • cuDNN (v8.4.1)

  • paddlepaddle 多卡训练需要NCLL支持 (ncll v2.12.12 cuda11.7)

paddlepaddle版本

  • v2.4.2

paddleDetection版本

  • v2.6.0

python环境

  • CentOS7.9

  • anaconda3

  • python3.8

普通视频处理

h264格式视频被opencv解析帧率超过65535报错

源码:

./deploy/pipeline/pipeline.py predict_video

1
2
3
out_path = os.path.join(self.output_dir, video_out_name + ".mp4")
fourcc = cv2.VideoWriter_fourcc(* 'mp4v')
writer = cv2.VideoWriter(out_path, fourcc, fps, (width, height))

输入:cv2.VideoCapture()

输出:cv2.VideoWriter()

本GPU模式下对时长5分钟的行人检测视频处理时间约20分钟(高精度模型),视频体积增大13倍(100M->1.3G)

Read More

搭建nebula-CentOS集群(极速版)

环境准备

  • 系统

CentOS7.9

  • 机器

三台,分别为nebula01nebula02nebula03

  • 安装位置

/usr/local

  • nebula版本

2.6.1

  • nebula-graph-studio版本

3.2.3

快速开始

  • 下载tar.gz文件
1
2
3
cd /usr/local
wget https://oss-cdn.nebula-graph.com.cn/package/2.6.1/nebula-graph-2.6.1.el7.x86_64.tar.gz
wget https://oss-cdn.nebula-graph.com.cn/nebula-graph-studio/3.2.3/nebula-graph-studio-3.2.3.x86_64.tar.gz
  • 解压缩并重命名文件
1
2
tar -zxvf nebula-graph-2.6.1.el7.x86_64.tar.gz && mv nebula-graph-2.6.1.el7.x86_64 nebula
tar -zxvf nebula-graph-studio-3.2.3.x86_64.tar.gz && mv nebula-graph-studio-3.2.3.x86_64 nebula-graph-studio
  • 复制配置文件
1
2
3
4
cd nebula/etc
cp nebula-graphd.conf.default nebula-graphd.conf
cp nebula-metad.conf.default nebula-metad.conf
cp nebula-storaged.conf.default nebula-storaged.conf

Read More

Nebula-Spark和图算法

Nebula Spark Connector

下载地址&官方文档:【https://github.com/vesoft-inc/nebula-spark-connector

环境

· nebula:2.6.1
· hadoop:2.7
· spark:2.4.7
· pyspark:2.4.7
· python:3.7.16
· nebula-spark-connector:2.6.1

编译打包nebula-spark-connector

1
2
$ cd nebula-spark-connector-2.6.1/nebula-spark-connector
$ mvn clean package -Dmaven.test.skip=true -Dgpg.skip -Dmaven.javadoc.skip=true

成功后在nebula-spark-connector/target/ 目录下得到 nebula-spark-connector-2.6.1.jar文件

1
2
3
4
5
6
7
8
9
10
11
12
(base) [root@root target]# ll
total 106792
drwxr-xr-x 3 root root 17 Mar 11 14:14 classes
-rw-r--r-- 1 root root 1 Mar 11 14:14 classes.-497386701.timestamp
-rw-r--r-- 1 root root 1 Mar 11 14:14 classes.timestamp
-rw-r--r-- 1 root root 30701 Mar 11 14:15 jacoco.exec
drwxr-xr-x 2 root root 28 Mar 11 14:15 maven-archiver
-rw-r--r-- 1 root root 108375457 Mar 11 14:16 nebula-spark-connector-2.6.1.jar
-rw-r--r-- 1 root root 583482 Mar 11 14:16 nebula-spark-connector-2.6.1-javadoc.jar
-rw-r--r-- 1 root root 36358 Mar 11 14:16 nebula-spark-connector-2.6.1-sources.jar
-rw-r--r-- 1 root root 315392 Mar 11 14:15 original-nebula-spark-connector-2.6.1.jar
drwxr-xr-x 4 root root 37 Mar 11 14:15 site

PySpark 读取 NebulaGraph 数据

metaAddress"metad0:9559" 的 Nebula Graph 中读取整个 tag 下的数据为一个 dataframe:

1
2
3
4
5
6
7
8
df = spark.read.format(
"com.vesoft.nebula.connector.NebulaDataSource").option(
"type", "vertex").option(
"spaceName", "basketballplayer").option(
"label", "player").option(
"returnCols", "name,age").option(
"metaAddress", "metad0:9559").option(
"partitionNumber", 1).load()

然后可以像这样 show 这个 dataframe:

1
2
3
4
5
6
7
8
>>> df.show(n=2)
+---------+--------------+---+
|_vertexId| name|age|
+---------+--------------+---+
|player105| Danny Green| 31|
|player109|Tiago Splitter| 34|
+---------+--------------+---+
only showing top 2 rows

Read More

ElasticSearch环境搭建

* 配合nebula全文检索测试环境而搭建的es单机环境

安装

下载地址

https://www.elastic.co/cn/downloads/elasticsearch#ga-release】 (或前往elastic中文社区下载中心【https://elasticsearch.cn/download/】)

  • 选择linux版本

安装ES

  • 解压缩
1
$ tar xf elasticsearch-7.14.2-linux-x86_64.tar.gz
  • 创建es用户
1
$ useradd es && passwd es
  • 更名
1
$ mv elasticsearch-7.14.2 elasticsearch
  • 赋予es用户权限
1
$ chown -R es:es elasticsearch

配置

* 可使用es自带的java环境:ES_JAVA_HOME
1
$ vim /etc/profile
1
2
3
# ES_JAVA_HOME
export ES_JAVA_HOME=/data/elasticsearch/jdk/
export PATH=$ES_JAVA_HOME/bin:$PATH
1
$ source /etc/profile
  • elasticsearch config
1
2
$ cd elasticsearch/config
$ vim elasticsearch.yml
1
2
3
4
5
6
7
8
9
10
11
node.name: node-1                          ##节点名称
path.data: /usr/local/elasticsearch/data ##数据存放路径
path.logs: /usr/local/elasticsearch/logs ##日志存放路径
bootstrap.memory_lock: true ##避免es使用swap交换分区
indices.requests.cache.size: 5% ##缓存配置
indices.queries.cache.size: 10% ##缓存配置
network.host: 192.168.80.128 ##本机IP
http.port: 9200 ##默认端口
cluster.initial_master_nodes: ["node-1"] ##设置符合主节点条件的节点的主机名或 IP 地址来引导启动集群
http.cors.enabled: true ##跨域
http.cors.allow-origin: "*"
  • 将当前用户软硬限制调大
1
$ vim /etc/security/limits.conf
1
2
3
4
es soft nofile 65535
es hard nofile 65537
es soft memlock unlimited
es hard memlock unlimited
  • 修改vm.max_map_count内存
1
vim /etc/sysctl.conf
1
vm.max_map_count=655360
1
sysctl -p

启动

1
2
3
$ su es
$ cd ../bin
$ ./elasticsearch -d

Read More

Spark-SQL

SparkSQL

SparkSQL是spark的一个用于处理海量结构化数据的模块

  • 支持SQL语言
  • 自动优化
  • 性能强
  • 兼容HIVE
  • API流程简单
  • 支持标准化JDBC和ODBC连接

SparkSQL数据抽象

  • Pandas · DataFrame

    · 二维表数据结构

    · 单机(本地)集合

  • SparkCore · RDD

    · 无标准数据结构

    · 分布式(分区)集合

  • SparkSQL · DataFrame

    · 二维表数据结构

    · 分布式(分区)集合

SparkSession对象

RDD程序的执行入口对象:SparkContext

在Spark2.0以后,推出了SparkSession对象,来作为Spark编码的统一入口对象。SparkSession

  • 用于SparkSQL编程,作为入口对象
  • 用于SparkCore编程,通过SparkSession对象获取SparkContext

构建SparkSession对象:

1
2
3
4
5
6
7
from pyspark.sql import SparkSession

# 通过builder方法来构建SparkSession对象
# appName:设置程序名称
# config:配置常用属性
# getOrCreate:完成创建SparkSession对象
spark = SparkSession.builder.appName("test").master("local[*]").config("spark.sql.shuffle.partitions", "4").getOrCreate()

通过SparkSesion对象获取SparkContext对象:

1
2
3
4
5
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("test").master("local[*]").config("spark.sql.shuffle.partitions", "4").getOrCreate()

sc = spark.sparkContext

Read More

Spark-Core

广播变量

本地对象被发送到同个Executor内每个分区的处理线程上使用,这样每个分区实际上存放了重复的数据。而Executor本质上是进程,进程内资源共享,没必要将本地对象分发给所有分区,造成内存浪费

解决方案:将本地对象设置为广播变量

1
2
3
4
5
# 1.将本地对象标记为广播变量
broadcast = sc.broadcast(var)
# 2.使用广播变量,从broadcast对象中取出本地对象
value = broadcast.value
# 当传输的是广播对象时,spark会只给每个Executor分发一份数据

当本地集合对象和分布式集合对象(RDD)进行关联时,需要将本地集合对象封装为广播变量

  • 节省网络IO次数
  • 降低Executor内存占用

累加器

当执行累加操作时,各个分区累加自身的内容

1
2
# spark提供累加器变量,参数是初始值
acmlt = sc.accumulator(0)

e.g.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pyspark import SparkConf, SparkContext

conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)

acmlt = sc.accumulator(0)


def counts(data):
global acmlt
acmlt += 1
return data


rdd1 = sc.parallelize([1, 2, 3], 3)
rdd2 = rdd1.map(counts)
print(rdd2.collect())
print(acmlt)
1
2
[1, 2, 3]
3

:累加器可能因血缘关系导致重复的累加,例如一个RDD被释放后累加已经完成,此时再使用该RDD将会导致重复累加。可通过cache缓存机制来解决

Read More


Powered by Hexo and Hexo-theme-hiker

Copyright © 2017 - 2025 青域 All Rights Reserved.

UV : | PV :