You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV-Python:如何合并垂直对齐的字符轮廓并生成整体凸包

解决僧伽罗语字符轮廓合并与整体凸包绘制问题

我明白你的困扰——僧伽罗语字符的核心部分和垂直修饰符会被识别成独立轮廓,导致最终的凸包分散开。要解决这个问题,我们需要先把垂直对齐的相关轮廓分组合并,再针对合并后的点集计算整体凸包,而不是单独处理每个轮廓。下面是具体的实现步骤和代码:

核心思路

  • 先获取图像中所有轮廓(而非仅最外层),确保不会遗漏修饰符这类独立小轮廓
  • 根据轮廓的水平位置(边界框的x轴范围)分组:僧伽罗语的修饰符与核心字符的左右范围通常重叠或接近,以此作为分组依据
  • 合并同一组内的所有轮廓点,再对合并后的点集计算凸包
  • 最后绘制合并后的整体凸包

完整代码实现

import cv2
import numpy as np

# 1. 读取图像并预处理
img = cv2.imread('input.png', -1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 若你的图像是白底黑字,用THRESH_BINARY_INV更易提取轮廓;黑底白字则改用THRESH_BINARY
ret, threshed_img = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)

# 2. 获取所有轮廓(RETR_LIST模式获取所有层级的轮廓)
contours, hier = cv2.findContours(threshed_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

# 3. 计算每个轮廓的边界框与中心坐标,方便后续分组
contour_info = []
for cnt in contours:
    x, y, w, h = cv2.boundingRect(cnt)
    center_x = x + w / 2
    contour_info.append({
        'contour': cnt,
        'bbox': (x, y, w, h),
        'center_x': center_x
    })

# 按x轴中心排序,让水平位置接近的轮廓排在一起
contour_info.sort(key=lambda x: x['center_x'])

# 4. 对轮廓进行分组:将水平范围重叠/接近的轮廓归为一组
groups = []
current_group = [contour_info[0]] if contour_info else []

for info in contour_info[1:]:
    # 取当前组第一个轮廓的x轴范围
    group_x_start = current_group[0]['bbox'][0]
    group_x_end = group_x_start + current_group[0]['bbox'][2]
    # 取当前轮廓的x轴范围
    curr_x_start = info['bbox'][0]
    curr_x_end = curr_x_start + info['bbox'][2]
    
    # 检查两个轮廓的x范围是否重叠,或中心间距小于阈值(可根据字符大小调整)
    overlap = min(group_x_end, curr_x_end) - max(group_x_start, curr_x_start)
    if overlap > 0 or abs(info['center_x'] - current_group[0]['center_x']) < 20:
        current_group.append(info)
    else:
        groups.append(current_group)
        current_group = [info]

# 加入最后一组轮廓
if current_group:
    groups.append(current_group)

# 5. 合并每组轮廓并绘制凸包
for group in groups:
    # 合并组内所有轮廓的点集
    merged_points = np.concatenate([info['contour'] for info in group])
    # 计算合并点集的凸包
    hull = cv2.convexHull(merged_points)
    # 绘制凸包(红色,线宽1)
    cv2.drawContours(img, [hull], -1, (0, 0, 255), 1)

# 保存结果
cv2.imwrite("output.png", img)

关键细节说明

  • 阈值化调整:代码中用THRESH_BINARY_INV适配白底黑字的字符图像,如果你的原图是黑底白字,改回THRESH_BINARY即可
  • 分组阈值:abs(info['center_x'] - current_group[0]['center_x']) < 20这个数值可以根据字符大小灵活调整——若修饰符与核心字符间距较大,适当调大阈值
  • 轮廓获取模式:使用RETR_LIST替代RETR_EXTERNAL,确保能捕获到所有修饰符轮廓,哪怕是独立的小轮廓

这样处理后,垂直对齐的核心字符和修饰符会被合并为一个整体,计算出的凸包就是你想要的完整轮廓效果啦!

内容的提问来源于stack exchange,提问作者Ishara Dayarathna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:07:51