Python学习笔记(九)

本文介绍了一种在不依赖云端服务的情况下,利用Python和PaddlePaddle库进行人像抠图的方法。作者详细列举了在安装和运行过程中可能遇到的问题,包括Python版本限制、配置文件错误和模块版本选择,并提供了Unity集成的示例代码,展示了如何在Unity中调用Python脚本进行图像处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*

最近接个小活,甲方想做一个互动程序,需要把人像抠出来。我查了一圈资料,有阿里腾讯百度的云平台都提供这样的接口,不过都需要联网才能使用,没法满足我的实际需求。虽然有离线部署的选项,但是应该不是我这样的个人能申请到的。

然后,我发现paddle上面有个这样的功能。

注:文章参考自(2条消息) Python实现自动人像抠图(小白也能学会)_赏月亮晒月光的博客-优快云博客_python 人像抠图https://blog.youkuaiyun.com/sinat_24354307/article/details/105802524

*/

Python部分

import paddle
import paddlehub as hub
from PIL import Image, ImageSequence
import numpy as np
import os

input_path =    'humanseg_input\\' 
out_path   =    'output\\'


paddle.enable_static()

module = hub.Module(name="deeplabv3p_xception65_humanseg")

while True :
    print("input")
    files = input()
    strs = files.split('|')
    img_path =  [input_path + img for img in strs]
    input_dict = {"image": img_path,'output_dir':out_path}
    results = module.segmentation(data=input_dict)

这里面安装的时候需要注意几个点

1、python3.10是跑不了的,有几个依赖再安装时会报错

2、我用3.9的python跑,发现import paddlehub时会报一个json解析的错误,经过排查,发现是在解析一个config.json文件时,文件里的内容是空的,经百度,解决如下:找到用户文件夹/.paddlehub/conf/config.json,把如下内容写入文件。

{
    "server_url": [
        "http://paddlepaddle.org.cn/paddlehub"
    ],
    "resource_storage_server_url": "https://bj.bcebos.com/paddlehub-data/",
    "debug": false,
    "log_level": "DEBUG"
}

3.模块deeplabv3p_xception65_humanseg如果用最新的,返回的数据结构会不一样,需指定版本。用到关键组件和版本如下:

pip install  PaddlePaddle
pip install paddlehub==1.6.0
hub install deeplabv3p_xception65_humanseg==1.0.0

 Unity 部分

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using UnityEngine;

public class LocalImageHandler : MonoBehaviour
{
    //python文件所在的目录
    private string pythonCmdDir = @"C:\Users\HuMingHao\Desktop\HumanSeg抠图\";
    private string humanseg_input = "humanseg_input";
    private string humanseg_output = "humanseg_output";

    //系统cmd控制台路径
    private string CmdPath = @"C:\Windows\System32\cmd.exe";

    private string startCmd = "python humanseg.py";


    private void RunCmd()
    {
        process = new Process();
        process.StartInfo.StandardOutputEncoding = Encoding.GetEncoding("gb2312");
        process.StartInfo.FileName = CmdPath;
        process.StartInfo.UseShellExecute = false;        
        process.StartInfo.RedirectStandardInput = true;   
        process.StartInfo.RedirectStandardOutput = true;  
        process.StartInfo.RedirectStandardError = true;   
        process.StartInfo.CreateNoWindow = true;          
        process.StartInfo.WorkingDirectory = pythonCmdDir;
        process.Start();//启动程序

        //向cmd窗口写入命令
        process.StandardInput.WriteLine(startCmd);

        while (true)
        {
            //获取cmd窗口的输出信息
            string output = process.StandardOutput.ReadLine();

            if (output == "input")
                READY = true;
            Thread.Sleep(500);
        }

    }
    private void OnDestroy()
    {
        if (cmdThread != null)
        {
            cmdThread.Abort();
        }
        if (process != null && process.HasExited == false)
        {
            process.Close();
        }
    }

    Process process;
    Thread cmdThread;

    public static LocalImageHandler instance;

    public bool READY = false;
    private void Awake()
    {
        instance = this;

        READY = false;
        cmdThread = new Thread(new ThreadStart(RunCmd));
        cmdThread.Start();


    }

    public void BeginHumanSeg(Texture2D tex,Action<Texture2D> callback)
    {
        if (READY == true)
        {
            READY = false;

            StartCoroutine(HumanSegCor(tex,callback));
        }
    }
    IEnumerator HumanSegCor(Texture2D tex,Action<Texture2D> callback)
    {
        string tempFileName = DateTime.Now.Ticks + ".png";
        byte[] imgdata = tex.EncodeToPNG();
        File.WriteAllBytes(pythonCmdDir + humanseg_input + "\\" + tempFileName, imgdata);

        process.StandardInput.WriteLine(tempFileName);

        while (!READY)
        {
            yield return new WaitForEndOfFrame();
        }

        byte[] outdata = File.ReadAllBytes(pythonCmdDir + humanseg_output + "\\" + tempFileName);
        Texture2D handledTex = new Texture2D(128, 128);
        handledTex.LoadImage(outdata);

        callback(handledTex);
    }
}

测试代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class test : MonoBehaviour {
    public Texture2D source;
    public RawImage imgTarget;

    private void OnGUI()
    {
        if (GUILayout.Button("handle image"))
        {
            LocalImageHandler.instance.BeginHumanSeg(source, (tex) =>
            {
                imgTarget.texture = tex;
            });
        }
    }
}

效果

在ROS 2中,将点云数据转换二维栅格地图通常需要借助于相关的传感器建图库,如`map_server`和`nav2_map_common`等工具。以下是基本步骤: 1. **获取点云数据**:首先,你需要从激光雷达或其他三维感知设备收集实时的点云数据。这通常通过`sensor_msgs/LaserScan`或`sensor_msgs/PointCloud2`消息来完成。 2. **点云处理**:使用像`rviz`这样的可视化工具,或者编写专门的节点来清理、滤波和组织点云,去除无效数据并将其转换为易于分析的数据结构。 3. **转换到栅格地图**:利用ROS包`nav2_map_common`中的函数,特别是`tf2_ros::Buffer`和`grid_map_2d_ros`,可以将点云转换二维栅格地图。例如,你可以创建一个`GridMap`实例,并设置其分辨率和范围,然后将点云投影到这个网格上。 ```cpp #include <grid_map_ros/GridMapRosConverter.h> GridMap grid_map; ros::NodeHandle nh; tf2_ros::Buffer tf_buffer; // 确定网格大小和坐标系变换 grid_map.setResolution(resolution); tf::Transform transform = ...; // 获取从激光雷达到世界坐标系的转换 grid_map_ros::transformPointCloud(grid_map, laser_scan_msg, transform, grid_map); ``` 4. **保存和显示**:最后,你可以将生成的栅格地图发布到`grid_map_msgs/msg/GridMap`话题上,以便其他系统消费或用`rviz`等工具查看。 5. **注意事项**:栅格地图的构建可能会消耗大量内存和计算资源,因此优化设置(如调整分辨率、帧率)至关重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值