0

I am trying to start a javascript subprocess inside a python script.

I'd like to do some photo analysis, by using the Human repo, which doesn't have any Python porting (natively js), so I must execute his detect function in javascript

The general idea is to start a Python code to take a picture from webcam (this is a project's constraint) and then process the photo inside the js script.

(the best thing would be not to save the photo but to directly pass it to the js script, which I tried by frame_json = json.dumps(frame.tolist()) and then process.communicate(input=frame_json) but it didn't work anyway)

This is my python code:

import cv2
import json
import subprocess
import asyncio

def capture():
    video_capture = cv2.VideoCapture(0)

    while True:
        # Grab a single frame of video
        ret, frame = video_capture.read()

        if not ret:
            break         
        #cv2.imwrite('photo1.png', frame)
        try:
            
            js_command = ['node', 'detect.js']
            process = subprocess.Popen(js_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
            output, output2 = process.communicate(input='photo1.png')
            
            print(f'h_res: {output}')
            return output.strip()
            
        except Exception as e:
            print(e)
            return None

capture()

whereas this is the javascript:

const tf = require('@tensorflow/tfjs-node'); 
const Human = require('@vladmandic/human').default; // points to @vladmandic/human/dist/human.node.js
const fs = require('fs');

process.stdin.setEncoding('utf-8');

const config = {
    modelBasePath: 'file://HumanNPM/node_modules/@vladmandic/human/models',
    body: { enabled: true, modelPath: 'file://node_modules/@vladmandic/human/models/models.json' },
};

function newFunction(inputFile) {
    
    const human = new Human(config);
    const buffer = fs.readFileSync(inputFile); // read file content into a binary buffer
    const tensor = human.tf.node.decodeImage(buffer); // decode jpg/png data to raw pixels

    
    res = human.detect(tensor, config).then((result) => {
        
        process.stdout.write(result);
        
        console.log(result)
        return result;
    });
    

    return res
}


process.stdin.on('data', function (data) {
    newFunction(data)
});


process.stdin.on('end', function () {
    process.exit();
});

The problem is that it seems like the Human library doesn't execute, since I don't see anything in my python output. Obviously if I comment the Human section out and console.log('something') from the js, I am able to see it in my Python console.

I can't figure out if is there something out that I'm missing.

Is there any concurrency problem? Or is there any chance that I'm using the library wrong in some way? (the library still works fine if used by itself without being used as subprocess, with node detect.js).

May someone give me an help?

1 Answer 1

0

EDIT: Eventually I managed to resolve my issue:

Python code:

import cv2
import json
import asyncio

async def run_js_script(data):
# Launch the subprocess
   proc = await asyncio.create_subprocess_exec('node', 'detect3.js', 
   stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE)

# Send the data to the subprocess and get output

   output, _ = await proc.communicate(input=data.encode())

   return output.decode().strip()


async def main():
    video_capture = cv2.VideoCapture(0)

    while True:
       # Grab a single frame of video
       ret, frame = video_capture.read()

       if not ret:
           break

       frame_json = json.dumps(frame.tolist())

       try:
           result = await run_js_script(frame_json)
           print(f'Result from JavaScript: {result}')
      except Exception as e:
           print(f'Error: {e}')

   

asyncio.run(main())

Javascript code:

const human = new Human(config);

async function processImage(data) {

   const frame1 = JSON.parse(data);
   
   const tensor = human.tf.tensor(frame1); 
   const result = await human.detect(tensor);

   return result["face"][0]["age"];
}

// Read input from stdin
process.stdin.on('data', async (data) => {
   const result = await processImage(data);

   process.stdout.write(JSON.stringify(result));
   process.stdout.end();
  });

The main issue was that the Python process was not waiting for Js to finish, so I made that async, forcing it to wait.

Regarding the image processing, I decided to use a json as a bridge between these two codes, and using the tensor as human input, as its wiki suggests for some specific instances.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.