| import gradio as gr |
| import numpy as np |
| import cv2 |
| from norfair import Detection, Tracker, Video |
| from detector.utils import detect_plates, detect_chars, imcrop, send_request, draw_text |
| from threading import Thread |
|
|
| DISTANCE_THRESHOLD_BBOX: float = 0.7 |
| DISTANCE_THRESHOLD_CENTROID: int = 30 |
| MAX_DISTANCE: int = 10000 |
|
|
|
|
| def yolo_to_norfair(yolo_detections): |
| norfair_detections = [] |
| detections_as_xyxy = yolo_detections.xyxy[0] |
| for detection_as_xyxy in detections_as_xyxy: |
| bbox = np.array( |
| [ |
| [detection_as_xyxy[0].item(), detection_as_xyxy[1].item()], |
| [detection_as_xyxy[2].item(), detection_as_xyxy[3].item()], |
| ] |
| ) |
| scores = np.array( |
| [detection_as_xyxy[4].item(), detection_as_xyxy[4].item()] |
| ) |
| norfair_detections.append( |
| Detection( |
| points=bbox, scores=scores, label=int(detection_as_xyxy[-1].item()) |
| ) |
| ) |
| return norfair_detections |
|
|
|
|
| def fn_image(foto): |
| plates_text = [] |
| plates = detect_plates(foto) |
| records = plates.pandas().xyxy[0].to_dict(orient='records') |
| if records: |
| for plate in records: |
| xi, yi, xf, yf = int(plate['xmin']), int(plate['ymin']), int(plate['xmax']), int(plate['ymax']) |
| crop = imcrop(foto, (xi, yi, xf, yf)) |
| if len(crop) > 0: |
| cv2.rectangle(foto, (xi, yi), (xf, yf), (0, 255, 0), 2) |
| text = detect_chars(crop) |
| draw_text(foto, text, (xi, yi)) |
| plates_text.append(text) |
| return foto, plates_text |
|
|
|
|
| def fn_video(video, initial_time, duration): |
| tracker = Tracker( |
| distance_function="iou_opt", |
| distance_threshold=DISTANCE_THRESHOLD_BBOX, |
| ) |
| cap = cv2.VideoCapture(video) |
| fps = cap.get(cv2.CAP_PROP_FPS) |
| image_size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))) |
| final_video = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*'VP90'), fps, image_size) |
| num_frames = 0 |
| min_frame = int(initial_time * fps) |
| max_frame = int((initial_time + duration) * fps) |
| plates = {} |
| while cap.isOpened(): |
| try: |
| ret, frame = cap.read() |
| gpu_frame = cv2.cuda_GpuMat() |
| gpu_frame.upload(frame) |
| if not ret: |
| break |
| frame_copy = frame.copy() |
| except Exception as e: |
| print(e) |
| continue |
| if num_frames < min_frame: |
| num_frames += 1 |
| continue |
| yolo_detections = detect_plates(gpu_frame) |
| detections = yolo_to_norfair(yolo_detections) |
| tracked_objects = tracker.update(detections=detections) |
| for obj in tracked_objects: |
| if obj.last_detection is not None: |
| bbox = obj.last_detection.points |
| bbox = int(bbox[0][0]), int(bbox[0][1]), int(bbox[1][0]), int(bbox[1][1]) |
| if obj.id not in plates.keys(): |
| crop = imcrop(gpu_frame, bbox) |
| text = detect_chars(crop) |
| plates[obj.id] = text |
| thread = Thread(target=send_request, args=(frame_copy, text, bbox)) |
| thread.start() |
|
|
| cv2.rectangle( |
| gpu_frame, |
| (bbox[0], bbox[1]), |
| (bbox[2], bbox[3]), |
| (0, 255, 0), |
| 2, |
| ) |
| draw_text(gpu_frame, plates[obj.id], (bbox[0], bbox[1])) |
| cv2.putText( |
| gpu_frame, |
| plates[obj.id], |
| (bbox[0], bbox[1]), |
| cv2.FONT_HERSHEY_SIMPLEX, |
| 1, |
| (0, 255, 0), |
| 2, |
| ) |
| final_video.write(gpu_frame) |
| num_frames += 1 |
| if num_frames == max_frame: |
| break |
| cap.release() |
| final_video.release() |
| return 'output.mp4', [plates[k] for k in plates.keys()] |
|
|
|
|
| image_interface = gr.Interface( |
| fn=fn_image, |
| inputs="image", |
| outputs=["image", "text"], |
| title="Buscar números de placa en una imagen", |
| allow_flagging=False, |
| allow_screenshot=False, |
| ) |
|
|
| video_interface = gr.Interface( |
| fn=fn_video, |
| inputs=[ |
| gr.Video(type="file", label="Video"), |
| gr.Slider(0, 600, value=0, label="Tiempo inicial en segundos", step=1), |
| gr.Slider(0, 10, value=4, label="Duración en segundos", step=1), |
| ], |
| outputs=["video", "text"], |
| title="Buscar números de placa en un video", |
| allow_flagging=False, |
| allow_screenshot=False, |
| ) |
|
|
| webcam_interface = gr.Interface( |
| fn_image, |
| inputs=[ |
| gr.Image(source='webcam', streaming=True), |
| ], |
| outputs=gr.Image(type="file"), |
| live=True, |
| title="Buscar placa con la cámara", |
| allow_flagging=False, |
| allow_screenshot=False, |
| ) |
|
|
| if __name__ == "__main__": |
| gr.TabbedInterface( |
| [image_interface, video_interface], |
| ["Fotos", "Videos"], |
| ).launch() |
|
|