I have a raspberry pi and usb webcam. I will take an image from the USB webcam I connected to the Raspberry Pi and send this image to my computer. My computer will perform a few operations on this image and send the resulting data back to the Raspberry. The program will repeat these steps as long as it runs (infinite loop). Raspberry pi sends data, but the length of the data the computer receives and the data sent by the raspberry pi are not the same. How can I solve this problem
Server.py :
import socket
import cv2
import io
from PIL import Image
import numpy as np
import struct
def encode_image(frame):
stream = io.BytesIO()
frame = cv2.resize(frame, (640, 480))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = Image.fromarray(frame)
frame.save(stream, format="JPEG")
stream.seek(0)
return stream
def decode_image(image_bytes):
stream = io.BytesIO(image_bytes)
return cv2.cvtColor(np.array(Image.open(stream)), cv2.COLOR_RGB2BGR)
server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 8000))
server_socket.listen(0)
c, addr = server_socket.accept()
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
x = encode_image(frame).read()
print(len(x))
print(x)
c.send(struct.pack('<L', len(x)))
c.send(x)
data = c.recv(1024)
if data == "q":
break
print(data.decode('utf-8'))
c.close()
server_socket.close()
Client.py :
import socket
import cv2
import io
from PIL import Image
import numpy as np
import struct
cl_socket = socket.socket()
cl_socket.connect(('192.168.1.108', 8000))
def encode_image(frame):
stream = io.BytesIO()
frame = cv2.resize(frame, (640, 480))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = Image.fromarray(frame)
frame.save(stream, format="JPEG")
return stream.getvalue()
def decode_image(image_bytes):
stream = io.BytesIO(image_bytes)
return cv2.cvtColor(np.array(Image.open(stream)), cv2.COLOR_RGB2BGR)
while True:
image_len = struct.unpack('<L', cl_socket.recv(struct.calcsize('<L')))[0]
print(image_len)
if not image_len:
break
image_bytes = io.BytesIO()
image_bytes.write(cl_socket.recv(image_len))
image_bytes.seek(0)
print(image_bytes.getvalue())
image_bytes.seek(0)
x = decode_image(image_bytes.read())
cv2.imshow('frame', x)
cv2.waitKey(1)
cl_socket.close()
You should consider using a loop to receive all the data since it may not be received in a single call to 'recv'.
Also, when sending data from the client to the server, you need to encode the string before sending and decode it after receiving.
Server.py:
import socket
import cv2
import io
from PIL import Image
import numpy as np
import struct
def encode_image(frame):
stream = io.BytesIO()
frame = cv2.resize(frame, (640, 480))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = Image.fromarray(frame)
frame.save(stream, format="JPEG")
stream.seek(0)
return stream.read()
def decode_image(image_bytes):
stream = io.BytesIO(image_bytes)
return cv2.cvtColor(np.array(Image.open(stream)), cv2.COLOR_RGB2BGR)
server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 8000))
server_socket.listen(0)
c, addr = server_socket.accept()
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
x = encode_image(frame)
image_len = struct.pack('<L', len(x))
c.sendall(image_len)
c.sendall(x)
data = c.recv(1024)
if data.decode('utf-8') == "q":
break
c.close()
server_socket.close()
Client.py:
import socket
import cv2
import io
from PIL import Image
import numpy as np
import struct
cl_socket = socket.socket()
cl_socket.connect(('192.168.1.108', 8000))
def encode_image(frame):
stream = io.BytesIO()
frame = cv2.resize(frame, (640, 480))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = Image.fromarray(frame)
frame.save(stream, format="JPEG")
return stream.getvalue()
def decode_image(image_bytes):
stream = io.BytesIO(image_bytes)
return cv2.cvtColor(np.array(Image.open(stream)), cv2.COLOR_RGB2BGR)
while True:
image_len = struct.unpack('<L', cl_socket.recv(struct.calcsize('<L')))[0]
if not image_len:
break
image_data = b''
while len(image_data) < image_len:
to_read = min(image_len - len(image_data), 4096)
image_data += cl_socket.recv(to_read)
x = decode_image(image_data)
cv2.imshow('frame', x)
cv2.waitKey(1)
message = input("Enter 'q' to quit: ")
cl_socket.sendall(message.encode('utf-8'))
cl_socket.close()