使用 OpenCV 进行文档矫正

本文只发布于博客园pchar博客

    std::vector<std::vector<cv::Point>> cvhelper::findCorners(const cv::Mat &image) {
cv::Mat gaussImage;
cv::GaussianBlur(image, gaussImage, cv::Size(5, 5), 0);
cv::threshold(gaussImage, gaussImage, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
cv::Canny(gaussImage, gaussImage, 50, 200);
cv::morphologyEx(gaussImage, gaussImage, cv::MORPH_CLOSE,
cv::Mat::ones(5, 5, CV_32F));
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(gaussImage, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE); std::vector<std::vector<cv::Point>> ret; for (auto &contour: contours) {
double peri = cv::arcLength(contour, true);
std::vector<cv::Point> approx;
cv::approxPolyDP(contour, approx, 0.05 * peri, true);
if (approx.size() == 4 && cv::isContourConvex(approx) && cv::contourArea(approx) > 1000) {
ret.push_back(approx);
}
} return ret;
} void cvhelper::GetDocumentRect(cv::Mat &src, std::vector<cv::Point> &ret_points) {
int shrunkImageHeight = 500;
cv::Mat shrunkImage;
cv::resize(src, shrunkImage, cv::Size(shrunkImageHeight * src.cols / src.rows, shrunkImageHeight)); cv::cvtColor(shrunkImage, shrunkImage, cv::COLOR_BGR2Luv);
std::vector<cv::Mat> channels;
cv::split(shrunkImage, channels); std::vector<std::vector<cv::Point>> documentCorners; for (const auto &channel: channels) {
std::vector<std::vector<cv::Point>> corners = findCorners(channel);
if (!corners.empty()) {
double maxArea = 0.0;
std::vector<cv::Point> maxAreaContourIt;
for (const auto &contour: corners) {
double area = cv::contourArea(contour);
if (area > maxArea) {
maxArea = area;
maxAreaContourIt = contour;
}
} if (maxArea > 0) {
std::vector<cv::Point> scaledContour;
for (const auto &point: maxAreaContourIt) {
cv::Point scaledPoint;
scaledPoint.x = static_cast<int>(point.x * static_cast<double>(src.rows) /
shrunkImageHeight);
scaledPoint.y = static_cast<int>(point.y * static_cast<double>(src.rows) /
shrunkImageHeight);
scaledContour.push_back(scaledPoint);
}
documentCorners.push_back(scaledContour);
}
}
} if (documentCorners.size() == 0) {
return;
} std::vector<cv::Point> maxDocumentCorners;
double maxDocumentArea = 0.0;
for (const auto &documentCorner: documentCorners) {
double area = cv::contourArea(documentCorner);
if (area > maxDocumentArea) {
maxDocumentArea = area;
maxDocumentCorners = documentCorner;
}
} ret_points = maxDocumentCorners;
} cv::Mat cvhelper::CutKeyPosition(cv::Mat &src, std::vector<cv::Point2f> &src_points) {
// 透视变换
cv::Point2f dst_points[4];
dst_points[0] = cv::Point2f(src.cols, 0);
dst_points[1] = cv::Point2f(0, 0);
dst_points[2] = cv::Point2f(0, src.rows);
dst_points[3] = cv::Point2f(src.cols, src.rows); cv::Point2f tL = src_points[1];
cv::Point2f tR = src_points[0];
cv::Point2f bR = src_points[3];
cv::Point2f bL = src_points[2]; int width = (std::min)(cv::norm(tR - tL), cv::norm(bR - bL));
int height = (std::min)(cv::norm(tR - bR), cv::norm(tL - bL)); cv::Mat M = cv::getPerspectiveTransform(src_points.data(), dst_points);
cv::Mat dst;
cv::warpPerspective(src, dst, M, src.size());
// 缩放图像
cv::resize(dst, dst, cv::Size(width, height));
return dst;
}

效果展示

使用 OpenCV 进行文档矫正的更多相关文章

  1. 配置允许匿名用户登录访问vsftpd服务,进行文档的上传下载、文档的新建删除等操作

    centos7环境下 临时关闭防火墙 #systemctl stop firewalld 临时关闭selinux #setenforce 0 安装ftp服务 #yum install vsftpd - ...

  2. 怎样在Linux下使用Markdown进行文档工作

    怎样在Linux下使用Markdown进行文档工作 在Linux系统中,编辑markdown能够用retext工具: sudo apt-get install retext retext Releas ...

  3. Linux系统通过FTP进行文档基本操作【华为云分享】

    [摘要] Linux系统里通过FTP可以对文档进行上传,更改权限和基本的文档管理. 获得Linux系统后,不熟悉命令操作的情况下,可以通过FTP工具进行文档操作,下面以WinSCP工具为例进行讲解: ...

  4. SharePoint2016如何使用策略进行文档归档

    前言 最近项目用户需要提供文档按照日期或标题关键字进行对应的文档归档操作,为了实施这个操作,需要准备2个文档库,我这里准备了如下文档库: 1. 测试文档库:在测试文档中上传几篇文档,如下图: 2. 我 ...

  5. 使用Word进行文档修订版本的比较

    项目经理在实际的工作过程中,比如要写文档方案,就需要对文档的修订版本进行管理和控制.在以前的工作中,笔者使用的是UltraEdit这个软件工具中的Ultra Compare这个子工具来进行的文档版本的 ...

  6. 利用kibana插件对Elasticsearch进行文档和索引的CRUD操作

    #添加索引PUT lagou { "settings": { "index": { , } } }#查看 索引设置 GET lagou/_settings GE ...

  7. 机器学习实战之朴素贝叶斯进行文档分类(Python 代码版)

    贝叶斯是搞概率论的.学术圈上有个贝叶斯学派.看起来吊吊的.关于贝叶斯是个啥网上有很多资料.想必读者基本都明了.我这里只简单概括下:贝叶斯分类其实就是基于先验概率的基础上的一种分类法,核心公式就是条件概 ...

  8. sharepoint2013用场管理员进行文档库的爬网提示"没有权限,拒绝"的解决方法

    爬网提示被拒绝,场管理员明明可以打开那个站点的,我初步怀疑是:环回请求(LoopbackRequest)导致的 解决方法就是修改环回问题.修改注册表 具体操作方法: http://www.c-shar ...

  9. Marior去除边距和迭代内容矫正用于自然文档矫正

    一.简要介绍 本文简要介绍了论文" Marior: Margin Removal and Iterative Content Rectification for Document Dewar ...

  10. 相机标定过程(opencv) + matlab参数导入opencv + matlab标定和矫正

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 辛苦原创所得,转载请注明出处 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ...

随机推荐

  1. Python函数每日一讲 - 一文让你彻底掌握Python中的frozenset函数

    引言 在 Python 中,frozenset() 函数是一个重要的工具,用于创建不可变的集合对象.本文将介绍 frozenset() 函数的语法.用法示例以及实际应用场景,帮助大家更好地理解和应用这 ...

  2. 测绘线性代数(四):数学期望、协方差、PCA

    数学期望 E(X) = ∑pixi,X为所有xi的集合,pi为xi对应的概率. 通常来说,xi都是离散的,除非像高斯分布,假设xi不是离散的,才用上式. 当xi是离散的,那么: E(X) = 1 / ...

  3. linux FTP服务搭建,匿名用户访问创建上传文件

    1.安装vsftpd 首先确认本地是否安装vftpd rpm -qa|grep vftpd 安装vsftpd yum install vsftpd 为什么呢??因为写权限问题   root 用户. 这 ...

  4. 从 HPC 到 AI:探索文件系统的发展及性能评估

    随着 AI 技术的迅速发展,模型规模和复杂度以及待处理数据量都在急剧上升,这些趋势使得高性能计算(HPC)变得越来越必要.HPC 通过集成强大的计算资源,比如 GPU 和 CPU 集群,提供了处理和分 ...

  5. 借助 Terraform 功能协调部署 CI/CD 流水线-Part 1

    在当今快节奏的开发环境中,实现无缝.稳健的 CI/CD 流水线对于交付高质量软件至关重要.在本文中,我们将向您介绍使用 Bitbucket Pipeline.ArgoCD GitOps 和 AWS E ...

  6. Django使用Bootstrap的经典方法

    前面的话 Bootstrap是简单.灵活的用于搭建WEB页面的HTML.CSS.Javascript的工具集.Bootstrap基于HTML5和CSS3,具有漂亮的设计.友好的学习曲线.卓越的兼容性, ...

  7. day09-Java数组

    Java数组 9.稀疏数组 什么是稀疏数组? 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组. 稀疏数组的处理方式是: 记录数组一共有几行几列,有多少个不同的值 把具有 ...

  8. 修改Tomcat服务器Server Locations

    首先双击我们集成好的Tomcat服务器  修改Server Locations选项  Specify the server path (i.e. catalina.base) and deploy p ...

  9. Java加密技术(四)——非对称加密算法RSA

    Java非对称加密算法rsa     接下来我们介绍典型的非对称加密算法--RSA RSA     这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作,也很 ...

  10. Spring Boot 实现各种参数校验(附项目源码)

    本文会详细介绍Spring Validation各种场景下的最佳实践及其实现原理,死磕到底! 项目源码:spring-validation 一.简单使用 Java API规范(JSR303)定义了Be ...