I am trying to receive data from my python script using Processes (IPC). Is it some sort of method for reading dictionaries in Unity from python ??? i am using Processes because speed is critical in my situation. Ideally i would like to send an image from unity and get results based on that from python. Thank you in advance
Unity code:
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 script:
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)