[DIP]如何提取文件中的公章,并识别其朝向是否准确

2023-11-05

任务描述,
我们需要知道,我们盖在文件上的红章是否是端正的。

需要解决的问题:
1、图章的识别
2、图章的定位
3、图章的方向判定

思路:
图章基本上是红色的,我们先根据颜色提取可能的图章区域。
当然,假如文档中,还有其他红色的区域,这一步都会提取出来。

img = cv2.imdecode(np.fromfile("jingshanshi_muti_stamp.png", dtype=np.uint8), -1)


def extract_red(img):
    ''''使用inRange方法,拼接mask0,mask1'''

    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    rows, cols, channels = img.shape
    # 区间1
    lower_red = np.array([0, 43, 46])
    upper_red = np.array([10, 255, 255])
    mask0 = cv2.inRange(img_hsv, lower_red, upper_red)
    # 区间2
    lower_red = np.array([156, 43, 46])
    upper_red = np.array([180, 255, 255])
    mask1 = cv2.inRange(img_hsv, lower_red, upper_red)
    # 拼接两个区间
    mask = mask0 + mask1
    return mask


mask = extract_red(img)
mask_img = cv2.add(img, np.zeros(np.shape(img), dtype=np.uint8), mask=mask)
#cv2.imwrite('jingshanshi_muti_stamp_pickred.png', mask_img)

公章一般都是圆形的,我们先利用HoughCircles 找出圆来

# cv2.HoughCircles 寻找出圆,匹配出图章的位置

circles = cv2.HoughCircles(binaryImg, cv2.HOUGH_GRADIENT, 1, 40,
                           param1=50, param2=30, minRadius=20, maxRadius=60)

circles = np.uint16(np.around(circles))

提取出文档中,图形的轮廓。根据点到圆心的距离小于或等于半径,进一步定位公章位置

# findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> image, contours, hierarchy
binaryImg = cv2.Canny(mask_img, 50, 200)  # 二值化,canny检测
image, contours, hierarchy = cv2.findContours(binaryImg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

'''
tuple cir_point:圆心坐标
int radius:半径
list points:点集
float dp: 误差
int samplingtime:采样次数

'''
import random


def circle_check(cir_point, radius, points, dp=4, samplingtime=30):
    # 根据点到圆心的距离等于半径判断点集是否在圆上
    # 多次抽样出5个点
    # 判断多次抽样的结果是否满足条件
    count = 0
    points = list(points)
    for s in range(samplingtime):
        # 从点集points 中采样一次
        points_samp = random.sample(points, 5)
        # 判断点到圆心的距离是否等于半径
        points_samp = np.array(points_samp[0])
        dist = np.linalg.norm(points_samp - cir_point)
        if dist == radius or abs(dist - radius) <= dp:
            continue
        else:
            count += 1
    if count < 3:
        return True
    else:
        return False


def circle_map(contours, circles):
    is_stramp = [0] * len(contours)
    circle_point = []
    for cir in circles[0, :]:
        # 获取圆心和半径
        cir_point = np.array((cir[0], cir[1]))
        radius = cir[2]

        # 遍历每一个点集
        for cidx, cont in enumerate(contours):
            # 当轮廓点数少于10 的时候,默认其不是公章轮廓
            if len(cont) < 10:
                continue
            # 匹配出公章轮廓,并对应出圆心坐标
            stampcheck = circle_check(cir_point, radius, cont, dp=6, samplingtime=40)
            # 如果满足点在圆心上,就将圆心,半径和对应的点记录
            if stampcheck:
                circle_point.append((cir_point, radius, cont))
                is_stramp[cidx] = 1

    return circle_point, is_stramp


circle_point, is_stramp = circle_map(contours, circles)

上面的代码中,用到了采样的方法,如何判断轮廓是圆弧呢?每个像素点穷举显然不合适,于是我们多次采样,然后投票判决。

找到公章的外围轮廓之后,我们进一步得到文字所在的轮廓像素。

获得外围轮廓是很有意义的,去掉他们,将会对后面的定位至关重要。

接下来,我们有圆心坐标,文字轮廓,如何计算公章朝向呢?

整体思路是:

我们对每一个文字轮廓,进行中心点坐标的计算。根据中心点和圆心组成的向量,计算夹角。然后找出满足一定条件的夹角对应的两个向量。再对这两个向量做差后计算与水平轴的夹角。

如下图,上面的方案能很好的找出公章下方的边缘位置:

上面的过程需要解决一些问题:

1、排除多个非常靠近的中心点的干扰,可以用聚类算法,基于角度的计算等等。我用的是第二种方法。

2、中心点分象限处理,分象限是很有必要的,在每个象限里,我们只需要考虑两个边际。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

 

 

 

 

 

 

 

 

 

 

 

 

我将代码放在github上。欢迎指导。

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[DIP]如何提取文件中的公章,并识别其朝向是否准确 的相关文章

随机推荐

  • 修复和预防Bug的成本的量化对比

    当我们打算提高软件质量的时候 首先考虑到的可能就是购买新工具的成本和实施新工具的人力成本 以及可能会因为增加了新的测试过程而 延长 的开发生命周期 但实际上 首先我们应该考虑从现在的产品生命周期中查找和修复问题产生的成本 除了这些直接的成本
  • 天才的引导历程

    这本书与科学15讲差不多 是数学科普类书籍 这里面对于无穷小数的思考 提出 可以看一看 学习数学的人真的可以看一看 2014 1 1
  • 前言技术:swagger

    1 前后端分离的特点 前后端分离是的前端与后端之间的职责更加明确 后台 负责业务处理 前端 负责显示逻辑 在这种情况下 前端和后端可以分别交付给专业的开发人员去做 所以是必须要定义前后端直接的对接 接口 否则各自为是则项目无法集成 这时就需
  • 基于51单片机的超声波水位液位监测仿真程序设计

    硬件设计 上一篇咱们说了基于液位传感器的优缺点 其中缺点就是测量距离有限 这里就引入了超声波的测距方式 该方式测量距离就大大增加 超声波测距系统原理 在超声探测电路中 发射端得到输出脉冲为一系列方波 其宽度为发射超声的时间间隔 被测物距离越
  • 中国移动OneOS助力全国大学生物联网竞赛开幕

    本文分享自中移物联网微信公众号 中国移动OneOS助力全国大学生物联网竞赛开幕 近日 2022年全国大学生物联网设计竞赛正式开赛 该项赛事是教育部高等学校计算机类专业教学指导委员会创办的物联网领域的学科竞赛 是以学科竞赛推动专业建设 培养大
  • Vmware虚拟机下三种网络模式配置

    原创链接 http blog csdn net collection4u article details 14127671 Vmware虚拟机下三种网络模式配置 VMware虚拟机有三种网络模式 分别是Bridged 桥接模式 NAT 网络
  • docker-compose部署Nacos集群

    docker compose部署Nacos集群 1 前置准备 docker nacos的数据库 2 创建nacos目录 3 切换到nacos目录下 创建并写nginx conf配置文件 4 创建并写docker compose yaml配置
  • Channel-wise Knowledge Distillation for Dense Prediction(ICCV 2021)原理与代码解析

    paper Channel wise Knowledge Distillation for Dense Prediction official implementation https github com irfanICMLL Torch
  • Vue3的从入门到实战的培训教程大纲

    Vue3的从入门到实战的培训教程大纲 第一部分 Vue3入门 Vue框架概述 介绍Vue的历史和特点 解释Vue的MVVM架构 Vue3的新特性 对比Vue2和Vue3的主要差异 强调Vue3的性能改进和优化 安装与配置Vue3 下载和安装
  • java 多线程-03-等待wait 和 通知 notify

    等待wait 和 通知 notify 引入 java多线程协作支持 wait notify是object类 任何对象都可以调用这两个方法 public final void wait throws InterruptedException
  • 如何使用宝塔部署网站

    1 根据自己的版本输入不同安装宝塔的命令 我用的使用的是finashell软件 安装及使用前一篇已经介绍过了 用的是第一个安装命令 yum install y wget wget O install sh https download bt
  • 图的遍历(详解DFS与BFS)

    首先 我们来看一下涉及的知识点 图 图 G V E 由顶点集 V 和边集 E 组成 每条边对应一个点对 v w 其中 v w 属于 V 如果图中的点对是有序的 那么该图就是有向图 反之为无向图 邻接点 若顶点 v 与 w 之间存在一条边 则
  • 6、状态模式

    文章目录 概念 3个角色 demo 概念 状态模式属于行为型模式 只需要改变对象状态即可改变对象的行为 状态模式对 开闭原则 的支持并不太好 所以对象状态最好为有限个且不常变动 场景 1 行为随状态 属性改变而改变的场景 2 条件 分支语句
  • 终于拿下淘宝了。淘宝抓取,淘宝爬虫。taobao spider

    上个demo先
  • Linux 查看当前路径下所有文件夹大小的方法

    进入需要查看的目录 例如 根目录 cd 查看当前目录下每个文件夹的大小 du sh 查看当前目录下每个文件夹的大小并排序 单位 字节 n 按照数值排序 du s sort n 补充 du sh 查看当前目录总共占的容量 而不单独列出各子项占
  • Task-Oriented Conversation Generation Using Heterogeneous Memory Networks

    EMNLP 2019 录用长文 Abstract 如何将外部知识库与对话模型结合起来是一个重要的问题 传统上人们是使用了Memory Network 然而当面对多种来源的 异构的info时 Mem对这些info的处理并不好 我理解的是权重的
  • Numpy基础数据结构

    Numpy基础数据结构 NumPy数组是一个多维数组对象 称为ndarray 其由两部分组成 实际的数据 描述这些数据的元数据 Numpy Python开源的科学计算工具包 高级的数据编程工具 ndarray 是强大的N维数组对象 对数据结
  • Eclipse导入项目No projects are found to import

    如果发现导入工程 impot 的时候 出现 No projects are found to import 的提示 首先查看项目目录中是否有隐藏文件 project 还有目录结构也还要有一个隐藏文件 classpath 如果没有 你可以参考
  • 不能不知道的OS模块的那些常用函数(附内置变量)

    文章目录 OS 模块 1 1 常用函数 1 2 使用示例 1 3 内置变量 1 4 附 内置变量详解 OS 模块 该模块提供了各种函数 允许您操作文件路径和检查与路径相关的信息 比如是否存在 文件扩展名 目录名等等 1 1 常用函数 其中一
  • [DIP]如何提取文件中的公章,并识别其朝向是否准确

    任务描述 我们需要知道 我们盖在文件上的红章是否是端正的 需要解决的问题 1 图章的识别 2 图章的定位 3 图章的方向判定 思路 图章基本上是红色的 我们先根据颜色提取可能的图章区域 当然 假如文档中 还有其他红色的区域 这一步都会提取出