Computer Vision

Video streaming with Flask and OpenCV

Trong bài viết này chúng ta sẽ tìm hiểu về Video Streaming với giao thức HTTP sau khi đã tiến hành xử lý hình ảnh với OpenCV.

Trong bài viết này chúng ta sẽ sử dụng OpenCV 3.


FLASK WEB FRAMEWORK

Để đơn giản chúng ta sẽ sử dụng Flask để tạo một Webserver, từ đó có thể stream dữ liệu hình ảnh.

Để cài đặt Flask ta sử dụng pip:

pip install Flask

hoặc pip3 install Flask

Bây giờ chúng ta sẽ test Flask với một ví dụ đơn giản

Example 1 – Hello World!

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello, dudes. This is codelungtung.com!"

app.run(host="localhost", debug=False, threaded=True)

Kết quả:

localhost

Figure 1 – Demo with Flash

Ở dòng 2, chúng ta tạo một Flask instance có tên là app.

Ở dòng 4, câu lệnh @app.route(“/”) sẽ tạo một đường dẫn được liên kết với function hello(). Mỗi khi chúng ta truy cập vào địa chỉ localhost:5000/ thì function hello() được thực thi.

Ở dòng 8, chúng ta tiến hành chạy server với dòng lệnh app.run() .

app.run(host=”address”, port=5000, debug=False, threaded=True)

Trong đó:

  • host: địa chỉ của server, có thể là localhost hoặc một địa chỉ IP cụ thể;
  • port: mặc định là 5000, chúng ta có thể đổi thành một port bất kỳ;
  • debug: cho phép hiển thị ra màn hình các thông tin của server đang chạy;
  • threaded: cho phép truy cập vào server từ nhiều client.

VIDEO STREAMING WITH FLASH

Để capture hình ảnh từ webcam, chúng ta sử dụng OpenCV và thư viện imutils của Adrian Rosebrock:

pip install imutils

Vì Streaming Server sẽ chạy như một blocking process , do đó chúng ta cần tạo một thread riêng để capture và xử lý hình ảnh từ Webcam.

Cùng tìm hiểu rõ hơn qua example 2 nào.

Example 2 – Streaming Server

import cv2
import numpy as np
from imutils.video import WebcamVideoStream
from flask import Flask, Response
from threading import Thread

class FaceDetector:
	def __init__(self):
		self.faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

	def detect(self, image, scaleFactor=1.05, minNeighbors=6, minSize=(30,30)):
		rects = self.faceCascade.detectMultiScale(image, scaleFactor=scaleFactor, minNeighbors=minNeighbors, minSize=minSize, flags=cv2.CASCADE_SCALE_IMAGE)
		return rects

def ImageProcessing():
	global frameClone
	while True:
		frame = camera.read()

		gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

		faces = fd.detect(gray, scaleFactor=1.2, minNeighbors=5, minSize=(30,30))
		frameClone = frame.copy()
		count = 0
		for (x,y,w,h) in faces:
			count += 1
			cv2.rectangle(frameClone, (x,y), (x+w,y+h), (0,255,0), 2)
			cv2.putText(frameClone, "Face [{}]".format(count), (x, y-15), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2, cv2.LINE_AA)

def getFrame():
	while True:
		ret, frame = cv2.imencode('.jpg', frameClone)
		yield (b'--frame\r\n'
			   b'Content-Type: image/jpeg\r\n\r\n'+frame.tobytes()+b'\r\n\r\n')	

app = Flask(__name__)

@app.route('/')
def hello():
	return "Hello guys"

@app.route('/stream')
def videostream():
	return Response(getFrame(), mimetype='multipart/x-mixed-replace; boundary=frame')

camera = WebcamVideoStream(src=0).start()
fd = FaceDetector()

Thread(target=ImageProcessing, args=()).start()
app.run(host='localhost', debug=False, threaded=True)

Nếu đã đọc qua các bài viết trước của mình thì chắc chắn các bạn đều đã quen thuộc với đa số các câu lệnh này.

Trong ví dụ này mình sử dụng Response object để phản hồi yêu cầu từ client. Khi client truy cập vào localhost:5000/stream thì fuction videostream() được thực thi. Fuction này trả về một Response instance. Response instance này sẽ thực thi function getFrame() để lấy dữ liệu hình ảnh cùng với mimetype=’multipart/x-mixed-replace; boundary=frame’.

Trong function getFrame(), chúng ta sẽ mã hóa hình ảnh nhận được từ Webcam về định dạng JPG và chuyển thành dạng bytes để gửi cho Client.

Sau khi chạy đoạn code trên, các bạn mở Browser và truy cập vào địa chỉ localhost:5000/stream, nếu mọi thứ đều ngon lành thì các bạn sẽ thấy hình ảnh từ webcam đang được stream lên web.

Cảm ơn các bạn đã theo dõi bài viết.

Thân ái và quyết thắng.

Reference:
[1] Flask API.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s