APIMONSTER commited on
Commit
089fa45
Β·
verified Β·
1 Parent(s): 97b6396

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -49
app.py CHANGED
@@ -9,61 +9,56 @@ from paddleocr import PaddleOCR
9
 
10
  # ─── 1) Load models ───────────────────────────────────────────────
11
  yolo = YOLO("models/best.pt")
12
-
13
- ocr = PaddleOCR(
14
- det=False, # OCR'nin kendi detector'ΓΌnΓΌ kapat
15
- rec=True, # sadece recognition
16
- rec_model_dir="models/ocr_model", # iΓ§inde inference.pdmodel / .pdparams / .yml var
17
- rec_image_shape="3,32,128", # height=32, width=128
18
- rec_char_dict_path=(
19
- "/usr/local/lib/python3.10/site-packages/"
20
- "paddleocr/ppocr/utils/ppocr_keys_v1.txt"
21
- ), # doğru dict dosyası
22
- use_angle_cls=False, # aΓ§Δ± sΔ±nΔ±flandΔ±rmasΔ±nΔ± kapat (opsiyonel)
23
- use_space_char=True # boşluk karakterini destekle
24
  )
25
 
26
- # ─── 2) Plate formatter ────────────────────────────────────────────
27
  def format_turkish_plate(s: str) -> str:
28
  s = re.sub(r'[^A-Z0-9]', '', s.upper())
29
  m = re.match(r'^(\d{2})([A-Z]{1,3})(\d{2,4})$', s)
30
  return f"{m.group(1)} {m.group(2)} {m.group(3)}" if m else "Unknown"
31
 
32
- # ─── Helper: OCR Γ§Δ±ktΔ±sΔ±nΔ± normalize et ────────────────────────────
33
  def extract_text_score(recs):
34
- """
35
- recs (det=False) β†’ [ [text,score], … ]
36
- recs (det=True) β†’ [ [[text,score],…], … ]
37
- """
38
  if not recs:
39
  return "", 0.0
40
  first = recs[0]
41
- # det=False formatΔ±
42
  if isinstance(first, (list,tuple)) and len(first)==2 and isinstance(first[0], str):
43
- return first[0], float(first[1])
44
- # det=True formatΔ±
45
- if isinstance(first, list) and first and isinstance(first[0], (list,tuple)):
46
- return first[0][0], float(first[0][1])
47
- return "", 0.0
 
 
 
 
 
 
48
 
49
- # ─── 3) Single‐image inference ─────────────────────────────────────
50
  def run_image(img, conf=0.25):
51
  bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
52
  res = yolo(bgr, conf=conf)[0]
53
  out = bgr.copy()
 
54
  for box in res.boxes.xyxy.cpu().numpy().astype(int):
55
  x1,y1,x2,y2 = box
56
  crop = out[y1:y2, x1:x2]
57
- if crop.size==0:
58
  continue
59
 
60
  plate_img = cv2.resize(crop, (128,32))
61
- try:
62
- recs = ocr.ocr(plate_img) # artΔ±k det=False, rec_image_shape, dict hep init'de
63
- except Exception:
64
- recs = []
65
- raw, score = extract_text_score(recs)
66
 
 
67
  plate = format_turkish_plate(raw)
68
  label = f"{plate} ({score:.2f})"
69
 
@@ -73,38 +68,36 @@ def run_image(img, conf=0.25):
73
 
74
  return cv2.cvtColor(out, cv2.COLOR_BGR2RGB), f"{len(res.boxes)} plate(s) detected"
75
 
76
- # ─── 4) Video inference ────────────────────────────────────────────
77
  def run_video(video_file, conf=0.25):
78
  cap = cv2.VideoCapture(video_file)
79
  fps = cap.get(cv2.CAP_PROP_FPS)
80
- w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
81
- h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
82
- tmp_out = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False).name
83
- writer = cv2.VideoWriter(tmp_out, cv2.VideoWriter_fourcc(*"mp4v"), fps, (w,h))
84
  records, idx = [], 0
85
 
86
  while True:
87
  ret, frame = cap.read()
88
  if not ret: break
89
- idx += 1; t = idx/fps
 
90
 
91
  res = yolo(frame, conf=conf)[0]
92
- for box in res.boxes.xyxy.cpu().numpy().astype(int):
93
- x1,y1,x2,y2 = box
94
  crop = frame[y1:y2, x1:x2]
95
- if crop.size==0:
96
  continue
97
 
98
  plate_img = cv2.resize(crop, (128,32))
99
- try:
100
- recs = ocr.ocr(plate_img)
101
- except Exception:
102
- recs = []
103
- raw, score = extract_text_score(recs)
104
 
 
105
  plate = format_turkish_plate(raw)
106
- if plate!="Unknown":
107
- records.append({"time_s":round(t,2),"plate":plate,"conf":round(score,3)})
 
 
108
 
109
  cv2.rectangle(frame, (x1,y1),(x2,y2), (0,255,0), 2)
110
  cv2.putText(frame, plate, (x1, y1-5),
@@ -115,9 +108,9 @@ def run_video(video_file, conf=0.25):
115
  cap.release(); writer.release()
116
  with open("output.json","w") as f:
117
  json.dump(records, f, indent=2)
118
- return tmp_out, "Done"
119
 
120
- # ─── 5) Gradio UI ─────────────────────────────────────────────────
121
  with gr.Blocks() as demo:
122
  gr.Markdown("## πŸš— License Plate Detection + Recognition")
123
  with gr.Row():
@@ -131,6 +124,7 @@ with gr.Blocks() as demo:
131
  img_out = gr.Image(type="numpy", label="Annotated Image")
132
  vid_out = gr.Video(label="Annotated Video")
133
  status = gr.Textbox(label="Status / JSON Path")
 
134
  b1.click(run_image, [img_in,conf], [img_out,status])
135
  b2.click(run_video, [vid_in,conf], [vid_out,status])
136
 
 
9
 
10
  # ─── 1) Load models ───────────────────────────────────────────────
11
  yolo = YOLO("models/best.pt")
12
+ ocr = PaddleOCR(
13
+ det=False, # <<< OCR’nin kendi detector’ınΔ± tamamen kapatΔ±yoruz
14
+ rec=True,
15
+ text_recognition_model_dir="models/ocr_model",
16
+ use_textline_orientation=False,
17
+ lang="en"
 
 
 
 
 
 
18
  )
19
 
20
+ # ─── 2) Turkish plate formatter ────────────────────────────────────
21
  def format_turkish_plate(s: str) -> str:
22
  s = re.sub(r'[^A-Z0-9]', '', s.upper())
23
  m = re.match(r'^(\d{2})([A-Z]{1,3})(\d{2,4})$', s)
24
  return f"{m.group(1)} {m.group(2)} {m.group(3)}" if m else "Unknown"
25
 
26
+ # ─── 3) OCR Γ§Δ±ktΔ±sΔ±nΔ± normalize et ─────────────────────────────────
27
  def extract_text_score(recs):
 
 
 
 
28
  if not recs:
29
  return "", 0.0
30
  first = recs[0]
31
+ # format: [text, score]
32
  if isinstance(first, (list,tuple)) and len(first)==2 and isinstance(first[0], str):
33
+ text, score = first[0], first[1]
34
+ # format: [[...], (text,score)] veya [[...], [text,score]]
35
+ elif isinstance(first, (list,tuple)) and len(first)==2 and isinstance(first[1], (list,tuple)):
36
+ text, score = first[1][0], first[1][1]
37
+ else:
38
+ return "", 0.0
39
+ try:
40
+ score = float(score)
41
+ except:
42
+ score = 0.0
43
+ return text, score
44
 
45
+ # ─── 4) Single‐image inference ─────────────────────────────────────
46
  def run_image(img, conf=0.25):
47
  bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
48
  res = yolo(bgr, conf=conf)[0]
49
  out = bgr.copy()
50
+
51
  for box in res.boxes.xyxy.cpu().numpy().astype(int):
52
  x1,y1,x2,y2 = box
53
  crop = out[y1:y2, x1:x2]
54
+ if crop.size == 0:
55
  continue
56
 
57
  plate_img = cv2.resize(crop, (128,32))
58
+ # <<< mutlaka det=False veriyoruz
59
+ recs = ocr.ocr(plate_img, det=False, cls=False)
 
 
 
60
 
61
+ raw, score = extract_text_score(recs)
62
  plate = format_turkish_plate(raw)
63
  label = f"{plate} ({score:.2f})"
64
 
 
68
 
69
  return cv2.cvtColor(out, cv2.COLOR_BGR2RGB), f"{len(res.boxes)} plate(s) detected"
70
 
71
+ # ─── 5) Video inference ────────────────────────────────────────────
72
  def run_video(video_file, conf=0.25):
73
  cap = cv2.VideoCapture(video_file)
74
  fps = cap.get(cv2.CAP_PROP_FPS)
75
+ w,h = int(cap.get(3)), int(cap.get(4))
76
+ outfp = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False).name
77
+ writer = cv2.VideoWriter(outfp, cv2.VideoWriter_fourcc(*"mp4v"), fps, (w,h))
 
78
  records, idx = [], 0
79
 
80
  while True:
81
  ret, frame = cap.read()
82
  if not ret: break
83
+ idx += 1
84
+ t = idx / fps
85
 
86
  res = yolo(frame, conf=conf)[0]
87
+ for (x1,y1,x2,y2) in res.boxes.xyxy.cpu().numpy().astype(int):
 
88
  crop = frame[y1:y2, x1:x2]
89
+ if crop.size == 0:
90
  continue
91
 
92
  plate_img = cv2.resize(crop, (128,32))
93
+ recs = ocr.ocr(plate_img, det=False, cls=False)
 
 
 
 
94
 
95
+ raw, score = extract_text_score(recs)
96
  plate = format_turkish_plate(raw)
97
+ if plate != "Unknown":
98
+ records.append({"time_s":round(t,2),
99
+ "plate":plate,
100
+ "conf":round(score,3)})
101
 
102
  cv2.rectangle(frame, (x1,y1),(x2,y2), (0,255,0), 2)
103
  cv2.putText(frame, plate, (x1, y1-5),
 
108
  cap.release(); writer.release()
109
  with open("output.json","w") as f:
110
  json.dump(records, f, indent=2)
111
+ return outfp, "Done"
112
 
113
+ # ─── 6) Gradio UI ──────────────────────────────────────────────────
114
  with gr.Blocks() as demo:
115
  gr.Markdown("## πŸš— License Plate Detection + Recognition")
116
  with gr.Row():
 
124
  img_out = gr.Image(type="numpy", label="Annotated Image")
125
  vid_out = gr.Video(label="Annotated Video")
126
  status = gr.Textbox(label="Status / JSON Path")
127
+
128
  b1.click(run_image, [img_in,conf], [img_out,status])
129
  b2.click(run_video, [vid_in,conf], [vid_out,status])
130