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

如何移除扫描图像边缘的零散文本?现有OpenCV代码问题求助

问题分析与解决方案

原代码的核心问题

  • 输出图像计算错误:最后一行labels*255/num_labels会把有效像素值压缩到远低于255的范围,直接导致生成黑底图像。
  • 边缘文本过滤不完整:只处理了左侧边缘的小对象,完全没覆盖右侧边缘的情况,而且labels[stats[i][1], stats[i][2]] != 0属于冗余判断(i从1开始的连通区域本身就是非背景)。
  • 冗余操作:移除目标标签后再次执行connectedComponentsWithStats完全没必要,反而打乱了结果逻辑。

修正后的代码

import cv2
import numpy as np

# 加载灰度扫描图
img = cv2.imread("1.jpg", cv2.IMREAD_GRAYSCALE)

# 反相二值化:让文字为白色,背景为黑色,方便连通区域分析
_, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 获取所有连通区域的属性(位置、大小等)
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity=8)

# 创建空掩码,用于保留需要的区域
result_mask = np.zeros_like(labels, dtype=np.uint8)
img_width = img.shape[1]

# 遍历每个连通区域(跳过背景,i从1开始)
for i in range(1, num_labels):
    x = stats[i][0]  # 区域左上角x坐标
    w = stats[i][2]  # 区域宽度
    # 判断是否是需要移除的边缘零散文本:左侧/右侧边缘50像素内,且宽度小于50
    is_edge_noise = (x < 50 or (x + w) > img_width - 50) and w < 50
    if not is_edge_noise:
        # 保留非边缘文本区域,设为白色
        result_mask[labels == i] = 255

# 转回黑字白底的原图风格,保存结果
final_img = cv2.bitwise_not(result_mask)
cv2.imwrite("output_image.png", final_img)

关键改进说明

  • 修复黑底问题:通过掩码保留有效区域,最后用bitwise_not还原成和原图一致的黑字白底,避免像素值被错误压缩。
  • 全覆盖边缘过滤:新增右侧边缘判断(x + w) > img_width - 50,同时保留宽度限制,确保只移除边缘的零散小文本,不影响正文内容。
  • 简化流程:去掉冗余的二次连通分量分析,直接通过掩码生成结果,代码更高效易懂。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 21:25:26