轻量级人像分割深度学习模型PP-HumanSeg树莓派部署

2023-11-14

人像分割是图像分割领域的高频应用,PaddleSeg推出在大规模人像数据上训练的人像分割系列模型PP-HumanSeg,包括超轻量级模型PP-HumanSeg-Lite,满足在服务端、移动端、Web端多种使用场景的需求。本项目将PP-HumanSeg-Lite模型转为onnx并部署到树莓派,实现人像抠图效果。效果如下图所示(这里只露个半脸):

目录

一、介绍

          硬件

 软件

二、具体流程

1、克隆PaddleSeg仓库

2、安装paddleseg

3、下载预训练模型

4、导出静态图模型

5、ONNX转换

6、移动模型的路径

7、预测代码

三、树莓派运行

四、问题解答

五、参考链接


一、介绍

本项目将PaddleSeg的轻量级人像分割模型转换为onnx,将其部署到树莓派实现实时人像分割。树莓派环境如下:

硬件:

树莓派4B/4G
摄像头一个

 软件

Ubuntu Desktop 21.10
onnxruntime
opencv-python

二、具体流程

1、克隆PaddleSeg仓库

%cd ~/
!git clone https://gitee.com/PaddlePaddle/PaddleSeg.git

2、安装paddleseg

!pip install paddleseg

3、下载预训练模型

%cd ~/PaddleSeg/contrib/PP-HumanSeg
!python pretrained_model/download_pretrained_model.py

4、导出静态图模型

导出静态图模型的时候,需要加上input_shape参数,本项目部署的模型是PP-HumanSeg-Lite,该模型的输入图片大小是192x192,如果要部署其他模型,需要更改model_path和config路径。

(为什么导出静态图模型?答:paddlepaddle在训练时可以使用动态图模型很方便的完成模型组网,完成训练模型的任务,但是动态图预测速度比静态图差,为了加快推理速度,可以将动态图转换为静态图。)

%cd ~/PaddleSeg/contrib/PP-HumanSeg
!python ../../export.py \
--config configs/fcn_hrnetw18_small_v1_humanseg_192x192_mini_supervisely.yml \
--model_path pretrained_model/fcn_hrnetw18_small_v1_humanseg_192x192/model.pdparams \
--save_dir export_model/fcn_hrnetw18_small_v1_humanseg_192x192 \
 --with_softmax  --input_shape 1 3 192 192

5、ONNX转换

将paddlepaddle静态图模型转换为onnx,方便后续的树莓派部署。

# ① 安装paddle2onnx
!pip install paddle2onnx 
# ② 转换为onnx
%cd ~/PaddleSeg/contrib/PP-HumanSeg
! paddle2onnx --model_dir ./export_model/fcn_hrnetw18_small_v1_humanseg_192x192/ \
    --model_filename model.pdmodel \
    --params_filename model.pdiparams \
    --save_file onnx_model/model.onnx \
    --opset_version 12

6、移动模型的路径

为了部署到树莓派,仅保留必要的文件,创建pp_humanseg_deploy文件夹,模型路径是~/pp_humanseg_deploy,文件夹目录结构如下:
|-onnx_model
|---model.onnx
|-predict.py   ---- 这个文件下一步生成

%cd ~/
!mkdir pp_humanseg_deploy
%cd ~/pp_humanseg_deploy/
!mkdir onnx_model
!cp ~/PaddleSeg/contrib/PP-HumanSeg/onnx_model/model.onnx ~/pp_humanseg_deploy/onnx_model

7、预测代码

按照上一步的目录结构,创建predict.py文件,将以下代码放入其中。

下方代码包含预处理和模型预测2个部分,其中预处理部分需要和PaddleSeg的预处理相同。

import cv2
import numpy as np
import onnxruntime as rt


def normalize(im, mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]):
    im = im.astype(np.float32, copy=False) / 255.0
    im -= mean
    im /= std
    return im


def resize(im, target_size=608, interp=cv2.INTER_LINEAR):
    if isinstance(target_size, list) or isinstance(target_size, tuple):
        w = target_size[0]
        h = target_size[1]
    else:
        w = target_size
        h = target_size
    im = cv2.resize(im, (w, h), interpolation=interp)
    return im


def preprocess(image, target_size=(192, 192)):
    image = normalize(image)
    image = resize(image, target_size=target_size)
    image = np.transpose(image, [2, 0, 1])
    image = image[None, :, :, :]
    return image


def display_masked_image(mask, image, color_map=[255, 0, 0], weight=0.6):
    mask = mask > 0
    c1 = np.zeros(shape=mask.shape, dtype='uint8')
    c2 = np.zeros(shape=mask.shape, dtype='uint8')
    c3 = np.zeros(shape=mask.shape, dtype='uint8')
    pseudo_img = np.dstack((c1, c2, c3))
    for i in range(3):
        pseudo_img[:, :, i][mask] = color_map[i]
    vis_result = cv2.addWeighted(image, weight, pseudo_img, 1 - weight, 0)
    return vis_result


onnx_model_path = 'onnx_model/model.onnx'
sess = rt.InferenceSession(onnx_model_path)
input_name = sess.get_inputs()[0].name
label_name = sess.get_outputs()[0].name

target_size = (192, 192)

cap_video = cv2.VideoCapture(0)
if not cap_video.isOpened():
    raise IOError("Error opening video stream or file.")

while cap_video.isOpened():
    ret, raw_frame = cap_video.read()
    pre_shape = raw_frame.shape[0:2][::-1]
    if ret:
        frame = cv2.cvtColor(raw_frame, cv2.COLOR_BGRA2RGB)
        frame = preprocess(frame, target_size)
        pred = sess.run(
            [label_name],
            {input_name: frame.astype(np.float32)}
        )[0]
        pred = pred[0]
        raw_frame = resize(raw_frame, target_size)
        image = display_masked_image(pred, raw_frame)
        image = resize(image, target_size=pre_shape)
        cv2.imshow('HumanSegmentation', image)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
cap_video.release()

三、树莓派运行

将~/pp_humanseg_deploy文件夹打包,放入树莓派环境运行predict.py,效果如下:

 四、问题解答

1、为什么图片看起来很模糊?

这里使用的模型是pp-humanseg-lite,该模型的输入像素是192x192,在树莓派部署 时,先将480x640的图片resize到192x192送入模型预测,再将预测结果resize到480x640,所以图片看起来模糊。

2、为什么转换为onnx?

也可以在树莓派安装paddlepaddle环境,然后使用paddlepaddle来实现推理功能。此处转换为onnx是考虑到个人的树莓派内存有限,并未安装过多的包。

3、如何训练自己的人像分割模型?

参考PaddleSeg

五、参考链接

onnx模型导出AiStudio参考链接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

轻量级人像分割深度学习模型PP-HumanSeg树莓派部署 的相关文章

随机推荐

  • Opencv之Unsharp Mask(USM)锐化

    1 介绍 USM技术是通过增强图像的高频部分的内容来提高视觉效果 用具体的公式表达即为 y n m x n m z n m 其中 x n m 为输入图像 y n m 为输出图像 而z n m 为校正信号 一般是通过对x进行高通滤波获取 是用
  • Shader入门指南

    Unity3D Shader入门指南 一 分类 Unity3d2014 04 28 17 40 16人阅读 评论 0 收藏 举报 unity3dShader3d渲染 目录 本文转载自 http onevcat com 2013 07 sha
  • 25岁竟要求产品经验10年?我一直以为是个段子,没想到居然是真的

    你是不是以为工作3年要求有10年工作经验是个段子 今天告诉你这是真事儿 25岁要求工作经验10年 你好歹给人家工作5年的机会吧 这样也好说剩下的5年工作经验靠加班 HR这样说我没法接啊 哈哈 按照对方逻辑来 毕竟25岁都没有 相关工作经验最
  • TCP拥塞控制原理

    一 拥塞控制的一般原理 1 产生拥塞的原因 在某段时间 若对网络中某一资源的需求超过了该资源所能提供的可用部分 网络的性能就会变坏 即对资源的需求 可用资源 注意拥塞控制与流量控制的区别 拥塞控制是防止过多的数据注入网络中 使得网络中路由器
  • CentOS7平台命令安装Anaconda3、配置Python3开发环境

    要在 CentOS 7 上安装 Anaconda3 您可以按照以下步骤进行操作 1 下载 Anaconda3 安装包 首先 访问 Anaconda 官方网站以获取最新版本的 Anaconda3 安装包的下载链接 可以使用 wget 命令来下
  • 【数据库原理及应用教程(第4版

    文章目录 一 选择题 二 填空题 三 简答题 Reference 一 选择题 1 2 3 4 5 6 7 8 9 10 B C B D A 1 在 SQL Server 中不是对象的是 A 用户 B 数据 C 表 D 数据类型 2 声明了变
  • studio和solo哪个好_beats studio3 和solo3的区别再哪里?

    首先两款机子在外观上就有很大的区别 前者是solo3 后者是studio3 仔细观察可以发现solo3的耳罩比较小 是圆形的 studio3的是椭圆形的 两款都是头戴式 外观设计 录音师是包耳的 SOLO是压耳的 体积的话 录音师大 SOL
  • async与await

    async await 是ES7提出的基于Promise的解决异步的最终方案 一 async async是一个加在函数前的修饰符 被async定义的函数会默认返回一个Promise对象resolve的值 因此对async函数可以直接then
  • UI 自动化测试框架:PO 模式+数据驱动 【详解版】

    目录 1 PO 设计模式简介 什么是 PO 模式 PO 模式的优点 2 工程结构简介 工程结构 框架特点 3 工程代码示例 page 包 action 包 business process 包 util 包 conf 包 1 PO 设计模式
  • 基于Centos 7虚拟机的磁盘操作(添加磁盘、分区、格式分区、挂载)

    目录 一 添加硬盘 二 查看新磁盘 三 磁盘分区 3 1新建分区 3 2 格式分区 3 3 挂载分区 3 4 永久挂载新分区 3 5 取消挂载分区 一 添加硬盘 1 在虚拟机处选择编辑虚拟机设置 然后选择添加 2 选择硬盘 然后选择下一步
  • 敏捷宣言以及敏捷开发的特点

    敏捷宣言 敏捷宣言 也叫做敏捷软件开发宣言 正式宣布了对四种核心价值和十二条原则 可以指导迭代的以人为中心的软件开发方法 敏捷宣言强调的敏捷软件开发的四个核心价值是 个体和互动高于流程和工具 工作的软件高于详尽的文档 客户合作高于合同谈判
  • Go_流程、跳转控制语详解

    流程控制语句分类 流程控制语句可以控制代码的执行顺序和条件 顺序结构 普通的代码 由上而下依次执行 分支结构 if switch 循环结构 for if语句 条件表达式值必须是bool类型 不可省略括号 且左大括号不能另起一行 格式1 if
  • AI绘图Midjourney手把手教程

    以下是使用Midjourney AI绘画程序的注册和入门指南 Midjourney是一款功能强大的绘图软件 通过输入一段图片的文字描述即可生成精美的绘画 我们将为您提供详细的操作步骤 让您轻松上手 下面是使用Midjourney AI绘画程
  • Android绘制笔记——Color、Shader

    Android 颜色Color 1 颜色 1 十六进制ARGB颜色值表示 Int color 0xFFFF0000 红色 2 Color类常量 本质为十六进制表示 Int color Color RED 红色 ColorInt public
  • ffmpeg-android dlopen failed: library “libclang_rt.ubsan_standalone-aarch64-android.so“ not found

    NDK编译的ffmpeg 库 在android上使用 提示动态库错误 15 08 54 276 18357 18357 E AndroidRuntime java lang UnsatisfiedLinkError dlopen faile
  • 报时机器人的rasa shell执行流程分析

    本文以报时机器人为载体 介绍了报时机器人的对话能力范围 配置文件功能和训练和运行命令 重点介绍了rasa shell命令启动后的程序执行过程 一 报时机器人项目结构 1 对话能力范围 1 能够识别欢迎语意图 greet 和拜拜意图 good
  • Linux 或者 Docker 容器通过 date 设置系统时间

    目录 1 Linux 2 Docker 容器 2 1 进入容器内部修改 2 2 可能会遇到的问题 1 Linux 要在Linux系统中设置日期和时间 可以使用date命令 使用以下命令格式来设置日期和时间 sudo date s YYYY
  • kubernetes二进制单节点和多节点部署(多节点+dashbord)

    kubernetes二进制单节点和多节点部署 多节点 dashbord kubernetes单节点部署 环境准备 在 master01 节点上操作 上传 master zip 和 k8s cert sh 到 opt k8s 目录中 解压 m
  • YOLOv5 Focus C3 各模块详解及代码实现

    目录 yolov5s yaml yolov5s yaml基本参数含义 一些基本参数 BackBone Head Focus 一 Focus模块的作用 Focus的参数量 Yolov3和Yolov5的改进对比 关于Focus的补充 网络结构图
  • 轻量级人像分割深度学习模型PP-HumanSeg树莓派部署

    人像分割是图像分割领域的高频应用 PaddleSeg推出在大规模人像数据上训练的人像分割系列模型PP HumanSeg 包括超轻量级模型PP HumanSeg Lite 满足在服务端 移动端 Web端多种使用场景的需求 本项目将PP Hum