进程间通信 Unity3d python

Posted

技术标签:

【中文标题】进程间通信 Unity3d python【英文标题】:Interprocess communication Unity3d python 【发布时间】:2020-07-19 16:20:10 【问题描述】:

我正在尝试使用进程 (IPC) 从我的 python 脚本接收数据。是从 python 中读取 Unity 字典的某种方法吗?我正在使用流程,因为速度在我的情况下至关重要。 理想情况下,我想从统一发送图像并根据 python 获得结果。提前谢谢你

统一代码:

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

public class Main : MonoBehaviour

   // Start is called before the first frame update
  void Start()

    Console.WriteLine("Execute python process...");
    Option1_ExecProcess();


// Update is called once per frame
void Update()

    


static void Option1_ExecProcess()

    // 1) Create Process Info
    var psi = new ProcessStartInfo();
    psi.FileName = @"python.exe";

    // 2) Provide script and arguments
    var script = @"pyScript.py";


    psi.Arguments = $"\"script\"";

    // 3) Process configuration
    psi.UseShellExecute = false;
    psi.CreateNoWindow = true;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;

    // 4) Execute process and get output
    var errors = "";
    var results = "";

    using (var process = Process.Start(psi))
    
        errors = process.StandardError.ReadToEnd();
        results = process.StandardOutput.ReadToEnd();
    

Python 脚本:

import logging
import math
import time
import traceback
import numpy as np
import io
from numpy import asarray, expand_dims
import tensorflow as tf
from tensorflow import keras
import base64
from tensorflow.python.keras.utils  import data_utils
import os

def closestDivisors(num):
n = math.floor(math.sqrt(num))
for i in range(n, 0, -1):
    if (num) % i == 0:
        res = [i, (num)//i]
        break
return res

def fixed_length_str(i):
return '%02d' % i

layers_indices = []
data = 

def init():
image_model = tf.keras.applications.VGG16(include_top=True,
                                          weights='imagenet', pooling='avg')
for index, layer in enumerate(image_model.layers):
    if 'fc' in layer.name:
        layers_indices.append(index)
    if 'dense'  in layer.name:
        layers_indices.append(index)
    if 'conv' in layer.name:
        layers_indices.append(index)
    if 'predictions' in layer.name:
        layers_indices.append(index)
outputs = [image_model.layers[i].output for i in layers_indices]
image_model = tf.keras.Model(inputs=image_model.inputs, outputs=outputs)
return image_model, layers_indices

def return_data(image_model,layers_indices):
   try:
        img = tf.keras.preprocessing.image.load_img('p4.png', target_size=(224, 224))
        img = tf.keras.preprocessing.image.img_to_array(img)  # convert to tensor
        img = expand_dims(img, axis=0)

        feature_maps = image_model.predict(img)
        layer_counter = -1
        for fmap in feature_maps:  # of each layer
            feature_map = 
            layer_counter = layer_counter + 1
            ix = 1
            layer_name = image_model.layers[layers_indices[layer_counter]].name
            if 'conv' in layer_name:
                x, z = closestDivisors(
                    image_model.layers[layers_indices[layer_counter]].output_shape[3])

                for i in range(x):
                    for j in range(z):
                        imageArray = fmap[0, :, :, ix-1]  # images  ndarray ix-1
                        imageArray = imageArray - imageArray.min()
                        if imageArray.max() != 0:
                            imageArray = imageArray/imageArray.max() * 255.0
                        imageArray = imageArray.astype(np.uint8)
                        var_name_conv = 'fmap__'.format(
                            layer_name, fixed_length_str(i) +""+ fixed_length_str(j))
                        feature_map[var_name_conv] = imageArray.tolist()
                        ix += 1
            elif 'fc' in layer_name:
                x, z = closestDivisors(
                    image_model.layers[layers_indices[layer_counter]].output_shape[1])
                fmap = fmap - fmap.min()
                if fmap.max() != 0:
                    fmap = fmap/fmap.max() * 255.0
                fmap = fmap.astype(np.uint8)
                var_name_fc = 'fmap_'.format(
                    layer_name)
                feature_map[var_name_fc] = fmap.tolist()
            elif 'predictions' in layer_name:
                x, z = closestDivisors(
                    image_model.layers[layers_indices[layer_counter]].output_shape[1])
                fmap = fmap - fmap.min()
                if fmap.max() != 0:
                    fmap = fmap/fmap.max() * 255.0
                fmap = fmap.astype(np.uint8)
                var_name_pred = 'fmap_'.format(layer_name) #, fixed_length_str(x), fixed_length_str(z)
                feature_map[var_name_pred] = fmap.tolist()
            data[str(image_model.layers[layers_indices[layer_counter]].name)] = feature_map
        return data
   except:
        pass


def __init__(self):
  model, layers = init()
  return return_data(model, layers)

【问题讨论】:

您可以将它们编码为 JSON 或结构 你能举个例子吗? :) 【参考方案1】:

有很多方法可以通过输入流发送数据。标准输出,就像互联网只是一种将字节从一个进程发送到另一个进程的方式。有很多方法可以通过数据流发送诸如字典之类的内容。

一种是 JSON,在 Internet 上很常见。它是一种基于文本的格式。这意味着在流上发送信息需要更多的数据,并且编码和解码也会更慢。但是,使用它要容易得多。 Python 包含json 模块,用于轻松转换为json。

如果你发现json可以提供的速度太慢,你可以设计一个costum-byte打包数据格式。这种格式可以更加紧凑,因为您不需要包含键的名称,并且可以使用固定长度的数字而不是十进制表示。由于数据已经是本机数据格式,因此打包和解包也会快得多。 python 中的struct 模块允许您将基本原语(整数、字符串)转换为结构表示,但是您需要自己组合它们来编码完整的字典。

哪个选项最好由您决定。还有很多其他方法可以做到这一点,如果您想获得更多灵感,请查看数据传输协议。

【讨论】:

以上是关于进程间通信 Unity3d python的主要内容,如果未能解决你的问题,请参考以下文章

Python并发编程—进程间通信

python基础 多进程 进程间通信 multiprocess

Python进程间通信进程池协程

python基础之进程间通信进程池协程

Python开发基础--- 进程间通信进程池协程

python进程间通信