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

数独图像轮廓排序异常求助:修正从右到左的ROI生成顺序

解决数独轮廓从下到上、从右到左排序的跳序问题

你的核心问题是同行轮廓的y坐标存在1-3像素的微小差异,直接按y逆序排序会导致行内轮廓乱序。要实现从底部开始、从右到左的ROI生成,需要先按行分组,再对每行内部按x逆序,最后按行的y值从大到小排列。

修正后的排序逻辑

替换你原来的sort_contours函数,采用分组排序的方式:

def sort_contours(contours, row_threshold=10):
    # 获取所有轮廓的 bounding box
    bounding_boxes = [cv2.boundingRect(c) for c in contours]
    # 将轮廓和 bounding box 配对,便于后续处理
    contour_box_pairs = list(zip(contours, bounding_boxes))
    
    # 第一步:先按 y 坐标从大到小排序(初步区分行)
    contour_box_pairs.sort(key=lambda pair: pair[1][1], reverse=True)
    
    # 第二步:按行分组,把 y 差小于阈值的归为同一行
    rows = []
    current_row = [contour_box_pairs[0]]
    for pair in contour_box_pairs[1:]:
        prev_y = current_row[-1][1][1]
        curr_y = pair[1][1]
        if abs(prev_y - curr_y) < row_threshold:
            current_row.append(pair)
        else:
            rows.append(current_row)
            current_row = [pair]
    rows.append(current_row)  # 加入最后一行
    
    # 第三步:每行内按 x 坐标从大到小排序(实现从右到左)
    sorted_pairs = []
    for row in rows:
        row_sorted = sorted(row, key=lambda pair: pair[1][0], reverse=True)
        sorted_pairs.extend(row_sorted)
    
    # 拆分回轮廓列表
    sorted_contours = [pair[0] for pair in sorted_pairs]
    return sorted_contours

代码解释

  1. 初步按y排序:先把所有轮廓按顶部y坐标从大到小排,让底部的行先出现,同时把同行的轮廓尽量聚集在一起。
  2. 行分组:遍历排序后的轮廓,把y值差异小于row_threshold(可根据你的数独单元格高度调整,比如设为单元格高度的1/3)的轮廓归为同一行,解决微小y差导致的行混乱问题。
  3. 行内逆序:每行内部按x坐标从大到小排序,这样每行的轮廓从右到左排列,符合你的需求。
  4. 合并结果:把所有行的轮廓按顺序合并,得到最终的排序结果。

其他优化建议

  • 你的contours_ocr函数中,保存ROI再读取的操作可以简化,直接用内存中的图像传给pytesseract,避免IO开销:
    # 替换原来的保存再读取逻辑
    ocr = pytesseract.image_to_string(roi, config='--psm 6')
    
  • 确保sudoku数组的长度是81(9x9),避免索引越界。

为什么原方案失效

你之前手动修改相邻轮廓y值的逻辑只处理了相邻的两个轮廓,无法覆盖同一行中不相邻的轮廓,而且没有对行内的x坐标做排序,自然无法实现从右到左的顺序。

内容的提问来源于stack exchange,提问作者Vitor L.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 18:24:25