身体证检测与识别(二)——HED边缘检测与矫正

article/2025/10/20 12:41:01

前言

1.关于边缘检测,我这里用了HED这个边缘检测网络,HED创作于2015年,骨干网络是state-of-the-art的VGG-16,并且使用迁移学习初始化了网络权重。关于HED的算法原理与训练模型代码可以转到github。
2.OpenCV也有好几边缘检测算法可用,就拿最常用的Canny算法来说,对背景复杂一点的图像,手动调参往往是这个场景下边缘很完美的提取出来,当换个有差异的场景,干扰源不一样,要得到好一些的效果,参数阈值又得重新调一遍,如果要做一个能商用的项目,Canny算法是不能完美解决边缘提取的问题。

项目流程

1.先用HED提取身份证边缘。
2.用霍夫变换直线检测对边缘图像做直线检测。
3.对检测到的直线做排序与筛选,得到最终的边缘。
4.找到边缘线的相交点。
5.以四条线的四个相交点来矫正得到的最终身份证目标。

代码实现

1.使用用OpenCV的DNN来做模型推理,得到最终于的边缘图像。

int hedEdge(cv::dnn::Net& edge_net, cv::Mat& cv_book, cv::Mat& cv_hed)
{if (cv_book.empty()){return -2;}cv::Mat cv_gamma;cv::Size reso(512, 512);cv::Mat blob = cv::dnn::blobFromImage(cv_book, 1.0 / 255.0, reso, cv::Scalar(0, 0, 0), true, false);edge_net.setInput(blob);cv_hed = edge_net.forward();cv::resize(cv_hed.reshape(1, reso.height), cv_hed, cv_book.size(), cv::INTER_LINEAR);cv_hed.convertTo(cv_hed, CV_8UC1, 255);return 0;
}

得到边缘图像:
在这里插入图片描述
2.对得到的边缘图像进行直线检测并分出垂直与水平线。

struct Line
{cv::Point LP1;cv::Point LP2;cv::Point LC;Line(cv::Point p1, cv::Point p2){LP1 = p1;LP2 = p2;LC = cv::Point((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);}
};
void lineDetection(cv::Mat cv_edge,std::vector<Line> &h_lines, std::vector<Line>& v_lines)
{cv::Mat cv_dilate, cv_erode;cv::Mat element_e = getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5), cv::Point(-1, -1));cv::Mat element_d = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3), cv::Point(-1, -1));cv::erode(cv_edge, cv_erode, element_e);cv::dilate(cv_erode, cv_dilate, element_d);std::vector<cv::Vec4i> lines;HoughLinesP(cv_dilate, lines, 1, CV_PI / 180, 100,80, 8);for (size_t i = 0; i < lines.size(); i++) {cv::Vec4i v = lines[i];double delta_x = v[0] - v[2], delta_y = v[1] - v[3];Line l(cv::Point(v[0], v[1]), cv::Point(v[2], v[3]));if (fabs(delta_x) > fabs(delta_y)){h_lines.push_back(l);}else{v_lines.push_back(l);}}
}

运行结果:
在这里插入图片描述
3.提取最终边缘线并得到四个矫正的点。

bool cmpLineY(const Line& p1, const Line& p2)
{return p1.LC.y < p2.LC.y;
}bool cmpLineX(const Line& p1, const Line& p2)
{return p1.LC.x < p2.LC.x;
}cv::Point2f computeIntersect(Line l1, Line l2) 
{int x1 = l1.LP1.x, x2 = l1.LP2.x, y1 = l1.LP1.y, y2 = l1.LP2.y;int x3 = l2.LP1.x, x4 = l2.LP2.x, y3 = l2.LP1.y, y4 = l2.LP2.y;if (float d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)){cv::Point2f pt;pt.x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;pt.y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;return pt;}return cv::Point2f(-1, -1);
}void screeningLine(cv::Mat cv_src, std::vector<Line> &h_lines, std::vector<Line> &v_lines, std::vector<cv::Point> &out_points)
{if (h_lines.size() >= 2 && v_lines.size() >= 2){std::sort(h_lines.begin(), h_lines.end(), cmpLineY);std::sort(v_lines.begin(), v_lines.end(), cmpLineX);out_points.push_back(computeIntersect(h_lines[0], v_lines[0]));out_points.push_back(computeIntersect(h_lines[0], v_lines[v_lines.size() - 1]));out_points.push_back(computeIntersect(h_lines[h_lines.size() - 1], v_lines[0]));out_points.push_back(computeIntersect(h_lines[h_lines.size() - 1], v_lines[v_lines.size() - 1]));}else{out_points.push_back(cv::Point2f(2, 2));out_points.push_back(cv::Point2f(2, cv_src.rows - 2));out_points.push_back(cv::Point2f(cv_src.cols - 2, 2));out_points.push_back(cv::Point2f(cv_src.cols - 2, cv_src.rows - 2));}
}

运行结果:
在这里插入图片描述

4.按四个点矫正图像。

int reviseImage(cv::Mat& cv_src, cv::Mat& cv_dst, std::vector<cv::Point>& in_points)
{cv::Point point_f, point_b;point_f.x = (in_points.at(0).x < in_points.at(2).x) ? in_points.at(0).x : in_points.at(2).x;point_f.y = (in_points.at(0).y < in_points.at(1).y) ? in_points.at(0).y : in_points.at(1).y;point_b.x = (in_points.at(3).x > in_points.at(1).x) ? in_points.at(3).x : in_points.at(1).x;point_b.y = (in_points.at(3).y > in_points.at(2).y) ? in_points.at(3).y : in_points.at(2).y;//代码取目标的最小外接矩形,但倾斜45度时会出现比例变形的现象cv::Rect rect(point_f, point_b);cv_dst = cv::Mat::zeros(rect.height, rect.width, CV_8UC3);std::vector<cv::Point2f> dst_pts;dst_pts.push_back(cv::Point2f(0, 0));dst_pts.push_back(cv::Point2f(rect.width - 1, 0));dst_pts.push_back(cv::Point2f(0, rect.height - 1));dst_pts.push_back(cv::Point2f(rect.width - 1, rect.height - 1));std::vector<cv::Point2f> tr_points;tr_points.push_back(in_points.at(0));tr_points.push_back(in_points.at(1));tr_points.push_back(in_points.at(2));tr_points.push_back(in_points.at(3));cv::Mat transmtx = getPerspectiveTransform(tr_points, dst_pts);warpPerspective(cv_src, cv_dst, transmtx, cv_dst.size());return 0;
}

运行结果:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/XD4awvbR.shtml

相关文章

mysql otter 数据同步_MySQL数据同步之otter

一、otter介绍 基于日志数据&#xff0c;用于MySQL或者ORACLE之间准实时同步数据。 用途&#xff1a; mysql/oracle互相同步 中间表/行记录同步 二、原理及架构图 otter整体模块 manager (提供web页面进行同步管理) arbitrate (分布式调度&#xff0c;可跨IDC机房) node (同步过…

Otter简介

原文地址&#xff1a;http://m635674608.iteye.com/blog/2314908 Otter它是一个数据同步解决方案,可以解决本地跨网络跨机房跨地域的数据同步问题,并且拥有可观的效率&#xff0c;web管理工具等特点,而且背景也很优秀,据说阿里B2B内部的本地/异地机房的同步需求基本全上了 otte…

Canal和Otter

问题一: 跨公网部署Otter 参考架构图 解析 ​ a. 数据涉及网络传输&#xff0c;S/E/T/L几个阶段会分散在2个或者更多Node节点上&#xff0c;多个Node之间通过zookeeper进行协同工作 (一般是Select和Extract在一个机房的Node&#xff0c;Transform/Load落在另一个机房的Node&a…

otter学习(一)——otter原理

1.otter原理&#xff1a; 基于数据库增量日志解析&#xff0c;准实时同步到本机房或异地机房的mysql/oracle数据库. 一个分布式数据库同步系统 原理描述&#xff1a; 1. 基于Canal开源产品&#xff0c;获取数据库增量日志数据。 2. 典型管理系统架构&#xff0c;manager(web管理…

otter数据同步

一、Otter目前支持了什么 1. 单向同步&#xff0c; mysql/oracle互相同步 2. 双向同步&#xff0c;无冲突变更 3. 文件同步&#xff0c;本地/aranda文件 4. 双A同步&#xff0c;冲突检测&冲突补救 5. 数据迁移&#xff0c;中间表/行记录同步 导历史表还需要程序代码实现吗&…

数据同步 之 Otter

一、Otter 语言&#xff1a;java 定位&#xff1a;基于数据库增量日志解析&#xff0c;准实时同步到本机房或异地机房的mysql/oracle数据库&#xff0c;一个分布式数据库同步系统。 1.工作原理&#xff1a; 2.原理描述 1. 基于Canal开源产品&#xff0c;获取数据库增量日志…

otter:分布式数据库同步系统

一、otter介绍 阿里巴巴B2B公司&#xff0c;因为业务的特性&#xff0c;卖家主要集中在国内&#xff0c;买家主要集中在国外&#xff0c;所以衍生出了杭州和美国异地机房的需求&#xff0c;同时为了提升用户体验&#xff0c;整个机房的架构为双A&#xff0c;两边均可写&#x…

Otter 下载安装

简介 基于数据库增量日志解析&#xff0c;准实时同步到本机房或异地机房的mysql/oracle数据库. 一个分布式数据库同步系统。 原理 1. 基于Canal开源产品&#xff0c;获取数据库增量日志数据。 什么是Canal, 请点击 2. 典型管理系统架构&#xff0c;manager(web管理)node(工…

otter使用手册

目录 1.机器管理 1.1 zookeeper管理 1.2 Node管理 2.配置管理 2.1数据源配置 2.2数据表配置&#xff08;添加数据库表&#xff09; 2.3 Canal配置&#xff08;添加Canal&#xff09; 3.同步管理 3.1 Channel管理 3.2 Pipeline管理 1.机器管理 1.1 zookeeper管理 添加z…

Otter 双向同步mysql

一、Otter目前支持了什么 1. 单向同步&#xff0c; mysql/oracle互相同步 2. 双向同步&#xff0c;无冲突变更 3. 文件同步&#xff0c;本地/aranda文件 4. 双A同步&#xff0c;冲突检测&冲突补救 5. 数据迁移&#xff0c;中间表/行记录同步 实际测试中&#xff0c;otter的…

Otter安装说明

Otter安装说明 Mysql安装&#xff08;如果已安装则无需再安装&#xff09;&#xff1a;【忽略安装Mysql】 安装依赖 yum -y install perl perl-devel autoconf #下载Mysql包 https://github.com/alibaba/otter/releases【Otter最新版本下载】 wget https://dev.mysql.com/g…

otter mysql hbase_otter自定义扩展

otter自定义扩展 otter支持数据处理自定义过程。 Extract模块&#xff1a; EventProcessor : 自定义数据处理&#xff0c;可以改变一条变更数据的任意内容 FileResolver : 解决数据和文件的关联关系 目前两者都只支持java语言编写&#xff0c;但都支持运行时动态编译&lib包…

otter搭建

一、安装zookeeper的单机版 apache-zookeeper-3.6.1-bin.tar.gz 如果下载的是3.5及以后的&#xff0c;需要下载包名带有-bin的版本&#xff0c;从3.5.5开始&#xff0c;带有bin的包才是解压以后可以直接使用的里面有编译后二进制的包&#xff0c;而之前的普通的tar.gz里面只是…

otter安装

译意&#xff1a; 水獭&#xff0c;数据搬运工 语言&#xff1a; 纯java开发 定位&#xff1a; 基于数据库增量日志解析&#xff0c;准实时同步到本机房或异地机房的mysql/oracle数据库. 一个分布式数据库同步系统 otter的环境需要&#xff1a;mysql&#xff0c;jdk&#x…

Otter 安装部署维护

介绍 淘宝开源的产品&#xff0c;基于数据库增量日志解析&#xff0c;准实时同步到本机房或异地机房的mysql/oracle数据库&#xff0c;一个分布式数据库同步系统。 目前同步规模&#xff1a; 同步数据量6亿 文件同步1.5TB(2000w张图片) 涉及200个数据库实例之间的同步 80台机器…

Otter配置说明

Otter配置说明 标签&#xff1a; Otter 下载 最新版Otter下载地址 CSDN下载地址 需要下载manager.deployer-4.2.13.tar.gz&#xff0c;node.deployer-4.2.13.tar.gz和Source code (zip) 需要安装zookeeper和jdk支持&#xff0c;canal已经内置&#xff0c;不需要安装 manage…

mysql otter_MySQL数据库实现远程同步的工具alibaba otter

MySQL数据库实现远程同步的工具alibaba otter 发布时间&#xff1a;2020-06-03 15:46:57 来源&#xff1a;51CTO 阅读&#xff1a;291 作者&#xff1a;三月 本篇文章给大家主要讲的是关于MySQL数据库实现远程同步的工具alibaba otter的内容&#xff0c;感兴趣的话就一起来看看…

Otter源码深入详解(三)

分析Node的代码前&#xff0c;需要理解Node的工作机制&#xff0c;需要先了解其工作原理&#xff1a; https://github.com/alibaba/otter/wiki/Otter调度模型 这里用到了SEDA模型&#xff0c;SEDA模型这里有偏文章介绍的很好&#xff1a; https://www.jianshu.com/p/e184fdc0ad…

otter mysql教学视频_3.Otter快速上手

QuickStart 1.几点说明 有一点特别注意&#xff1a;目前canal支持mixed,row,statement多种日志协议的解析&#xff0c;但配合otter进行数据库同步&#xff0c;目前仅支持row协议的同步&#xff0c;使用时需要注意. 环境准备 操作系统 a. otter为纯java编写&#xff0c;windows/…

通过docker构建otter

本文是通过docker构建otter环境与mysql环境 一、使用docker构建otter docker pull canal/otter-all curl -fsSL https://raw.githubusercontent.com/alibaba/otter/master/docker/run.sh | bash 访问otter&#xff1a;http://192.168.102.212:8080 账号密码默认是admin/adm…