(image, item, prompt_chars=None, engine=None)
| 559 | return [{**item, 'char': text_chars[0]}] |
| 560 | |
| 561 | crop, (x1, y1, x2, y2) = crop_bbox(image, item['bbox'], pad=4) |
| 562 | mask = choose_best_mask(crop, len(text_chars)) |
| 563 | local_boxes = split_mask_to_boxes(mask, x1, y1, len(text_chars)) |
| 564 | horizontal = item['bbox'][2] >= item['bbox'][3] |
| 565 | if not split_boxes_are_reasonable(item['bbox'], local_boxes, len(text_chars)): |
| 566 | local_boxes = split_bbox_with_yellow_segments(crop, x1, y1, len(text_chars), horizontal) |
| 567 | if not split_boxes_are_reasonable(item['bbox'], local_boxes, len(text_chars)): |
| 568 | return [] |
| 569 | |
| 570 | ordered = sorted( |
| 571 | local_boxes, |
| 572 | key=lambda box: box[0] if horizontal else box[1], |
| 573 | ) |
| 574 | recognized = recognize_prompt_boxes(image, ordered, prompt_chars or [], engine) if prompt_chars and engine else [] |
| 575 | prompt_set = set(prompt_chars or []) |
| 576 | |
| 577 | split_items = [] |
| 578 | for index, (char, box) in enumerate(zip(text_chars, ordered)): |
| 579 | recognized_item = recognized[index] if index < len(recognized) else None |
| 580 | resolved_char = '' |
| 581 | resolved_score = item['score'] |
| 582 | resolved_source = 'split_source_text' |
| 583 | resolved_source_text = item['text'] |
| 584 | |
| 585 | if recognized_item is not None and recognized_item.get('char'): |
| 586 | resolved_char = recognized_item['char'] |
| 587 | resolved_score = max(float(recognized_item.get('score') or 0), float(item['score'])) |
| 588 | resolved_source = recognized_item.get('source') or resolved_source |
| 589 | resolved_source_text = recognized_item.get('source_text') or item['text'] |
| 590 | elif char in prompt_set or not prompt_set: |
| 591 | resolved_char = char |
| 592 | elif recognized_item is not None: |
| 593 | resolved_score = float(recognized_item.get('score') or 0) |
| 594 | resolved_source = recognized_item.get('source') or resolved_source |
| 595 | resolved_source_text = recognized_item.get('source_text') or item['text'] |
| 596 | |
| 597 | split_items.append( |
| 598 | { |
| 599 | 'bbox': tuple(int(v) for v in box), |
| 600 | 'char': resolved_char, |
| 601 | 'text': resolved_char, |
| 602 | 'score': resolved_score, |
| 603 | 'source_text': resolved_source_text, |
| 604 | 'source_index': item['index'], |
| 605 | 'source': resolved_source, |
| 606 | 'area': int(box[2] * box[3]), |
| 607 | } |
| 608 | ) |
| 609 | return split_items |
| 610 | |
| 611 | |
| 612 | def build_candidate_chars(image, items, prompt_item, image_h, image_w, prompt_chars=None, engine=None): |
| 613 | candidates = [] |
| 614 | for item in items: |
| 615 | if is_ignored_item(item, prompt_item, image_h, image_w): |
| 616 | continue |
| 617 | candidates.extend(split_ocr_item(image, item, prompt_chars=prompt_chars, engine=engine)) |
| 618 | candidates = [ |
no test coverage detected