python socket pickled numpy data not showing up - python

I'm trying to send python-opencv frames over sockets. I'm pickling the data and unpickling but for some reason it's blank or nothing is showing up.
This is my terminal when I run client.py
new message length: b'720 '
It should be streaming the webcam from server but nothing is showing up.
Here is my code for the client and server:
client.py
import socket
import numpy as np
import cv2
import pickle
HEADERSIZE = 10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1232))
while True:
full_msg = b''
new_msg = True
while True:
msg = s.recv(16)
if new_msg:
print(f'new message length: {msg[:HEADERSIZE]}')
msglen = int(msg[:HEADERSIZE])
new_msg = False
full_msg += msg
if len(full_msg)-HEADERSIZE == msglen:
print('full msg recvd')
print(full_msg[HEADERSIZE:])
d = pickle.loads(full_msg[HEADERSIZE:])
print(d)
cv2.namedWindow('Webcam', cv2.WINDOW_NORMAL)
cv2.imshow('Webcam', full_msg[HEADERSIZE:])
new_msg = True
full_msg = b''
print(full_msg)
server.py
import socket
import numpy as np
import cv2
import time
import pickle
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE, SIG_DFL)
HEADERSIZE = 10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1232))
s.listen(5)
cap = cv2.VideoCapture(0)
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established!")
while True:
ret, frame = cap.read()
msg = pickle.dumps(frame)
print(frame)
msg = bytes(f'{len(frame):<{HEADERSIZE}}', "utf-8") + msg
clientsocket.send(msg)
I have no idea why nothing is showing up. I don't even know if anything is coming though. Does it have to do with numpy data? I heard that can be tricky.

When you stream frames of 720 bytes from server, you are actually sending 730 bytes (length 10 bytes + data 720 bytes) per frame continuously, one frame after another.
In client you are reading 16 bytes per recv(). Hence your condition if len(full_msg)-HEADERSIZE == msglen: will never be true, with header size 10, as 730 is not divisible by 16.
So your program is looping indefinitely on while True: in client.
Try below program for client. I tested with dummy data.
client.py
import socket
import numpy as np
import cv2
import pickle
HEADERSIZE = 10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1232))
while True:
msg_length=int(s.recv(HEADERSIZE))
full_msg=b''
while len(full_msg)<msg_length:
full_msg+=s.recv(msg_length-len(full_msg))
print(full_msg)
d = pickle.loads(full_msg)
cv2.namedWindow('Webcam', cv2.WINDOW_NORMAL)
cv2.imshow('Webcam', full_msg)

Related

Send Thermal Image with mlx90640 via TCP

I have a problem with my program I am trying to send the images I collect from the MLX90640 thanks to the Raspberry to process them in a remote PC.
I am using a Raspberry 4 as a client and the data is routed to a PC. I am using the socket to start the server which is to receive and the images and thermal images. For the images connected to the camera, I took care of it my problem is to transfer the thermal images. I am currently using a wifi connection that I share with my cellphone for the tests.If necessary I will post the server code. But I have this error message I have tried many solutions and I have not found it. In fact, the Raspberry is the client and the PC is the server. So I collect data from the raspberry to transmit it to the PC for processing. I want to detect the temperature of the face and for that the MLX90640 which is connected to the Raspberry must send the thermal data. Knowing that it collects 768 values, so I want these values ​​to be transmitted or the maximum value to be returned to the PC. Can someone help me
import cv2
import io
import socket
import struct
import time
import pickle
import zlib
import adafruit_mlx90640
import board
import busio
import numpy as np
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('192.168.43.134', 8485))
connection = client_socket.makefile('wb')
i2c = busio.I2C(board.SCL, board.SDA, frequency=800000)
mlx = adafruit_mlx90640.MLX90640(i2c)
print("MLX addr detected on I2C")
print([hex(i) for i in mlx.serial_number])
mlx.refresh_rate = adafruit_mlx90640.RefreshRate.REFRESH_4_HZ
frame1 = np.zeros((24*32,))
#max_t=0
#moy = 0
#cam = cv2.VideoCapture(0)
#mlx.set(3, 32);
#mlx.set(4, 24);
img_counter = 0
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
while True:
frame = mlx.getFrame(frame1)
result, frame = cv2.imencode('.jpg', frame, encode_param)
# data = zlib.compress(pickle.dumps(frame, 0))
data = pickle.dumps(frame, 0)
size = len(data)
print("{}: {}".format(img_counter, size))
client_socket.sendall(struct.pack(">L", size) + data)
img_counter += 1
```Traceback (most recent call last): File "client1.py", line 37, in <module> result, frame = cv2.imencode('.jpg', frame, encode_param) cv2.error: OpenCV(4.1.1) /home/pi/opencv/modules/imgcodecs/src/grfmt_base.cpp:145: error: (-10:Unknown error code -10) Raw image encoder error: Empty JPEG image (DNL not supported) in function 'throwOnEror'
Do you manage to get thermal at Raspberry pi? I did a similar approach but i am not using thermal camera. If your problem is not able to transfer image from raspberry pi to your computer
Server code at Raspberry pi
#!/usr/bin/env python3
import os
import datetime
import numpy as np
import cv2
import sys
import socket
import select
import queue
import pickle
import struct
import time
from threading import Thread
class WebcamVideoStream:
def __init__(self, src=0):
self.stream = cv2.VideoCapture(src)
cv2.VideoWriter_fourcc('M','J','P','G')
self.stream .set(cv2.CAP_PROP_BUFFERSIZE,1)
self.stream .set(5, 60)
self.stream .set(3,640)
self.stream .set(4,480)
(self.grabbed, self.frame) = self.stream.read()
self.stopped = False
def start(self):
Thread(target=self.update, args=()).start()
return self
def update(self):
while True:
if self.stopped:
return
(self.grabbed, self.frame) = self.stream.read()
time.sleep(0.1)
def read(self):
img= cv2.cvtColor(self.frame , cv2.COLOR_BGR2GRAY)
data = pickle.dumps(img)
return data
def stop(self):
self.stopped = True
def commandParser(cmd, stream):
reply = ""
if(cmd == "getimage"):
reply = stream.read()
time.sleep(0.1)
else:
reply = '/n'.encode()
return(reply)
if __name__ == '__main__':
camera_idx = 0
for i in range(3):
stream = cv2.VideoCapture(i)
test,frame = stream.read()
stream.release()
if test == True:
camera_idx = i
break
#stream = cv2.VideoCapture(camera_idx)
vs = WebcamVideoStream(src=camera_idx).start()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 8080
server.bind(('192.168.128.14', port))
server.listen(5)
inputs = [server]
outputs = []
message_queues = {}
cmd =""
while inputs:
readable, writable, exceptional = select.select(inputs, outputs, inputs, 1)
for s in readable:
if s is server:
connection, client_address = s.accept()
inputs.append(connection)
message_queues[connection] = queue.Queue(1024)
else:
data = s.recv(4096)
if data:
cmd = data.decode()
message_queues[s].put(commandParser(data.decode(), vs))
if s not in outputs:
outputs.append(s)
else:
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
del message_queues[s]
for s in writable:
try:
next_msg = message_queues[s].get_nowait()
except queue.Empty:
outputs.remove(s)
else:
if(cmd == "getimage"):
size = len(next_msg)
s.sendall(struct.pack(">L", size) + next_msg)
else:
s.send("ABCDEFGHIJKLMNONOOO".encode())
for s in exceptional:
print ('handling exceptional condition for', s.getpeername())
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()
del message_queues[s]
vs.stop()
Client Code at PC
#!/usr/bin/env python3
import os
import datetime
import numpy as np
import cv2
import socket
import socket
import sys
import pickle
import struct ## new
import zlib
import time
server_address = ('192.168.128.14', 8080)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#print ('connecting to %s port %s' % server_address)
s.connect(server_address)
cv2.namedWindow('Streaming')
payload_size = struct.calcsize(">L")
while True:
s.send("getimage".encode())
data = b""
while len(data) < payload_size:
data += s.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 += s.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
frame=pickle.loads(frame_data, fix_imports=True, encoding="bytes")
cv2.imshow('Streaming',frame)
cv2.waitKey(1)
#cv2.imwrite("test.tiff", frame)
s.close()

How to send and recieve a cv2 image in the form of numpy array

I'm an intermediate in python and new to libraries like numpy and opencv. I'm trying to make a video calling app using sockets.This code is just a try. I've tried in the following way but as it receives the array it's size becomes 0 and shape becomes null. Please help me do this. I'm sorry for anymistakes I've done
any help will be appreciated
Thank you. Have a nice day enter
Server:-
import socket
import threading
from _thread import *
import cv2
import numpy as np
srvr = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_ip = socket.gethostbyname(socket.gethostname())
port = 9999
client = []
try:
srvr.bind((server_ip, port))
except socket.error as e:
print(e)
def connected_client(conn, addr):
global client
print("[SERVER]: CONNECTED WITH ", addr)
check_msg = "Welcome Client"
conn.send(str.encode(check_msg))
while True:
try:
data = conn.recv(5000)
if not data:
print("[SERVER]: DISCONNECTED..")
break
for i in client:
i.sendall(data)
except:
break
conn.close()
srvr.listen(5)
while True:
print("[SERVER]: STARTED...\n [SERVER]: ACCEPTING CONNECTIONS....")
conn, addr = srvr.accept()
start_new_thread(connected_client, (conn, addr))
client.append(conn)
Client:-
import socket, cv2
import threading
from _thread import *
import numpy as np
import time
import base64
video = cv2.VideoCapture(0)
clt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SERVER = socket.gethostbyname(socket.gethostname())
PORT = 9999
ADDR = (SERVER, PORT)
clt.connect(ADDR)
print(clt.recv(2048).decode())
#recieving data from server
def recieve():
global clt
while True:
recv_frame = clt.recv(5000)
nparr = np.frombuffer(recv_frame, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
key = cv2.waitKey(1)
if key == ord('a'):
break
print(img)
# cv2.imshow("aman", recv_frame)
# break
# https://stackoverflow.com/questions/17967320/python-opencv-convert-image-to-byte-string
# new thread while to continuously recieve data
start_new_thread(recieve, ())
# loop for continuously sending data
while True:
check, frame = video.read()
str_frame = cv2.imencode('.jpg', frame)[1].tobytes()
clt.sendall(str_frame)
video.release()
cv2.destroyAllWindows()

python video streaming using opencv and web socket

i'm trying to write a python script that streams video to browser using web socket. I'm using opencv as client to send frames via socket and browser script receive and display it on a browser. single image are displayed in browser but issue occurs while streaming video not able to display it on browser. python flask works fine but there are few issues so i have planned use web socket for browser display
client code sends frame to server using opencv and socket
import cv2
import numpy as np
import socket
import sys
import pickle
import struct ### new code
cap=cv2.VideoCapture("test.avi")
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('0.0.0.0',8082))
while True:
ret,frame=cap.read()
data = pickle.dumps(frame) ### new code
clientsocket.sendall(struct.pack("L", len(data))+data)
browser code
import socket #for sockets handling
import time #for time functions
import sys
import cv2
import pickle
import numpy as np
import struct ##
hostIP = '127.0.0.1'
SourcePort = 8082 #client socket
PlayerPort = 8081 #Internet Browser
def gen_headers():
# determine response code
h = ''
h = 'HTTP/1.1 200 OK\n'
# write further headers
current_date = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
h += 'Date: ' + current_date +'\n'
h += 'Content-Type: image/jpeg\n\n'
return h
def start_server():
socketFFMPEG = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# this is for easy starting/killing the app
socketFFMPEG.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print('Socket created')
### new
data = b""
payload_size = struct.calcsize("L")
try:
socketFFMPEG.bind((hostIP, SourcePort))
print('Socket bind complete')
except socket.error as msg:
print('Bind failed. Error : ' + str(sys.exc_info()))
sys.exit()
#Start listening on socketFFMPEG
socketFFMPEG.listen(10)
print('Socket now listening. Waiting for video source from client socket on port', SourcePort)
conn, addr = socketFFMPEG.accept()
ip, port = str(addr[0]), str(addr[1])
print('Accepting connection from ' + ip + ':' + port)
socketPlayer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socketPlayer.bind((hostIP, PlayerPort))
socketPlayer.listen(1) #listen just 1 petition
print('Waiting for Internet Browser')
conn2, addr2 = socketPlayer.accept()
#conn2.sendall(gen_headers().encode())
while True:
try :
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)
#send data to internet browser
print(frame)
ret, frame = cv2.imencode('.jpg', frame)
frames = frame.tobytes()
conn2.sendall( gen_headers().encode()+frames)
except socket.error:
print('Error data :' + str(frame))
print('send Error : ' + str(sys.exc_info()))
conn2.close()
sys.exit()
socketFFMPEG.close()
start_server()
Server.py
# This is server code to send video frames over UDP
import cv2, imutils, socket
import numpy as np
import time
import base64
BUFF_SIZE = 65536
server_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,BUFF_SIZE)
host_name = socket.gethostname()
host_ip = '192.168.1.102'# socket.gethostbyname(host_name)
print(host_ip)
port = 9999
socket_address = (host_ip,port)
server_socket.bind(socket_address)
print('Listening at:',socket_address)
vid = cv2.VideoCapture(0) # replace 'rocket.mp4' with 0 for webcam
fps,st,frames_to_count,cnt = (0,0,20,0)
while True:
msg,client_addr = server_socket.recvfrom(BUFF_SIZE)
print('GOT connection from ',client_addr)
WIDTH=400
while(vid.isOpened()):
_,frame = vid.read()
frame = imutils.resize(frame,width=WIDTH)
encoded,buffer = cv2.imencode('.jpg',frame,[cv2.IMWRITE_JPEG_QUALITY,80])
message = base64.b64encode(buffer)
server_socket.sendto(message,client_addr)
frame = cv2.putText(frame,'FPS: '+str(fps),(10,40),cv2.FONT_HERSHEY_SIMPLEX,0.7,(0,0,255),2)
cv2.imshow('TRANSMITTING VIDEO',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
server_socket.close()
break
if cnt == frames_to_count:
try:
fps = round(frames_to_count/(time.time()-st))
st=time.time()
cnt=0
except:
pass
cnt+=1
Client.py
# This is client code to receive video frames over UDP
import cv2, imutils, socket
import numpy as np
import time
import base64
BUFF_SIZE = 65536
client_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
client_socket.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,BUFF_SIZE)
host_name = socket.gethostname()
host_ip = '192.168.1.102'# socket.gethostbyname(host_name)
print(host_ip)
port = 9999
message = b'Hello'
client_socket.sendto(message,(host_ip,port))
fps,st,frames_to_count,cnt = (0,0,20,0)
while True:
packet,_ = client_socket.recvfrom(BUFF_SIZE)
data = base64.b64decode(packet,' /')
npdata = np.fromstring(data,dtype=np.uint8)
frame = cv2.imdecode(npdata,1)
frame = cv2.putText(frame,'FPS: '+str(fps),(10,40),cv2.FONT_HERSHEY_SIMPLEX,0.7,(0,0,255),2)
cv2.imshow("RECEIVING VIDEO",frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
client_socket.close()
break
if cnt == frames_to_count:
try:
fps = round(frames_to_count/(time.time()-st))
st=time.time()
cnt=0
except:
pass
cnt+=1

i am running a program to send a picture over two sockets and i have got no errors but the program gets stuck

I created a server and a client in python so I could send an image across two sockets but when I run the client it receives the data but once it reaches the end of the file it gets stuck. It raises no error and doesn't crash the terminal is just there stuck.
I have tried changing the code a bit to no avail. I am still a beginner.
client.py
import socket
import cv2
import numpy as np
import pickle
client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client_socket.bind(('127.0.0.1',5000))
host_ip = ('127.0.0.1',400)
client_socket.connect(host_ip)
serialized_img = b""
while True:
packet = client_socket.recv(1024)
if not packet :
break
serialized_img += packet
image = pickle.loads(serialized_img)
cv2.imshow("a",image)
server.py
import socket
import cv2
import numpy as np
import pickle
server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1',400))
cap = cv2.VideoCapture(0)
ret,img = cap.read()
cv2.imshow('image',img)
cv2.waitKey(0)
cap.release()
cv2.destroyAllWindows()
serialized_img = pickle.dumps(img)
print(serialized_img)
while ret:
try:
server_socket.listen()
client_socket,client_address = server_socket.accept()
print(client_address)
client_socket.sendall(serialized_img)
except socket.timeout :
print("time out")
server_socket.close()
I want the client side to be able to show the image.
Close client_socket in server to inform client that it end of data.
client_socket.sendall(serialized_img)
client_socket.close()
In client you have to wait for key to keep window opened.
cv2.imshow("a", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Server:
import socket
import cv2
import pickle
server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('127.0.0.1', 4000))
cap = cv2.VideoCapture(0)
ret, img = cap.read()
cap.release()
cv2.imshow("server", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
serialized_img = pickle.dumps(img)
while ret:
try:
server_socket.listen()
client_socket,client_address = server_socket.accept()
print(client_address)
client_socket.sendall(serialized_img)
client_socket.close()
print('closed')
except socket.timeout :
print("time out")
server_socket.close()
Client:
import socket
import cv2
import pickle
client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client_socket.connect(('127.0.0.1', 4000))
serialized_img = b""
while True:
packet = client_socket.recv(1024)
if not packet :
break
serialized_img += packet
image = pickle.loads(serialized_img)
cv2.imshow("client", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
If you want to send live video then server would have to run separate thread with camera or with while ret. And every client_socket run in separate thread in while True loop. Problem is how to inform client where is end of one frame and beginning of next frame. You couldn't use close() for this.
EDIT: this code streams images from camera so client can see on live - with small delay.
It sends image's size before image so client know how many bytes to receive to get full image. Serialized integer has always 8 bytes so I always receive 8 bytes before image.
I use cv2.waitKey(10) in client to check button not only to close window but it didn't display image without this. Maybe window has to receive events from system to work correctly (and refresh window) like in others modules - ie. PyGame - and waitKey() is checking events.
Server:
import socket
import cv2
import pickle
server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('127.0.0.1', 4000))
cap = cv2.VideoCapture(0)
while True:
try:
server_socket.listen()
print('waiting ...')
client_socket,client_address = server_socket.accept()
print(client_address)
while True:
try:
ret, img = cap.read()
serialized_img = pickle.dumps(img)
print('serialized_len:', len(serialized_img))
serialized_len = pickle.dumps(len(serialized_img))
#print('len(serialized_len):', len(serialized_len)) # always length 8
client_socket.sendall(serialized_len) # always length 8
client_socket.sendall(serialized_img)
except Exception as ex:
print(ex)
# exit loop when errro, ie. when client close connection
break
client_socket.close()
print('closed')
except socket.timeout:
print('time out')
cap.release()
server_socket.close()
Client:
import socket
import cv2
import pickle
client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client_socket.connect(('127.0.0.1', 4000))
cv2.namedWindow('client')
while True:
serialized_image = b""
serialized_len = client_socket.recv(8) # always length 8
length = pickle.loads(serialized_len)
#print('length:', length)
while length > 0:
if length < 1024:
packet = client_socket.recv(length)
else:
packet = client_socket.recv(1024)
if not packet:
print('error: no data')
break
serialized_image += packet
length -= len(packet)
#print('received:', len(serialized_image))
image = pickle.loads(serialized_image)
cv2.imshow('client', image)
# it need it to display image (maybe it has to receive events from system)
# it `waitKey` waits 10ms so it doesn't block loop
key = cv2.waitKey(10) & 0XFF
if key == 27:
break
cv2.destroyAllWindows()

I want to stream a webcam feed using socket programming in Python

This is my code:
server.py:
#The server receives the data
import socket
from PIL import Image
import pygame,sys
import pygame.camera
from pygame.locals import *
import time
host = "localhost"
port = 1890
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
conn, addr = s.accept()
print "connected by",addr
screen = pygame.display.set_mode((640,480))
while 1:
data = conn.recv(921637)
image = pygame.image.fromstring(data,(640,480),"RGB")
screen.blit(image,(0,0))
pygame.display.update()
if not image:
break;
conn.send(data)
conn.close()
client.py
#The client sends the data
import socket
from PIL import Image
import pygame,sys
import pygame.camera
from pygame.locals import *
import time
host = "localhost"
port = 1890
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(640,480))
cam.start()
while 1:
image = cam.get_image()
data = pygame.image.tostring(image,"RGB")
s.sendall(data)
s.close()
print "recieved", repr(data)
Just to test, I tried the following code and it's working fine, but the above does not...
Working code when implemeted without sockets: camcapture.py
import sys
import time
import pygame
import pygame.camera
from pygame.locals import *
pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(640,480))
cam.start()
screen = pygame.display.set_mode((640,480))
while 1:
image = cam.get_image()
data = pygame.image.tostring(image,"RGB")
img = pygame.image.fromstring(data,(640,480),"RGB")
screen.blit(img,(0,0))
pygame.display.update()
The error is:
image = pygame.image.fromstring(data,(640,480),"RGB")
ValueError: String length does not equal format and resolution size
Where did I go wrong?
The problem is not the camera.
The problem is that you send a very large string over the socket and you incorrectly assume that you can read the entire string at once with conn.recv(921637).
You'll have to call recv multiple times to receive all over your data. Try printing the length of data you send in client.py and print the length of data in server.py before calling pygame.image.fromstring and you'll see.
There are several ways to solve this:
make a new connection for each image you send
send the size of your data so the server knows how much data to read
use some kind of end marker
Here's a simple example:
sender:
import socket
import pygame
import time
host = "localhost"
port = 1890
pygame.init()
image = pygame.surface.Surface((640, 480))
i=0
j=0
while 1:
image.fill((i,j,0))
i+=10
j+=5
if i >= 255: i = 0
if j >= 255: j = 0
data = pygame.image.tostring(image,"RGB")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.sendall(data)
s.close()
time.sleep(0.5)
receiver:
import socket
import pygame
host="localhost"
port=1890
screen = pygame.display.set_mode((640,480))
while 1:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
conn, addr = s.accept()
message = []
while True:
d = conn.recv(1024*1024)
if not d: break
else: message.append(d)
data = ''.join(message)
image = pygame.image.fromstring(data,(640,480),"RGB")
screen.blit(image,(0,0))
pygame.display.update()

Categories