J'essaie d'utiliser Flask pour afficher un flux d'images OpenCV. J'utilise ROS et la caméra stéréo Zed.
Le problème est que le serveur flask ne montre qu'une icône d'image cassée. Je suppose que le problème est dans la méthode gen () parce que cv2.imwrite ('t.jpg', img) est la mauvaise façon de procéder. J'ai très peu d'expérience avec OpenCV.
Les données d'image que le serveur Flask reçoit est un InputArray. J'ai besoin d'un moyen de le convertir et d'afficher l'image dans le serveur Flask.
J'utilise Python 2.7 et rospy (ROS).
Aucun conseil?
MISE À JOUR:
Le code du nœud ROS accédant à la came ZED:
#!/usr/bin/env python
# ROS imports
import rospy
from sensor_msgs.msg import Image
# Utils
import numpy as np
import cv2
from cv_bridge import CvBridge, CvBridgeError
import stream
def callback(data):
"""
param data: data from zed/rgb/image_rect_color topic
"""
# convert from ROS sensor_msgs/Image to cv2
bridge = CvBridge()
try:
cv_img = bridge.imgmsg_to_cv2(data, desired_encoding='passthrough')
stream.img = cv_img
except CvBridgeError as e:
print(e)
# show image stream
# cv2.imshow('zed', cv_img)
# cv2.waitKey(3)
def zed_sub():
# initialize ROS node 'zed_sub'
rospy.init_node('zed_sub')
# subscribe to the ROS topic 'zed/rgb/image_rect_color'
rospy.Subscriber('zed/rgb/image_rect_color', Image, callback)
# keep python from exiting until this node is stopped
try:
rospy.spin()
except KeyboardInterrupt:
cv2.destroyAllWindows()
if __name__ == '__main__':
zed_sub()
Le code du serveur Flask:
#!/usr/bin/env python
from flask import Flask, render_template, Response
import cv2
app = Flask(__name__)
Host = '192.168.1.3' # on-board computer's IP address
PORT = 8080
img = None
@app.route('/')
def index():
return render_template('index.html')
@app.route('/video_feed')
def video_feed():
return Response(gen(), mimetype='multipart/x-mixed-replace; boundary=frame')
def gen():
"""Video streaming generator function."""
global img
while True:
try:
cv2.imwrite('t.jpg', img)
yield(b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + open('t.jpg', 'rb').read() + b'\r\n')
except NameError as e:
print(e)
if __name__ == '__main__':
app.run(Host=HOST, port=PORT, debug=True, threaded=True)
pour accéder à une caméra autre que la webcam de votre ordinateur portable, vous pouvez utiliser un lien RTSP comme celui-ci rtsp: // admin: [email protected]: 554/h264/ch1/main/av_stream "
où
> username:admin > password:12345 > your camera ip address and port > ch1 is first camera on that DVR
remplacez cv2.VideoCamera (0) par ce lien comme celui-ci pour votre appareil photo et cela fonctionnera
camera.py
import cv2
class VideoCamera(object):
def __init__(self):
# Using OpenCV to capture from device 0. If you have trouble capturing
# from a webcam, comment the line below out and use a video file
# instead.
self.video = cv2.VideoCapture(0)
# If you decide to use video.mp4, you must have this file in the folder
# as the main.py.
# self.video = cv2.VideoCapture('video.mp4')
def __del__(self):
self.video.release()
def get_frame(self):
success, image = self.video.read()
# We are using Motion JPEG, but OpenCV defaults to capture raw images,
# so we must encode it into JPEG in order to correctly display the
# video stream.
ret, jpeg = cv2.imencode('.jpg', image)
return jpeg.tobytes()
main.py
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)
alors vous pouvez suivre ce blog pour augmenter votre FPS
https://www.pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/