I'm having a idea of using TCP socket to send array object captured by webcam to a client and reconstruct the image in another program.
Server Side:
import socket
import numpy as np
import cv2
UDP_IP = '192.168.1.3'
UDP_PORT = 8081
cap = cv2.VideoCapture(0)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((UDP_IP,UDP_PORT))
sock.listen(1)
conn,addr=sock.accept()
print(addr)
while(True):
ret, frame = cap.read()
cv2.imshow('streamer',frame)
conn.send(frame.toBytes)
print(frame)
Client side:
import socket
import numpy
import time
import cv2
UDP_IP="192.168.1.3"
UDP_PORT = 8081
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((UDP_IP,UDP_PORT))
while True:
data = sock.recv(480*640*3)
print(data)
my issue is in server side the array is showing up correctly in the console. But in the client side the console is filled with Junk characters.
Why is that.? How should i reconstruct the array same as the server side?
Related
I am using sockets to send video feed bytes from server to client. The video feed is being captured using openCV. But the method I am using right now works for a couple of seconds and stops with error OSError: [WinError 10040] A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself Where did I go wrong and how can I fix it? Thanks in advance.
HOST
import cv2
import socket
import pickle
s_stream = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s_stream.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 10000000)
streamIp = "192.168.3.5"
streamPort = 8787
camera = cv2.VideoCapture(0)
while True:
ret, img = camera.read()
ret, buffer = cv2.imencode(
'.jpg', img, [int(cv2.IMWRITE_JPEG_QUALITY), 30])
x_as_bytes = pickle.dumps(buffer)
s_stream.sendto(x_as_bytes, (streamIp, streamPort))
CLIENT
import cv2, socket, pickle
s_stream=socket.socket(socket.AF_INET , socket.SOCK_DGRAM)
streamIp="192.168.3.5"
streamPort=8787
s_stream.bind((streamIp,streamPort))
while True:
x=s_stream.recvfrom(10000000)
clientip = x[1][0]
data=x[0]
data=pickle.loads(data)
print(data)
I tried to stream a video over Kafka and displaying it in a simple HTTP server, built in Python. regardless the good streaming data, only the first timeframe (or first received timeframe) is served in the HTTP Server.
I have proved that the sent and received timeframes equal to the streamed video (by exporting out the sent and received time frames). my suspicion is that the HTTP Server doesn't automatically refresh or write the received timeframe every new messages are received.
KafkaProducer
import cv2
import io
from PIL import Image
from kafka import KafkaProducer
def recordedVid(video_file):
producer = KafkaProducer(
bootstrap_servers='localhost:9092'
)
cap = cv2.VideoCapture(video_file)
while(cap.isOpened()):
ret, frame = cap.read()
ret, buffer = cv2.imencode('.jpg', frame)
toStream = buffer.tobytes()
producer.send('Video', toStream)
print('sent')
time.sleep(0.1)
cap.release()
print('done')
recordedVid('sample.mp4')
KafkaConsumer
import cv2
import socket
from http.server import HTTPServer, BaseHTTPRequestHandler
from kafka import KafkaConsumer
from PIL import Image
import numpy as np
import io
from ensurepip import bootstrap
def extract_IP():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
HOST = s.getsockname()[0]
return HOST
def msg_process(msg) :
frame_bytes = msg.value
frame_arr = np.frombuffer(frame_bytes, np.uint8)
frame = cv2.imdecode(frame_arr, cv2.IMREAD_COLOR)
img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
toLoad = io.BytesIO()
img.save(toLoad, format='JPEG')
return toLoad.getvalue()
consumer = KafkaConsumer(
"Video",
bootstrap_servers = 'localhost:9092'
)
class Display(BaseHTTPRequestHandler):
def do_GET(self):
for msg in consumer:
frame = msg_process(msg)
self.send_response(200)
self.send_header("Content-type", "image/jpeg")
self.end_headers()
self.wfile.write(frame)
HOST = extract_IP()
PORT = 9999
server = HTTPServer((HOST, PORT), Display)
print("server is now running in ", HOST," and Port ", PORT)
server.serve_forever()
server.server_close()
Did I miss something or is there any workaround for my problem?
I'm trying to build a desktop streaming app. It consists of a server and a client for now. I learned that I should use the library pickle in order to serialize/deserialize the data. However, when I run both the scripts, I get the error "Pickle data was truncated" from the client side. Could you help me to solve this? I tried the solution the following link, whose OP apparently was trying to do the similar think but it didn't work.
python 3.6 socket pickle data was truncated
Server
import numpy as np
import cv2
from PIL import ImageGrab
import socket
import pickle
HOST = "0.0.0.0"
SOCKET = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST,SOCKET))
while True:
s.listen(5)
client, addres = s.accept()
print(addres, " has connected")
img = ImageGrab.grab()
img_np = np.array(img)
img_np_serial = pickle.dumps(img_np)
client.send(img_np_serial)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
Client
import socket
import pickle
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostbyname(socket.gethostname()),5000))
data = b""
while True:
packet = s.recv(4096)
if not packet: break
data += packet
data_deserial = pickle.loads(data)
print((data_deserial))
I'm trying to send multiple images from client to server .
from my client I send one image at a time then for each image I get the size in the server and then send the size back to client and then try and store all the sizes of all images in a table .
I wrote this code and it doesn't seem to work:
client.py:
from PIL import Image
import glob
import sys
import pickle
import socket
import os
import numpy
reload(sys)
def readFileImages(strFolderName):
st = os.path.join(strFolderName, "*.png")
print st
return glob.glob(st)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
client_socket.bind(("127.0.0.1", 4000))
list1=readFileImages("test")
myoutput =[]
while (list1):
for im in list1:
f=open(im,"rb")
while True:
veri = f.read()
if not veri:
break
client_socket.send(veri)
f.close()
data = client_socket.recv(4096)
data_arr=pickle.loads(data)
newrow=numpy.asarray(data_arr)
myoutput=numpy.vstack([myoutput,newrow])
client_socket.close()
numpy.savetxt("testTable.csv",myoutput,delimiter=",")
server.py:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
s.bind(("127.0.0.1",4000))
s.listen(5)
client_socket, address = s.accept()
print "Connected to - ",address,"\n"
fname="test.png"
fp = open(fname,'wb')
# image
while True:
strng = client_socket.recv(1024)
if not strng:
break
fp.write(strng)
fp.close()
#T[0]=detect_carte_grise(fp)
im = Image.open(fp)
T= im.size #width,height
data=pickle.dumps(T)
client_socket.send(data)
and why do i get this error ?:[errno98] address already in use
I cannot even connect to server
First, in server code you bind to port, but in client code, you need to CONNECT to that server. You are binding in both of your scripts and address is already used by the first running script. so in client drop bind and change to client_socket.connect(("127.0.0.1", 4000)). That will resolve current issues, if you have any more, please, ask another question.
I got the same error, I Changed the "port number". It's worked fine
using a library called ImageGrab from PIL folder, i tryed to screenshot the server screen and send it to the customer. I saved the screenshot in a folder but how to send it? and if the image size is too big how do I split it and send it in pieces to the customer?
Server Side:
import socket
from PIL import ImageGrab
server_socket = socket.socket()
server_socket.bind('0.0.0.0', 8820)
server_socket.listen(1)
(client_socket, client_address) = server_socket.accept()
print client_address + ' Have connected to server'
commend = client_socket.recv(1024)
while commend != 'exit':
if commend == 'screenShot':
im = ImageGrab.grab()
im.save(r'C:\screen.jpg')
server_socket.close()
Client Side:
import socket
my_socket = socket.socket()
my_socket.connect('127.0.0.1', 8820)
commend = raw_input('Connected! Enter your commend')
my_socket.send(commend)
my_socket.close()
ty for help