import torch def detect_tables(model, pixel_values): with torch.no_grad(): outputs = model(pixel_values) return outputs def detect_cells(model, pixel_values): with torch.no_grad(): outputs = model(pixel_values) return outputs def outputs_to_objects(outputs, img_size, id2label): def box_cxcywh_to_xyxy(x): x_c, y_c, w, h = x.unbind(-1) b = [(x_c - 0.5 * w), (y_c - 0.5 * h), (x_c + 0.5 * w), (y_c + 0.5 * h)] return torch.stack(b, dim=1) def rescale_bboxes(out_bbox, size): img_w, img_h = size b = box_cxcywh_to_xyxy(out_bbox) b = b * torch.tensor([img_w, img_h, img_w, img_h], dtype=torch.float32) return b # Add "no object" to id2label if not present if len(id2label) not in id2label: id2label[len(id2label)] = "no object" m = outputs.logits.softmax(-1).max(-1) pred_labels = list(m.indices.detach().cpu().numpy())[0] pred_scores = list(m.values.detach().cpu().numpy())[0] pred_bboxes = outputs['pred_boxes'].detach().cpu()[0] pred_bboxes = [elem.tolist() for elem in rescale_bboxes(pred_bboxes, img_size)] print(f"Predicted labels: {pred_labels}") print(f"id2label: {id2label}") objects = [] for label, score, bbox in zip(pred_labels, pred_scores, pred_bboxes): try: class_label = id2label[int(label)] except KeyError: print(f"Label {label} not found in id2label. Skipping.") continue if not class_label == 'no object': objects.append({'label': class_label, 'score': float(score), 'bbox': [float(elem) for elem in bbox]}) return objects def objects_to_crops(img, tokens, objects, class_thresholds, padding=10): table_crops = [] for obj in objects: if obj['score'] < class_thresholds[obj['label']]: continue cropped_table = {} bbox = obj['bbox'] bbox = [bbox[0] - padding, bbox[1] - padding, bbox[2] + padding, bbox[3] + padding] cropped_img = img.crop(bbox) table_tokens = [token for token in tokens if iob(token['bbox'], bbox) >= 0.5] for token in table_tokens: token['bbox'] = [token['bbox'][0] - bbox[0], token['bbox'][1] - bbox[1], token['bbox'][2] - bbox[0], token['bbox'][3] - bbox[1]] if obj['label'] == 'table rotated': cropped_img = cropped_img.rotate(270, expand=True) for token in table_tokens: bbox = token['bbox'] bbox = [cropped_img.size[0] - bbox[3] - 1, bbox[0], cropped_img.size[0] - bbox[1] - 1, bbox[2]] token['bbox'] = bbox cropped_table['image'] = cropped_img cropped_table['tokens'] = table_tokens table_crops.append(cropped_table) return table_crops def get_cell_coordinates_by_row(table_data): rows = [entry for entry in table_data if entry['label'] == 'table row'] columns = [entry for entry in table_data if entry['label'] == 'table column'] rows.sort(key=lambda x: x['bbox'][1]) columns.sort(key=lambda x: x['bbox'][0]) def find_cell_coordinates(row, column): cell_bbox = [column['bbox'][0], row['bbox'][1], column['bbox'][2], row['bbox'][3]] return cell_bbox cell_coordinates = [] for row in rows: row_cells = [] for column in columns: cell_bbox = find_cell_coordinates(row, column) row_cells.append({'column': column['bbox'], 'cell': cell_bbox}) row_cells.sort(key=lambda x: x['column'][0]) cell_coordinates.append({'row': row['bbox'], 'cells': row_cells, 'cell_count': len(row_cells)}) cell_coordinates.sort(key=lambda x: x['row'][1]) return cell_coordinates