我正在开发 ANPR,它可以检测车牌、捕获图像、从中提取文本,并将其与数据库进行比较。
在此,我想在网页上显示视频流和检测到的图像。视频流完成。但在从车辆中检测到图像后,我无法同时将检测到的图像上传到网络。
这是我的代码
from flask import Flask, render_template, Response
import cv2
import os
from ultralytics import YOLO
from addons import read_license_plate
import mysql.connector
app = Flask(__name__)
# Establish MySQL connection
mysql_connection = mysql.connector.connect(
host="localhost",
user="root",
password="",
database="number_plate"
)
def compare_with_database(license_plate_text):
cursor = mysql_connection.cursor()
query = "SELECT license_plate, owner FROM plates WHERE license_plate = %s"
cursor.execute(query, (license_plate_text,))
result = cursor.fetchone()
cursor.close()
if result:
return result[1]
else:
return None
output_directory = 'captured_images'
os.makedirs(output_directory, exist_ok=True)
yolo = YOLO('./models/license_plate_detector.pt')
video_path = 'sample.mp4'
cap = cv2.VideoCapture(video_path)
box_x1 = 0
box_y1 = 1700
box_x2 = 3835
box_y2 = 1800
@app.route('/')
def index():
return render_template('index.html')
def generate_frames():
image_captured = False
image_counter = 1
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# cv2.rectangle(frame, (box_x1, box_y1), (box_x2, box_y2), (0, 255, 0), thickness=2)
results = yolo(frame, verbose=False)
detected_boxes = results[0].boxes.xyxy
objects_inside_box = False
for box in detected_boxes:
center_x = (box[0] + box[2]) / 2
center_y = (box[1] + box[3]) / 2
if box_x1 < center_x < box_x2 and box_y1 < center_y < box_y2:
objects_inside_box = True
if not image_captured:
object_frame = frame[int(box[1]):int(box[3]), int(box[0]):int(box[2])]
object_frame_gray = cv2.cvtColor(object_frame, cv2.COLOR_BGR2GRAY)
_, object_frame_thresh = cv2.threshold(object_frame_gray, 55, 255, cv2.THRESH_BINARY)
image_filename = os.path.join(output_directory, f"captured_object_{image_counter}.jpg")
cv2.imwrite(image_filename, object_frame)
license_plate_text, confidence_score = read_license_plate(object_frame_thresh)
if license_plate_text:
owner = compare_with_database(license_plate_text)
if owner:
print("License Plate:", license_plate_text, "Owner:", owner)
else:
print(license_plate_text, "Fake Number Plate Detected")
image_counter += 1
image_captured = True
break # Exit the loop after capturing the image
if not objects_inside_box:
image_captured = False
_, frame = cv2.imencode('.jpg', frame)
frame_bytes = frame.tobytes()
yield (b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
@app.route('/video_feed')
def video_feed():
return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>License Plate Recognition</title>
</head>
<style>
img{
width: 960px;
height: 540px;
}
.row{
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
<body>
<div class="container">
<div class="row">
<div class="col">
<h3 class="mt-5">Live Streaming</h3>
<img src="{{ url_for('video_feed') }}" >
</div>
<div class="col2">
<h3 class="mt-5">Captured Object</h3>
<img id="object_frame" >
</div>
<div class="col2">
</div>
</div>
</div>
</body>
</html>
尝试实现异步代码 -> “好处是您可以在视图中运行异步代码,例如进行多个并发数据库查询、对外部 API 的 HTTP 请求等。但是,您的应用程序可以处理的请求数量某一时刻会保持不变” https://flask.palletsprojects.com/en/3.0.x/async-await/