From bb148906e7b94a551335e93f9ac4c6ff28204cf6 Mon Sep 17 00:00:00 2001 From: yihong1120 Date: Mon, 20 May 2024 02:07:03 +0800 Subject: [PATCH] Utilise web socket to conduct image frames to frontend --- examples/Stream-Web/app.py | 154 ++++++++++++++-------- examples/Stream-Web/static/css/styles.css | 19 +++ 2 files changed, 115 insertions(+), 58 deletions(-) diff --git a/examples/Stream-Web/app.py b/examples/Stream-Web/app.py index 724ede5..70760d5 100644 --- a/examples/Stream-Web/app.py +++ b/examples/Stream-Web/app.py @@ -1,105 +1,147 @@ import base64 -from tkinter import image_names -from flask import Flask, redirect, render_template, send_from_directory, make_response, Response, request, jsonify, url_for -import subprocess -import threading -import os -import signal -from threading import Timer +from flask import Flask, abort, render_template, make_response, Response from flask_limiter import Limiter from flask_limiter.util import get_remote_address -from pathlib import Path -import json -import uuid -import time import redis -import pickle -import cv2 -import numpy as np +from flask_socketio import SocketIO, emit +from flask_cors import CORS +from typing import List, Tuple # Connect to Redis r = redis.Redis(host='localhost', port=6379, db=0) app = Flask(__name__) +CORS(app) # Allow cross-origin requests from any domain +socketio = SocketIO(app, cors_allowed_origins="*") # Allow all origins for WebSocket connections limiter = Limiter(key_func=get_remote_address) -DETECTED_FRAMES_DIR = Path.cwd() / 'detected_frames' CACHE_DURATION = 60 # Cache duration in seconds -cache = {} + +def get_labels() -> List[str]: + """ + Retrieve and decode all unique labels from Redis keys. + + Returns: + list: Sorted list of unique labels. + """ + cursor, keys = r.scan() + decoded_keys = [key.decode('utf-8') for key in keys] + labels = {key.split('_')[0] for key in decoded_keys if key.count('_') == 1 and not key.startswith('_') and not key.endswith('_')} + return sorted(labels) + +def get_image_data(label: str) -> List[Tuple[str, str]]: + """ + Retrieve and process image data for a specific label. + + Args: + label (str): The label/category of the images. + + Returns: + list: List of tuples containing base64 encoded images and their names. + """ + cursor, keys = r.scan(match=f'{label}_*') + image_data = [(base64.b64encode(r.get(key)).decode('utf-8'), key.decode('utf-8').split('_')[1]) for key in keys] + return sorted(image_data, key=lambda x: x[1]) @app.route('/') -@limiter.limit("60 per minute") # Apply rate limiting to this endpoint +@limiter.limit("60 per minute") def index() -> str: """ - Serves the index page with a dynamically generated list of labels from subdirectories. + Serve the index page with a dynamically generated list of labels from Redis. Returns: str: The rendered 'index.html' page. """ - labels = [d.name for d in DETECTED_FRAMES_DIR.iterdir() if d.is_dir()] - labels.sort() + labels = get_labels() return render_template('index.html', labels=labels) -@app.route('/label/