# -*- coding: utf-8 -*- """ 分析一个 ocr_result.jsonl,判断"冗余文字过多"是真冗余还是误杀。 复现过滤逻辑:看文字的垂直位置分布(distinct_bands)、每帧文字框数、有没有稳定字幕行。 用法: python temp/analyze_ocr_result.py "ocr_result (1).jsonl" """ import json import sys from collections import defaultdict PATH = sys.argv[1] if len(sys.argv) > 1 else "ocr_result.jsonl" def parse(path): """解析 'pic_path: X' + json 交替格式,返回 [(frame, detections), ...]。""" pairs = [] cur_frame = None with open(path, encoding="utf-8") as f: for line in f: line = line.rstrip("\n") if line.startswith("pic_path:"): cur_frame = line.split("pic_path:", 1)[1].strip() elif line.strip(): try: data = json.loads(line) pairs.append((cur_frame, data.get("TextDetections", []))) except json.JSONDecodeError: pass return pairs def center_y(det): poly = det.get("Polygon", []) ys = [p.get("Y", 0) for p in poly] return sum(ys) / len(ys) if ys else 0 def main(): try: pairs = parse(PATH) except FileNotFoundError: print(f"找不到文件: {PATH}") return if not pairs: print("没解析到数据(格式不对?)") return n_frames = len(pairs) boxes_per_frame = [len(d) for _, d in pairs] total_boxes = sum(boxes_per_frame) frames_with_text = sum(1 for b in boxes_per_frame if b) # 所有文字框的中心 Y all_cy = [] for _, dets in pairs: for det in dets: all_cy.append(center_y(det)) print(f"文件: {PATH}") print("=" * 60) print(f"帧/图数: {n_frames}") print(f"有文字的: {frames_with_text}") print(f"文字框总数: {total_boxes}") print(f"平均每帧框数: {total_boxes / n_frames:.1f}") print(f"最多一帧框数: {max(boxes_per_frame) if boxes_per_frame else 0}") # distinct vertical bands(复现 merge.py 的冗余判定:中心Y间隔>80算一个新垂直簇) cys = sorted(all_cy) bands = 1 if cys else 0 for i in range(1, len(cys)): if cys[i] - cys[i - 1] > 80: bands += 1 print(f"不同垂直位置簇: {bands} (>=8 会被判冗余)") # Y 分布直方图(每 100px 一档),看文字集中在哪还是散布全屏 hist = defaultdict(int) for y in all_cy: hist[int(y // 100) * 100] += 1 print("\n文字垂直分布(Y每100px一档,看文字集中度):") if hist: mx = max(hist.values()) for y in sorted(hist): bar = "#" * int(hist[y] / mx * 40) print(f" y={y:>5}-{y+99:<5} {hist[y]:>6} {bar}") # 判定 print("\n" + "=" * 60) if bands >= 8: print(f"❌ 真冗余:文字散布在 {bands} 个不同垂直位置(满屏文字/弹幕/文档类)。") elif total_boxes / n_frames > 10: print(f"⚠️ 偏冗余:平均每帧 {total_boxes/n_frames:.0f} 个文字框,画面文字很多。") else: topy = max(hist, key=hist.get) if hist else 0 print(f"✅ 可能误杀:文字主要集中在 y={topy}~{topy+99},像是有固定字幕行的。") print(" 若确实有正常字幕,可放宽 merge.py 的 distinct_bands 阈值。") if __name__ == "__main__": main()