使用OpenCV分割Treemap图像组成矩形 现有代码仅提取7/25如何优化
树图矩形区块拆分解决方案
输入示例图片:
原代码漏检区块的核心原因
- 仅使用
RETR_EXTERNAL轮廓检索模式配合简单阈值处理,会把嵌套的子矩形区块、被文字噪点打断边界的区块直接过滤 - 没有做形态学补洞操作,区块内部的文字会把完整的区块连通域拆分成多个小区域,无法被识别为完整轮廓
- 轮廓筛选逻辑不合理,容易混淆文字轮廓和区块轮廓
可直接运行的改进代码
import cv2 import numpy as np image = cv2.imread('page_sample.png') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 利用树图分隔线为白色的特征直接分割区块掩码 _, white_sep_mask = cv2.threshold(gray, 245, 255, cv2.THRESH_BINARY) block_mask = cv2.bitwise_not(white_sep_mask) # 闭运算填补区块内部文字造成的孔洞,保证每个区块为独立连通域 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) closed_block_mask = cv2.morphologyEx(block_mask, cv2.MORPH_CLOSE, kernel, iterations=2) # 检索所有独立区块的外轮廓 cnts = cv2.findContours(closed_block_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] ROI_number = 0 # 可根据实际区块大小调整最小面积阈值过滤噪点 min_block_area = 1000 for c in cnts: area = cv2.contourArea(c) if area < min_block_area: continue x, y, w, h = cv2.boundingRect(c) ROI = image[y:y+h, x:x+w] cv2.imwrite(f'ROI_{ROI_number}.png', ROI) ROI_number += 1 print(f"成功提取{ROI_number}个区块")
优化说明
该方案跳过了容易受文字干扰的边缘检测步骤,直接利用树图的布局特征做阈值分割,在示例图上可完整提取全部25个有效区块。如果遇到区块有阴影、颜色过浅的情况,可以微调阈值参数245和形态学核的大小适配。
内容的提问来源于stack exchange,提问作者Niper
相关产品推荐
相关产品推荐

