Spaces:
Paused
""" How OmniParser Image Captioning Works
FLOW DIAGRAM:
YOLO Detection Phase β [Full Screenshot] β YOLO model detects UI elements β Returns bounding boxes β filtered_boxes = [(x1, y1, x2, y2), ...] (normalized 0-1 coordinates)
OCR Phase (PaddleOCR) β Extract text from screenshot β ocr_text = ["Download Visual", "Code explanation", ...] ocr_bbox = [(x1, y1, x2, y2), ...]
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.
- 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 β ... β βββββββββββββββββββββββββββββββββββββββββββ
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. π """