Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send Video over TCP using OpenCV and sockets in Raspberry Pi

I have been trying to send live video frame from my client (Raspberry Pi) to a server hosted on Laptop. Both these devices are connected to the same network.

Server.py

import socket
import sys
import cv2
import pickle
import numpy as np
import struct

HOST = '192.168.1.3'
PORT = 8083

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

s.bind((HOST, PORT))
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening'

conn, addr = s.accept()

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

while True:
    while len(data) < payload_size:
        data += conn.recv(4096)
    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(4096)
    frame_data = data[:msg_size]
    data = data[msg_size:]

    frame=pickle.loads(frame_data)
    print frame.size
    # cv2.imshow('frame', frame)
    # cv2.waitKey(10)

Client.py

import cv2
import numpy as np
import socket
import sys
import pickle
import struct

cap = cv2.VideoCapture(0)
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('192.168.1.3', 8081))

while True:
    ret,frame = cap.read()
    data = pickle.dumps(frame)
    clientsocket.sendall(struct.pack("L", len(data)) + data)

My server on laptop is not receiving any data. But when I run this client and server on same devices (e.g. server and client on laptop) then it is working properly.

I am able to send data from raspberry to laptop (tested for echo application).

Can anyone help me with this ?

like image 935
Shinchan Avatar asked Apr 08 '16 15:04

Shinchan


2 Answers

Create a file with code below, run server code in Powershell on Windows by running for example python "C:\path\toFile\streamTestServer.py"

Code is:

import socket
import sys
import cv2
import pickle
import numpy as np
import struct

HOST = '127.0.0.1'
PORT = 8083

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

s.bind((HOST, PORT))
print('Socket bind complete')
s.listen(10)
print('Socket now listening')

conn, addr = s.accept()

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

while True:
    while len(data) < payload_size:
        data += conn.recv(4096)
    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(4096)
    frame_data = data[:msg_size]
    data = data[msg_size:]

    frame=pickle.loads(frame_data)
    print(frame.size)
    cv2.imshow('frame', frame)
    cv2.waitKey(10)

Then run client in Python IDLE or in another window of Powershell. Client code is:

import cv2
import numpy as np
import socket
import sys
import pickle
import struct

cap = cv2.VideoCapture(0)
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('127.0.0.1', 8083))

while True:
    ret,frame = cap.read()
    data = pickle.dumps(frame)
    clientsocket.sendall(struct.pack("L", len(data)) + data)

Now you are streaming from localhost client to localhost server.

like image 187
Martin M Avatar answered Nov 07 '22 03:11

Martin M


According to my understanding, you should use the same ports for client and server, but you are using two different ones, 8083 and 8081.

Have you checked that the firewall is opened for the port used?

like image 23
tfv Avatar answered Nov 07 '22 04:11

tfv