@@ -131,15 +131,10 @@ def merge_high_iou_tables(table_res_list, layout_res, table_indices, iou_thresho
131131
132132 # Create merged table
133133 merged_table = table_res_list [i ].copy ()
134- merged_table ['poly' ][0 ] = union_xmin
135- merged_table ['poly' ][1 ] = union_ymin
136- merged_table ['poly' ][2 ] = union_xmax
137- merged_table ['poly' ][3 ] = union_ymin
138- merged_table ['poly' ][4 ] = union_xmax
139- merged_table ['poly' ][5 ] = union_ymax
140- merged_table ['poly' ][6 ] = union_xmin
141- merged_table ['poly' ][7 ] = union_ymax
142-
134+ merged_table ['poly' ] = [
135+ union_xmin , union_ymin , union_xmax , union_ymin ,
136+ union_xmax , union_ymax , union_xmin , union_ymax
137+ ]
143138 # Update layout_res
144139 to_remove = [table_indices [j ], table_indices [i ]]
145140 for idx in sorted (to_remove , reverse = True ):
@@ -253,6 +248,83 @@ def remove_overlaps_min_blocks(res_list):
253248 return res_list , need_remove
254249
255250
251+ def remove_overlaps_low_confidence_blocks (combined_res_list , overlap_threshold = 0.8 ):
252+ """
253+ Remove low-confidence blocks that overlap with other blocks.
254+
255+ This function identifies and removes blocks with low confidence scores that overlap
256+ with other blocks. It calculates the coordinates and area of each block, and checks
257+ for overlaps based on a specified threshold. Blocks that meet the criteria for removal
258+ are returned in a list.
259+
260+ Parameters:
261+ combined_res_list (list): A list of blocks, where each block is a dictionary containing
262+ keys like 'poly' (polygon coordinates) and optionally 'score' (confidence score).
263+ overlap_threshold (float): The threshold for determining overlap between blocks. Default is 0.8.
264+
265+ Returns:
266+ list: A list of blocks to be removed, based on the overlap and confidence criteria.
267+ """
268+ # 计算每个block的坐标和面积
269+ block_info = []
270+ for block in combined_res_list :
271+ xmin , ymin = int (block ['poly' ][0 ]), int (block ['poly' ][1 ])
272+ xmax , ymax = int (block ['poly' ][4 ]), int (block ['poly' ][5 ])
273+ area = (xmax - xmin ) * (ymax - ymin )
274+ score = block .get ('score' , 0.5 ) # 如果没有score字段,默认为0.5
275+ block_info .append ((xmin , ymin , xmax , ymax , area , score , block ))
276+
277+ blocks_to_remove = []
278+ marked_indices = set () # 跟踪已标记为删除的block索引
279+
280+ # 检查每个block内部是否有3个及以上的小block
281+ for i , (xmin , ymin , xmax , ymax , area , score , block ) in enumerate (block_info ):
282+ # 如果当前block已标记为删除,则跳过
283+ if i in marked_indices :
284+ continue
285+
286+ # 查找内部的小block (仅考虑尚未被标记为删除的block)
287+ blocks_inside = [(j , j_score , j_block ) for j , (xj_min , yj_min , xj_max , yj_max , j_area , j_score , j_block ) in
288+ enumerate (block_info )
289+ if i != j and j not in marked_indices and is_inside (block_info [j ], block_info [i ],
290+ overlap_threshold )]
291+
292+ # 如果内部有3个及以上的小block
293+ if len (blocks_inside ) >= 3 :
294+ # 计算小block的平均分数
295+ avg_score = sum (s for _ , s , _ in blocks_inside ) / len (blocks_inside )
296+
297+ # 比较大block的分数和小block的平均分数
298+ if score > avg_score :
299+ # 保留大block,扩展其边界
300+ # 首先将所有小block标记为要删除
301+ for j , _ , j_block in blocks_inside :
302+ if j_block not in blocks_to_remove :
303+ blocks_to_remove .append (j_block )
304+ marked_indices .add (j ) # 标记索引为已处理
305+
306+ # 扩展大block的边界以包含所有小block
307+ new_xmin , new_ymin , new_xmax , new_ymax = xmin , ymin , xmax , ymax
308+ for _ , _ , j_block in blocks_inside :
309+ j_xmin , j_ymin = int (j_block ['poly' ][0 ]), int (j_block ['poly' ][1 ])
310+ j_xmax , j_ymax = int (j_block ['poly' ][4 ]), int (j_block ['poly' ][5 ])
311+ new_xmin = min (new_xmin , j_xmin )
312+ new_ymin = min (new_ymin , j_ymin )
313+ new_xmax = max (new_xmax , j_xmax )
314+ new_ymax = max (new_ymax , j_ymax )
315+
316+ # 更新大block的边界
317+ block ['poly' ][0 ] = block ['poly' ][6 ] = new_xmin
318+ block ['poly' ][1 ] = block ['poly' ][3 ] = new_ymin
319+ block ['poly' ][2 ] = block ['poly' ][4 ] = new_xmax
320+ block ['poly' ][5 ] = block ['poly' ][7 ] = new_ymax
321+ else :
322+ # 保留小blocks,删除大block
323+ blocks_to_remove .append (block )
324+ marked_indices .add (i ) # 标记当前索引为已处理
325+ return blocks_to_remove
326+
327+
256328def get_res_list_from_layout_res (layout_res , iou_threshold = 0.7 , overlap_threshold = 0.8 , area_threshold = 0.8 ):
257329 """Extract OCR, table and other regions from layout results."""
258330 ocr_res_list = []
@@ -311,6 +383,19 @@ def get_res_list_from_layout_res(layout_res, iou_threshold=0.7, overlap_threshol
311383 del res ['bbox' ]
312384 layout_res .remove (res )
313385
386+ # 检测大block内部是否包含多个小block, 合并ocr和table列表进行检测
387+ combined_res_list = ocr_res_list + filtered_table_res_list
388+ blocks_to_remove = remove_overlaps_low_confidence_blocks (combined_res_list , overlap_threshold )
389+ # 移除需要删除的blocks
390+ for block in blocks_to_remove :
391+ if block in ocr_res_list :
392+ ocr_res_list .remove (block )
393+ elif block in filtered_table_res_list :
394+ filtered_table_res_list .remove (block )
395+ # 同时从layout_res中删除
396+ if block in layout_res :
397+ layout_res .remove (block )
398+
314399 return ocr_res_list , filtered_table_res_list , single_page_mfdetrec_res
315400
316401
0 commit comments