I am trying to send my macbook air webcam video in realtime and receive it using python on another computer. The motivation for this is to be able to offload realtime image recognition tasks to a server. The server requires having access to the realtime video frames in python so that I can then pass the frames to my image recognition algorithm (a deep neural net).
I was able to do this successfully using https://github.com/atuldo/videoStream which uses the socket library to send the video frames in string format. However, this method results is a very low frame rate (see below for code snippet).
Attempt 1:
from flask import Flask, render_template, Response
from camera import VideoCamera
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
def gen(camera):
while True:
frame = camera.get_frame()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
@app.route('/video_feed')
def video_feed():
return Response(gen(VideoCamera()),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
I also used this https://github.com/log0/video_streaming_with_flask_example which uses flask to stream the video to a web page. Looking at the webpage in chrome it has a much better frame rate than my first solution. However, this solution does not receive the video in python and would require me to read the video from the webpage, which I am not exactly sure how to go about.
Attempt 2 (I replaced pygame from original github code with cv2 to be able to access my mac webcam) :
### Server
import socket
from threading import *
import socket
import pygame
import pygame.camera
from pygame.locals import *
import cv2
def server():
#host_name = socket.gethostname()
host_name = 'localhost'
print "\nServer started at " + str(socket.gethostbyname(host_name)) + " at port " + str(90)
#port = 90
port = 1024
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(("",port))
serversocket.listen(10)
#pygame.camera.init()
#cam = pygame.camera.Camera(0,(640,480),"RGB")
#cam.start()
#img = pygame.Surface((640,480))
video = cv2.VideoCapture(0)
while True:
connection, address = serversocket.accept()
print "GOT_CONNECTION"
#cam.get_image(img)
#data = pygame.image.tostring(img,"RGB")
success, image = video.read()
data = cv2.imencode('.jpg', image)[1].tostring()
connection.sendall(data)
connection.close()
server()
###Reciever (snippet, for full code please refer to the github link above)
clientsocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect((self.ipAddress, self.port))
received = []
while True:
recvd_data = clientsocket.recv(230400)
if not recvd_data:
break
else:
received.append(recvd_data)
dataset = ''.join(received)
#image = pygame.image.fromstring(dataset,(640, 480),"RGB") # convert received image from string
nparr = np.fromstring(dataset, np.uint8)
image = cv2.imdecode(nparr, cv2.CV_LOAD_IMAGE_COLOR)
cv2.imwrite('foo.jpg', image)
#pygame.image.save(image, "foo.jpg")
self.ids.image_source.reload()
The video stream is displayed on the webpage like so:
<html>
<head>
<title>Video Streaming Demonstration</title>
</head>
<body>
<h1>Video Streaming Demonstration</h1>
<img id="bg" src="{{ url_for('video_feed') }}">
</body>
</html>
How can I get a high frame rate with either one of the two approaches or is there a better way to go about this?
The reason may be that you VideoCapture
device is not configured for higher framerate or it does not support higher framerate at all.
You specified very low frame rate, I don't know what this means to you, but I tested it with my 2 cameras. With slightly modified code, I can max out the first camera to 15fps, but the second one is running at 25fps without problems. These are expected numbers for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With