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`)
|
||||
- `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`.)
|
||||
- `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
|
||||
```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:
|
||||
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 ----
|
||||
|
||||
@app.route('/health', methods=['GET'])
|
||||
|
|
@ -382,9 +466,18 @@ def image2text():
|
|||
target_width=target_w,
|
||||
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:
|
||||
_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:
|
||||
pass
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue