update
This commit is contained in:
parent
268c4a6e7e
commit
a61fe467aa
3 changed files with 96 additions and 3 deletions
|
|
@ -71,7 +71,7 @@ OpenCV from JetPack repos (4.x) usually ships without CUDA dnn. To use CUDA, bui
|
||||||
- `RETURN_BOXES` (default `true`)
|
- `RETURN_BOXES` (default `true`)
|
||||||
- `USE_CUDA_DNN` (default `false`, set `true` to attempt CUDA backend for EAST if OpenCV built with CUDA)
|
- `USE_CUDA_DNN` (default `false`, set `true` to attempt CUDA backend for EAST if OpenCV built with CUDA)
|
||||||
- `DEBUG_VISUAL` (default `false`; if true, response includes `debug_image_base64`. Per-request: add `?debug=1` or form field `debug=1`.)
|
- `DEBUG_VISUAL` (default `false`; if true, response includes `debug_image_base64`. Per-request: add `?debug=1` or form field `debug=1`.)
|
||||||
- `SHOW_GUI` (default `false`; if true and OpenCV GUI available, service opens a window with overlays. Requires X/Wayland/VDI that supports GUI.)
|
- `SHOW_GUI` (default `false`; if true and OpenCV GUI available, service opens a text-centric window: left = detected text regions, right = OCR block text/conf. Requires X/Wayland/VDI that supports GUI.)
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
Binary file not shown.
97
app.py
97
app.py
|
|
@ -235,6 +235,90 @@ def build_debug_image(img_rgb, boxes, blocks, objects, target_width=1024, return
|
||||||
except Exception:
|
except Exception:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
|
def build_text_gui_image(img_rgb, boxes, blocks, target_width=1600):
|
||||||
|
"""Build a text-centric GUI frame: regions on left, OCR lines on right."""
|
||||||
|
if cv2 is None or img_rgb is None:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
src = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
|
||||||
|
h, w = src.shape[:2]
|
||||||
|
frame_w = target_width if target_width and target_width > 0 else 1600
|
||||||
|
if frame_w < 900:
|
||||||
|
frame_w = 900
|
||||||
|
|
||||||
|
left_w = int(frame_w * 0.64)
|
||||||
|
scale = float(left_w) / float(max(1, w))
|
||||||
|
left_h = max(360, int(h * scale))
|
||||||
|
left = cv2.resize(src, (left_w, left_h), interpolation=cv2.INTER_AREA if scale < 1.0 else cv2.INTER_CUBIC)
|
||||||
|
|
||||||
|
# text detector regions
|
||||||
|
for idx, b in enumerate(boxes or []):
|
||||||
|
try:
|
||||||
|
x1, y1, x2, y2 = [int(v * scale) for v in b]
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
cv2.rectangle(left, (x1, y1), (x2, y2), (255, 90, 0), 2)
|
||||||
|
cv2.putText(left, "T{}".format(idx + 1), (x1, max(12, y1 - 4)),
|
||||||
|
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (255, 90, 0), 1, cv2.LINE_AA)
|
||||||
|
|
||||||
|
# OCR blocks (where text was actually extracted)
|
||||||
|
for idx, blk in enumerate(blocks or []):
|
||||||
|
try:
|
||||||
|
x1, y1, x2, y2 = [int(v * scale) for v in blk.get("bbox", [0, 0, 0, 0])]
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
cv2.rectangle(left, (x1, y1), (x2, y2), (0, 160, 255), 2)
|
||||||
|
cv2.putText(left, "R{}".format(idx + 1), (x1, min(left_h - 8, y2 + 14)),
|
||||||
|
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 160, 255), 1, cv2.LINE_AA)
|
||||||
|
|
||||||
|
right_w = frame_w - left_w
|
||||||
|
if right_w < 320:
|
||||||
|
right_w = 320
|
||||||
|
left = cv2.resize(left, (frame_w - right_w, left_h))
|
||||||
|
left_w = left.shape[1]
|
||||||
|
right = np.ones((left_h, right_w, 3), dtype=np.uint8) * 245
|
||||||
|
|
||||||
|
y = 28
|
||||||
|
line_h = 22
|
||||||
|
cv2.putText(right, "OCR text panel", (14, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (30, 30, 30), 2, cv2.LINE_AA)
|
||||||
|
y += line_h + 4
|
||||||
|
cv2.putText(right, "detected regions: {}".format(len(boxes or [])), (14, y),
|
||||||
|
cv2.FONT_HERSHEY_SIMPLEX, 0.55, (70, 70, 70), 1, cv2.LINE_AA)
|
||||||
|
y += line_h
|
||||||
|
cv2.putText(right, "recognized blocks: {}".format(len(blocks or [])), (14, y),
|
||||||
|
cv2.FONT_HERSHEY_SIMPLEX, 0.55, (70, 70, 70), 1, cv2.LINE_AA)
|
||||||
|
y += line_h + 4
|
||||||
|
cv2.line(right, (12, y), (right_w - 12, y), (200, 200, 200), 1)
|
||||||
|
y += 18
|
||||||
|
|
||||||
|
if not blocks:
|
||||||
|
cv2.putText(right, "No OCR text blocks", (14, y),
|
||||||
|
cv2.FONT_HERSHEY_SIMPLEX, 0.56, (100, 100, 100), 1, cv2.LINE_AA)
|
||||||
|
else:
|
||||||
|
visible = blocks[:10]
|
||||||
|
max_chars = max(18, int((right_w - 24) / 8))
|
||||||
|
for idx, blk in enumerate(visible):
|
||||||
|
conf = blk.get("conf", -1)
|
||||||
|
conf_str = "{:.1f}".format(conf) if isinstance(conf, (float, int)) and conf >= 0 else "n/a"
|
||||||
|
header = "#{:02d} conf={}".format(idx + 1, conf_str)
|
||||||
|
cv2.putText(right, header, (14, y), cv2.FONT_HERSHEY_SIMPLEX, 0.50, (20, 20, 20), 1, cv2.LINE_AA)
|
||||||
|
y += line_h - 2
|
||||||
|
raw = (blk.get("text", "") or "").replace("\n", " ").replace("\r", " ").strip()
|
||||||
|
txt = " ".join(raw.split())
|
||||||
|
if len(txt) > max_chars:
|
||||||
|
txt = txt[:max_chars - 1] + "..."
|
||||||
|
cv2.putText(right, txt if txt else "<empty>", (14, y),
|
||||||
|
cv2.FONT_HERSHEY_SIMPLEX, 0.52, (30, 30, 30), 1, cv2.LINE_AA)
|
||||||
|
y += line_h
|
||||||
|
if y > left_h - 18:
|
||||||
|
break
|
||||||
|
|
||||||
|
frame = np.concatenate([left, right], axis=1)
|
||||||
|
return frame
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
# ---- Routes ----
|
# ---- Routes ----
|
||||||
|
|
||||||
@app.route('/health', methods=['GET'])
|
@app.route('/health', methods=['GET'])
|
||||||
|
|
@ -382,9 +466,18 @@ def image2text():
|
||||||
target_width=target_w,
|
target_width=target_w,
|
||||||
return_image=SHOW_GUI,
|
return_image=SHOW_GUI,
|
||||||
)
|
)
|
||||||
if SHOW_GUI and cv2 is not None and debug_image_arr is not None:
|
if SHOW_GUI and cv2 is not None:
|
||||||
try:
|
try:
|
||||||
_gui_show(debug_image_arr)
|
gui_frame = build_text_gui_image(
|
||||||
|
img_rgb,
|
||||||
|
boxes,
|
||||||
|
blocks if RETURN_BOXES else [],
|
||||||
|
target_width=GUI_TARGET_WIDTH,
|
||||||
|
)
|
||||||
|
if gui_frame is None:
|
||||||
|
gui_frame = debug_image_arr
|
||||||
|
if gui_frame is not None:
|
||||||
|
_gui_show(gui_frame)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue