omoi-ui-detector / CAPTIONING_EXPLAINED.md
makeitfr's picture
Upload CAPTIONING_EXPLAINED.md with huggingface_hub
099fe70 verified
|
Raw
History Blame Contribute Delete
6.66 kB

""" How OmniParser Image Captioning Works

FLOW DIAGRAM:

  1. YOLO Detection Phase ↓ [Full Screenshot] ↓ YOLO model detects UI elements β†’ Returns bounding boxes ↓ filtered_boxes = [(x1, y1, x2, y2), ...] (normalized 0-1 coordinates)

  2. OCR Phase (PaddleOCR) ↓ Extract text from screenshot ↓ ocr_text = ["Download Visual", "Code explanation", ...] ocr_bbox = [(x1, y1, x2, y2), ...]

  3. CAPTION GENERATION Phase (Florence-2) ↓ FOR EACH detected UI element:

    Step A: Crop the UI element region ───────────────────────────────── Take bounding box coordinates and crop the image:

    xmin = int(bbox[0] * image_width) # e.g., 587 xmax = int(bbox[2] * image_width) # e.g., 764 ymin = int(bbox[1] * image_height) # e.g., 394 ymax = int(bbox[3] * image_height) # e.g., 441

    cropped = image[ymin:ymax, xmin:xmax, :]

    Then resize to 64x64: cropped = cv2.resize(cropped, (64, 64))

    Example: For "Select File" button: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ CROPPED REGION β”‚ β”‚ β”‚ β”‚ (64x64 pixels) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

    Step B: Prepare inputs for Florence model ────────────────────────────────────────── input_ids = processor.tokenize(prompt="") pixel_values = processor.process_image(cropped_64x64)

    inputs = { "input_ids": tensor([...]), # Tokenized prompt "pixel_values": tensor([...]) # Processed image }

    Step C: Generate caption using Florence-2 ────────────────────────────────────────── with torch.no_grad(): generated_ids = model.generate( input_ids=inputs["input_ids"], pixel_values=inputs["pixel_values"], max_new_tokens=20, num_beams=1, do_sample=False ) Step D: Decode output ──────────────────── caption_text = processor.decode(generated_ids, skip_special_tokens=True)

    Result: "Select File" or "File Selection Button" etc.

    1. Batch Processing (for speed) ────────────────────────────── Process multiple cropped images at once:

    GPU: batch_size = 128 (each batch ~30 seconds on high-end GPU) CPU: batch_size = 4 (each batch ~30 seconds on CPU - MUCH slower!)

    Example flow: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Detected 120 UI elements β”‚ β”‚ β”‚ β”‚ Batch 1: Elements 0-127 (128 images) β”‚ β†’ Process 30s β”‚ Batch 2: Elements 128-255 (128 images) β”‚ β†’ Process 30s β”‚ ... β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  4. Output - parsed_content_list ──────────────────────────── [ { 'type': 'icon', 'bbox': [0.43, 0.51, 0.56, 0.58], 'content': 'Select File', # ← Generated by Florence! 'source': 'box_caption_florence' }, { 'type': 'icon', 'bbox': [0.22, 0.34, 0.32, 0.36], 'content': 'JPG Converter', # ← Generated by Florence! 'source': 'box_caption_florence' }, ... ]

KEY DIFFERENCES: Florence vs OCR-only

With Florence Captions: β”œβ”€ Generates semantic descriptions: "Select File Button", "Download Link" β”œβ”€ Understands visual context: can identify buttons vs text vs icons β”œβ”€ Slower: ~30 seconds per batch on CPU, ~seconds on GPU └─ Result: High quality semantic labels

With OCR Text Only (no captions): β”œβ”€ Extracts visible text: "Select File", "Download Visual" β”œβ”€ Uses bbox intersection to match text to elements β”œβ”€ Fast: Done immediately (OCR already done in phase 2) └─ Result: Accurate for text-based elements, misses icons without text

Example: ───────── Button with text "Select File": With Florence: "File Selection UI Element" (semantic) With OCR only: "Select File" (exact text)

Icon without visible label: With Florence: "Download icon" or "Settings gear" With OCR only: No label (fallback to Icon N)

CODE PATHS:

βœ“ With captions (default in original code): Omniparser.init() ↓ self.caption_model_processor = get_caption_model_processor(...)

parse() ↓ get_som_labeled_img() ↓ if use_local_semantics and caption_model_processor is not None: get_parsed_content_icon() # ← Florence caption generation ↓ Crop each UI element ↓ model.generate() with Florence ↓ Return captions

βœ— With captions disabled (what I changed): Omniparser.init() ↓ self.caption_model_processor = None # ← DISABLED

parse() ↓ get_som_labeled_img() ↓ if use_local_semantics and caption_model_processor is None: # ← Now takes this branch # Use OCR text matching with bbox intersection for bbox in filtered_boxes: Find intersecting OCR text Use as label

WHY SO SLOW ON CPU?

Florence-2 has ~7 billion parameters: β€’ Model size: ~14GB β€’ Batch of 4 images: Must do 7B matrix operations for each β€’ Modern GPU: 100+ TFLOPS β†’ can handle this β€’ CPU: 0.1 TFLOPS β†’ 1000x slower!

Result: Each 4-image batch takes ~30 seconds on CPU For 120 elements β†’ ~30 batches β†’ ~15 minutes total!

That's why I disabled it for testing. πŸ˜… """