APIMONSTER commited on
Commit
4c90346
Β·
verified Β·
1 Parent(s): 4edb0a2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -22
app.py CHANGED
@@ -7,22 +7,26 @@ import gradio as gr
7
  from ultralytics import YOLO
8
  from paddleocr import PaddleOCR
9
 
10
- # 1) Load models
11
  yolo = YOLO("models/best.pt")
12
- ocr = PaddleOCR(
13
- text_detection_model_dir=None,
14
- text_recognition_model_dir="models/ocr_model",
15
- use_textline_orientation=False,
16
- lang="en"
 
 
 
 
17
  )
18
 
19
- # 2) Turkish plate formatter
20
  def format_turkish_plate(s: str) -> str:
21
  s = re.sub(r'[^A-Z0-9]', '', s.upper())
22
  m = re.match(r'^(\d{2})([A-Z]{1,3})(\d{2,4})$', s)
23
  return f"{m.group(1)} {m.group(2)} {m.group(3)}" if m else "Unknown"
24
 
25
- # 3) Single‐image inference
26
  def run_image(img, conf=0.25):
27
  bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
28
  res = yolo(bgr, conf=conf)[0]
@@ -32,10 +36,12 @@ def run_image(img, conf=0.25):
32
  res.boxes.conf.cpu().numpy()):
33
  x1,y1,x2,y2 = box.astype(int)
34
  crop = out[y1:y2, x1:x2]
35
- if crop.size==0: continue
 
36
 
37
  plate_img = cv2.resize(crop, (128,32))
38
- recs = ocr.ocr(plate_img, cls=False)
 
39
 
40
  if recs and recs[0]:
41
  _, (raw, ocr_score) = recs[0]
@@ -51,7 +57,7 @@ def run_image(img, conf=0.25):
51
 
52
  return cv2.cvtColor(out, cv2.COLOR_BGR2RGB), f"{len(res.boxes)} plate(s) detected"
53
 
54
- # 4) Video inference (same pattern)
55
  def run_video(video_file, conf=0.25):
56
  cap = cv2.VideoCapture(video_file)
57
  fps = cap.get(cv2.CAP_PROP_FPS)
@@ -62,16 +68,19 @@ def run_video(video_file, conf=0.25):
62
 
63
  while True:
64
  ret, frame = cap.read()
65
- if not ret: break
 
66
  idx += 1
67
  t = idx / fps
68
 
69
  res = yolo(frame, conf=conf)[0]
70
  for (x1,y1,x2,y2) in res.boxes.xyxy.cpu().numpy().astype(int):
71
  crop = frame[y1:y2, x1:x2]
72
- if crop.size==0: continue
 
 
73
  plate_img = cv2.resize(crop, (128,32))
74
- recs = ocr.ocr(plate_img, cls=False)
75
 
76
  if recs and recs[0]:
77
  _, (raw, ocr_score) = recs[0]
@@ -88,25 +97,26 @@ def run_video(video_file, conf=0.25):
88
 
89
  writer.write(frame)
90
 
91
- cap.release(); writer.release()
 
92
  with open("output.json","w") as f:
93
  json.dump(records, f, indent=2)
94
  return outfp
95
 
96
- # 5) Gradio UI
97
  with gr.Blocks() as demo:
98
  gr.Markdown("## πŸš— License Plate Detection + Recognition")
99
  with gr.Row():
100
  with gr.Column():
101
- img_in = gr.Image(type="numpy")
102
- vid_in = gr.File(label="Video (.mp4)")
103
- conf = gr.Slider(0,1,0.25,0.01)
104
  b1 = gr.Button("Run Image")
105
  b2 = gr.Button("Run Video")
106
  with gr.Column():
107
- img_out = gr.Image(type="numpy")
108
- vid_out = gr.Video()
109
- status = gr.Textbox()
110
 
111
  b1.click(run_image, [img_in,conf], [img_out,status])
112
  b2.click(run_video, [vid_in,conf], [vid_out,status])
 
7
  from ultralytics import YOLO
8
  from paddleocr import PaddleOCR
9
 
10
+ # ─── 1) Load models ───────────────────────────────────────────────
11
  yolo = YOLO("models/best.pt")
12
+
13
+ # Use recognition‐only mode (no detector), with angle‐cls to handle simple flips
14
+ ocr = PaddleOCR(
15
+ det=False, # skip built‐in detection
16
+ rec=True, # enable recognition
17
+ rec_model_dir="models/ocr_model",
18
+ cls=True, # turn on angle classification
19
+ use_angle_cls=True, # v2.x flag
20
+ lang="en" # our char dict is basic Latin+digits
21
  )
22
 
23
+ # ─── 2) Turkish plate formatter ────────────────────────────────────
24
  def format_turkish_plate(s: str) -> str:
25
  s = re.sub(r'[^A-Z0-9]', '', s.upper())
26
  m = re.match(r'^(\d{2})([A-Z]{1,3})(\d{2,4})$', s)
27
  return f"{m.group(1)} {m.group(2)} {m.group(3)}" if m else "Unknown"
28
 
29
+ # ─── 3) Single‐image inference ─────────────────────────────────────
30
  def run_image(img, conf=0.25):
31
  bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
32
  res = yolo(bgr, conf=conf)[0]
 
36
  res.boxes.conf.cpu().numpy()):
37
  x1,y1,x2,y2 = box.astype(int)
38
  crop = out[y1:y2, x1:x2]
39
+ if crop.size == 0:
40
+ continue
41
 
42
  plate_img = cv2.resize(crop, (128,32))
43
+ # explicitly tell PaddleOCR: skip detection here
44
+ recs = ocr.ocr(plate_img, det=False, cls=False)
45
 
46
  if recs and recs[0]:
47
  _, (raw, ocr_score) = recs[0]
 
57
 
58
  return cv2.cvtColor(out, cv2.COLOR_BGR2RGB), f"{len(res.boxes)} plate(s) detected"
59
 
60
+ # ─── 4) Video inference (same pattern) ───────────────────────────
61
  def run_video(video_file, conf=0.25):
62
  cap = cv2.VideoCapture(video_file)
63
  fps = cap.get(cv2.CAP_PROP_FPS)
 
68
 
69
  while True:
70
  ret, frame = cap.read()
71
+ if not ret:
72
+ break
73
  idx += 1
74
  t = idx / fps
75
 
76
  res = yolo(frame, conf=conf)[0]
77
  for (x1,y1,x2,y2) in res.boxes.xyxy.cpu().numpy().astype(int):
78
  crop = frame[y1:y2, x1:x2]
79
+ if crop.size == 0:
80
+ continue
81
+
82
  plate_img = cv2.resize(crop, (128,32))
83
+ recs = ocr.ocr(plate_img, det=False, cls=False)
84
 
85
  if recs and recs[0]:
86
  _, (raw, ocr_score) = recs[0]
 
97
 
98
  writer.write(frame)
99
 
100
+ cap.release()
101
+ writer.release()
102
  with open("output.json","w") as f:
103
  json.dump(records, f, indent=2)
104
  return outfp
105
 
106
+ # ─── 5) Gradio UI ─────────────────────────────────────────────────
107
  with gr.Blocks() as demo:
108
  gr.Markdown("## πŸš— License Plate Detection + Recognition")
109
  with gr.Row():
110
  with gr.Column():
111
+ img_in = gr.Image(type="numpy", label="Upload Image")
112
+ vid_in = gr.File(label="Upload Video (.mp4)")
113
+ conf = gr.Slider(0,1,0.25,0.01, label="YOLO Confidence")
114
  b1 = gr.Button("Run Image")
115
  b2 = gr.Button("Run Video")
116
  with gr.Column():
117
+ img_out = gr.Image(type="numpy", label="Annotated Image")
118
+ vid_out = gr.Video(label="Annotated Video")
119
+ status = gr.Textbox(label="Status / JSON Path")
120
 
121
  b1.click(run_image, [img_in,conf], [img_out,status])
122
  b2.click(run_video, [vid_in,conf], [vid_out,status])