当前位置: 首页 > news >正文

从图像中提取的每行数字作为一张完整的图片,而不是每个数字单独成为一张图片

具体实现思路:

  1. 提取行区域:先通过轮廓或空白区域分割出每行数字。
  2. 确保每行是一个整体:在提取每行时,确保提取区域的宽度包含该行所有的数字(即避免单独分割每个数字)。
  3. 保存每一行作为一张图片:确保每行的区域保持原样,保存为单张图片。
  4. 获取轮廓并按 y 坐标排序:先找到所有数字的轮廓,并按 y 坐标从上到下排序。这样可以确保我们从上到下处理每一行。

  5. 合并相邻行:当检测到当前行的 y 坐标与前一行的 y 坐标非常接近时,认为它们属于同一行,可以将这两个区域合并成一张图片。

  6. 分割行并保存:将属于同一水平线的多个区域合并成一个区域后,保存为一张新的图片。

import cv2
import numpy as np

# 读取图片
image = cv2.imread('image.png')

# 转为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 二值化图像,使得文字变为白色,背景变为黑色
_, thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)

# 查找轮廓(可以忽略背景,集中在文字区域)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 按照y坐标排序(从上到下)
contours = sorted(contours, key=lambda ctr: cv2.boundingRect(ctr)[1])

# 设定一个阈值,用于判断是否为同一行(水平对齐)
y_threshold = 10  # 根据实际情况调整,表示两行之间的最大间距

# 初始化一个空列表,用于存储行的图片
row_images = []
current_row = []

# 遍历所有轮廓
for i, contour in enumerate(contours):
    x, y, w, h = cv2.boundingRect(contour)

    # 过滤掉噪音区域(高度过小的区域)
    if h > 20:
        # 如果当前行是空的,或者当前行的y坐标和上一行的y坐标相差较小(认为是同一行)
        if not current_row or abs(current_row[-1][1] - y) < y_threshold:
            # 将当前轮廓的区域加入当前行
            current_row.append((x, y, w, h))
        else:
            # 如果是新的一行,则合并上一行的图片并清空当前行
            if current_row:
                # 计算当前行的左上角和右下角,合并所有小块区域
                x_min = min([rect[0] for rect in current_row])
                y_min = min([rect[1] for rect in current_row])
                x_max = max([rect[0] + rect[2] for rect in current_row])
                y_max = max([rect[1] + rect[3] for rect in current_row])
                
                # 裁剪出当前行的完整图像
                row_image = image[y_min:y_max, x_min:x_max]
                row_images.append(row_image)

            # 重置当前行,添加当前轮廓
            current_row = [(x, y, w, h)]

# 最后处理剩余的行
if current_row:
    # 合并最后一行
    x_min = min([rect[0] for rect in current_row])
    y_min = min([rect[1] for rect in current_row])
    x_max = max([rect[0] + rect[2] for rect in current_row])
    y_max = max([rect[1] + rect[3] for rect in current_row])
    
    row_image = image[y_min:y_max, x_min:x_max]
    row_images.append(row_image)

# 保存每一行作为图片
for i, row_image in enumerate(row_images):
    cv2.imwrite(f'row_{i+1}.png', row_image)

原图:

实现效果

相关文章:

  • 教程:使用 Vue 3 和 arco 实现表格合并
  • MySQL 数据库定时任务及进阶学习
  • UE_C++ —— Metadata Specifiers
  • Redis——优惠券秒杀问题(分布式id、一人多单超卖、乐悲锁、CAS、分布式锁、Redisson)
  • 【目标检测json2txt】label从COCO格式json文件转YOLO格式txt文件
  • mysql开启gtid并配置主从
  • Windows 11 下 Ollama 安装与 OpenWebUI 调用 DeepSeek-R1 的详细指南
  • 100N03-ASEMI豆浆机专用MOS管100N03
  • qt QOpenGLContext详解
  • 数字电路-基础逻辑门实验
  • 【Elasticsearch】runtime_mappings搜索请求中定义运行时字段
  • 微软AutoGen高级功能——Magentic-One
  • LabVIEW软件需求开发文档参考
  • Win11配置wsl、ubuntu、docker
  • 【哇! C++】内联函数、auto关键字、基于范围的for循环、指针空值nullptr
  • git bash在github的库中上传或更新本地文件
  • 本地部署Deepseek-R1模型指南:从Ollama安装到RAG应用
  • 【Linux】Ubuntu Linux 系统——Node.js 开发环境
  • Spring Security,servlet filter,和白名单之间的关系
  • C#中的GC机制简析
  • 受贿1.29亿余元,黑龙江省原副省长王一新被判无期
  • 乌克兰谈判代表团由12人组成,乌防长率领
  • 株洲一重病妇女被要求本人到银行取款时去世?当地警方:正在处理
  • 牛市早报|4月新增社融1.16万亿,降准今日正式落地
  • 基金经理调仓引发大金融板块拉升?公募新规落地究竟利好哪些板块
  • 讲武谈兵|视距外的狙杀:从印巴空战谈谈超视距空战