6

I am developing a wx application in python for streaming and displaying video from two different webcams. This works fine, but now I need to do this in a different scenario in which the two cameras are connected in separate machine running on Windows connected over a network. My application will run on machine 1. The video from the camera 1 can be fetched using opencv and display on a panel. And also I want to fetch video from camera 2 connected to machine 2, and display it in the application.

Is there any way to do this?

Ashique PS
  • 691
  • 1
  • 12
  • 26

2 Answers2

6

VLC can stream the image of a capture device's over RTSP, see the "Streaming using the GUI" chapter of VLC's "Streaming HowTo".

Then OpenCV's VideoCapture can grab frames from RTSP stream such as:

std::string address = "rtsp://<username:password>@<ip_address>:<port>";
cv::VideoCapture cap;

if(!cap.open(address)) 
{
    std::cout << "Error opening video stream: " << address << std::endl;
    return -1;
}

Where address is something like rtsp://127.0.0.1:554 or rtsp://username:password@127.0.0.1:554 if it is password protected.

Kornel
  • 5,264
  • 2
  • 21
  • 28
  • I tried this. But I am facing a delay of approximately 5sec in streaming. Is there any way to reduce the delay? – Ashique PS Mar 18 '15 at 06:03
  • 2
    Hard to tell, the delay can be the result of the camera's or codec's internal buffer, the caching of VLC or directly the latency of network. Have you activated the transcoding? – Kornel Mar 18 '15 at 08:12
  • I have increased the caching. Now there isn't any noticeable delay. Thanks a lot for your help. – Ashique PS Mar 18 '15 at 08:20
2

I have used websockets to stream data between the two machines. You grab the image in machine 1 and stream it to machine 2 which is listening for connections on a certain port.

Machine 1 (client):

cap=cv2.VideoCapture(0)
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('localhost',8089))

while(cap.isOpened()):
  ret,frame=cap.read()

  memfile = StringIO.StringIO()
  np.save(memfile, frame)
  memfile.seek(0)
  data = json.dumps(memfile.read().decode('latin-1'))

  clientsocket.sendall(struct.pack("L", len(data))+data)
  if cv2.waitKey(1) & 0xFF == ord('q'):
    break

cap.release()

Machine 2 (server thread):

self.isRunning = True

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

s.bind((self.hostname, self.port))
print 'Socket bind complete'

data = ""
payload_size = struct.calcsize("L")

s.listen(10)
print 'Socket now listening'

while self.isRunning:

  conn, addr = s.accept()

  while True:

    data = conn.recv(4096)

    if data:
      packed_msg_size = data[:payload_size]
      data = data[payload_size:]
      msg_size = struct.unpack("L", packed_msg_size)[0]

      while len(data) < msg_size:
        data += conn.recv(10000)

      frame_data = data[:msg_size]

      memfile = StringIO.StringIO()
      memfile.write(json.loads(frame_data).encode('latin-1'))
      memfile.seek(0)
      frame = numpy.load(memfile)

      ret, jpeg = cv2.imencode('.jpg', frame)
      self.jpeg = jpeg

      self.connected = True

    else:
      conn.close()
      self.connected = False
      break

self.connected = False

Note for the the json serializer which greatly increases the performance of the serialization process, specially comparing to pickle, as explained in this awesome article.

Source code can be found here.

renatodamas
  • 16,555
  • 8
  • 30
  • 51
  • While this link may answer the question, link only answers are discouraged on Stack Overflow, you can improve this answer by taking vital parts of the link and putting it into your answer, this makes sure your answer is still an answer if the link gets changed or removed :) – WhatsThePoint Feb 15 '18 at 09:05