【发布时间】:2019-11-15 10:14:15
【问题描述】:
我有这段代码将 Nodejs 连接到 Python 脚本。该脚本包含带有 Tensor 流后端等的 ML 模型......,它基本上给出了一个字符串输出。我从节点 js via.child process spawn 将图像 URL 发送到 python,并将其识别的表达式作为字符串返回。基本上我正在做面部识别,用python编码,但通过Node js调用并将字符串作为JSON数据(Rest API)发送到响应。
我面临的问题是,每当我调用 spawn 时,它都会运行 python 的整个代码,并且如果我们从顶部开始并最终给出输出,python 脚本必须加载所有模块。
这是python代码
from gtts import gTTS
language = 'en'
#myobj = gTTS(text='Do you know the person? Yes or No', lang=language, slow=True)
#myobj.save("question1.mp3")
#myobj = gTTS(text='What is his or her name', lang=language, slow=True)
#myobj.save("question2.mp3")
import csv
import pandas as pd
import numpy as np
#with open('database.csv','w') as f:
# writer=csv.writer(f)
# writer.writerow(['Chinmay',embedded])
face_embeddings=np.array(pd.read_csv('database.csv',header=None))
face_names=np.array(pd.read_csv('database_names.csv',header=None))
from cv2 import cv2
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from align import AlignDlib
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import torch
import torch.nn as nn
import torch.nn.functional as F
import os
from torch.autograd import Variable
from model import create_model
import transforms as transforms
from skimage import io
from skimage.transform import resize
from models import *
import matplotlib.pyplot as plt
from keras.models import load_model
from keras.preprocessing.image import load_img, img_to_array
from util.model import CNNModel, generate_caption_beam_search
import os
from config import config
from pickle import load
import sys
cut_size = 44
transform_test = transforms.Compose([
transforms.TenCrop(cut_size),
transforms.Lambda(lambda crops: torch.stack([transforms.ToTensor()(crop) for crop in crops])),
])
class_names = ['Angry', 'Disgust', 'Fear', 'Happy', 'Sad', 'Surprise', 'Neutral']
final_text=''
nn4_small2_pretrained = create_model()
nn4_small2_pretrained.load_weights('weights/nn4.small2.v1.h5')
def rgb2gray(rgb):
return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
def load_image(path):
img = cv2.imread(path, 1)
# OpenCV loads images with color channels
# in BGR order. So we need to reverse them
return img[...,::-1]
def extract_features(filename, model, model_type):
if model_type == 'inceptionv3':
from keras.applications.inception_v3 import preprocess_input
target_size = (299, 299)
elif model_type == 'vgg16':
from keras.applications.vgg16 import preprocess_input
target_size = (224, 224)
# Loading and resizing image
image = load_img(filename, target_size=target_size)
# Convert the image pixels to a numpy array
image = img_to_array(image)
# Reshape data for the model
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
# Prepare the image for the CNN Model model
image = preprocess_input(image)
# Pass image into model to get encoded features
features = model.predict(image, verbose=0)
return features
def getrecogstr( imgurl ):
# Path of Image
#image_file=imgurl
image_file = sys.argv[1]
# Initialize the OpenFace face alignment utility
alignment = AlignDlib('models/landmarks.dat')
# Load an image
jc_orig = load_image(image_file)
# Detect face and return bounding box -
bb = alignment.getAllFaceBoundingBoxes(jc_orig)
net = VGG('VGG19')
checkpoint = torch.load(os.path.join('FER2013_VGG19', 'PrivateTest_model.t7'),map_location='cpu')
net.load_state_dict(checkpoint['net'])
# Load the tokenizer
tokenizer_path = config['tokenizer_path']
tokenizer = load(open(tokenizer_path, 'rb'))
# Max sequence length (from training)
max_length = config['max_length']
caption_model = load_model('model.hdf5')
image_model = CNNModel(config['model_type'])
for i in bb:
# Transform image using specified face landmark indices and crop image to 96x96
jc_aligned = alignment.align(96, jc_orig, i, landmarkIndices=AlignDlib.OUTER_EYES_AND_NOSE)
location=(i.height()+i.width())/(jc_orig.shape[0]+jc_orig.shape[1])
# Finding the emotion of cropped image
gray = rgb2gray(jc_aligned)
gray = resize(gray, (48,48), mode='symmetric').astype(np.uint8)
img = gray[:, :, np.newaxis]
img = np.concatenate((img, img, img), axis=2)
img = Image.fromarray(img)
inputs = transform_test(img)
#net.cuda()
net.eval()
ncrops, c, h, w = np.shape(inputs)
inputs = inputs.view(-1, c, h, w)
#inputs = inputs.cuda()
inputs = Variable(inputs, volatile=True)
outputs = net(inputs)
outputs_avg = outputs.view(ncrops, -1).mean(0) # avg over crops
score = F.softmax(outputs_avg)
_, predicted = torch.max(outputs_avg.data, 0)
# Find the name of the person in the image
jc_aligned = (jc_aligned / 255.).astype(np.float32)
embeddings = nn4_small2_pretrained.predict(np.expand_dims(jc_aligned, axis=0))[0]
print("@@")
print(embeddings)
matched_embeddings=1000
for j in range(len(face_embeddings)):
temp=np.sum(np.square(embeddings-face_embeddings[j]))
if (temp<=0.56 and temp <matched_embeddings):
matched_embeddings=np.sum(np.square(embeddings-face_embeddings[j]))
face_index=j
print(temp)
print('above')
if matched_embeddings!=1000:
face_name=face_names[face_index][0]
print("@@known")
else:
face_name='Unknown'
print("@@unknown")
#print("Unknown Person detected. Do you know this person yes or no ?")
#Play welcome1.mp3
#Play welcome2.mp3 if input is yes
final_text+= face_name+' expression is '+class_names[int(predicted.cpu().numpy())] + "."
print("@@"+final_text)
sys.stdout.flush()
getrecogstr()
这是节点代码
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const port = 1000;
const spawn = require("child_process").spawn;
app.use(bodyParser.json()); // application/json
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
});
app.get('/test', (req, res, next) => {
const imgurl = req.query.imgurl;
var process = spawn('python', ["./final.py",
imgurl,
]);
process.stdout.on('data', function (data) {
const recog_str = data.toString().split('@@')[3];
console.log(recog_str);
res.json(recog_str)
})
})
server.listen(port, () => {
console.log("Ok");
})
我只想跳过每次加载模块的那部分。我知道我们必须运行模块才能让它们进入内存,但这需要很长时间。可以像 python 脚本一直运行一样,我们可以在运行过程中从节点 js 发送参数并调用可以返回该字符串的函数?
【问题讨论】:
-
你的问题是你的python代码在你运行你的python代码的时候运行?
-
如果你想重复运行 python,但又不想重复启动成本,你需要实现某种形式的 Python 守护进程或服务器,将请求转发到。
-
不,我不想从一开始就运行整个 python 代码我只想调用函数 getrecogstrI() 需要加载所有模块并且需要时间来加载(比如 10秒左右)。
-
所以,是的,您需要实现一个 python 守护程序或服务器来公开该功能。
-
我们如何做到这一点?一些代码有帮助
标签: javascript python node.js tensorflow spawn