I am using 2 raspberry pi and each of them has a camera connected.
I am trying to run, from the first pi, a script to get the video feed of the second one.
And for that, I would need the value my function returns through ssh.
With a simple example :
slaveScript.py
def run(): return "hello there" if __name__ == '__main__': run()
masterScript.py
import pexpect try: # ssh connection child = pexpect.spawn('ssh -X pi@pislave.local') child.expect('pi@pislave.local's password:', timeout=10) child.sendline('pi') child.expect('$') # run script child.sendline('python3 slaveScript.py run') cap = child.read() # error here print(cap) except pexpect.ExceptionPexpect as e: print(str(e))
I would like, for this example to get “hello there”. How can I get it? Is there a pexpect method I can use?
In context with the cameras :
SlaveScript.py
import cv2 def run(): return cv2.VideoCapture(0) if __name__ == '__main__': run()
MasterScript.py
import pexpect import cv2 try: # ssh connection child = pexpect.spawn('ssh -X pi@pislave.local') child.expect('pi@pislave.local's password:', timeout=10) child.sendline('pi') child.expect('$') # run script to read and show the video feed while True: child.sendline('python3 SlaveScript.py') cap = child.read() ret, frame = cap.read() cv2.imshow('slaveCam', frame) except pexpect.ExceptionPexpect as e: print(str(e))
I know that it works if I put the lines from while True
to cv2.imshow
in the slave script. I have a window opening and a video feed of around 1 image every 3 seconds (I don’t care about performance).
However, the video feed will have to be implemented inside a kivy GUI, so I need to get the frame
in my master script so that I can put it in a texture in kivy.
Is there any way to do it?
Advertisement
Answer
I think you are on the wrong track with pexpect
. You should be using password-less login by copying your public RSA key to the slave device – then you can get rid of all the awkwardness of pexpect
.
Also, I would consider using Redis. It is very fast, and lightweight and it serves integers, strings, lists, sets, hashes from memory (RAM) across a network.
Simply stuff the frames of video in Redis on the slave, either as JPEGs, or PNGs or Numpy arrays and call it latestFrame
. That looks like:
redis.set('latestFrame', frame)
On the other machine, just grab latestFrame
from Redis and display it. That looks like:
frame = redis.get('latestFrame')
Example here.