iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >OpenCV实现倾斜文字校正
  • 818
分享到

OpenCV实现倾斜文字校正

OpenCV倾斜文字校正OpenCV倾斜校正OpenCV文字校正 2022-11-13 13:11:38 818人浏览 泡泡鱼
摘要

基于OpenCV的倾斜文字校正,供大家参考,具体内容如下 使用OpenCV里example中的的倾斜文本作为输入,本文的目的即将该倾斜的文本校正成水平方向的文本。 主要思路为: 读取

基于OpenCV的倾斜文字校正,供大家参考,具体内容如下

使用OpenCV里example中的的倾斜文本作为输入,本文的目的即将该倾斜的文本校正成水平方向的文本。

主要思路为:

读取图像-——>Canny边缘检测——->形态学操作-——>提取最小外接矩形——->计算旋转矩阵-——>仿射变换校正文本图像

原始图像:

提取最小外接矩形区域

校正后的图像

主要涉及的api

创建滑动条

这个API可以创建一个滑动条,可以在不改变程序的情况下更改变量的值来显示图像变化的效果。在这个场景中使用创建滑动条来调节Canny边缘检测的阈值,提取合适的边缘。

```cpp
Clicking the label of each trackbar enables editing the trackbar values manually.

@param trackbarname Name of the created trackbar.\\第一个参数为滑动条的名称
@param winname Name of the window that will be used as a parent of the created trackbar. \\ 滑动条所依附的窗口名称
@param value Optional pointer to an integer variable whose value reflects the position of the slider. Upon creation, the slider position is defined by this variable.
\\ 引用值,即拖动滑动条所改变的值,需要提前定义,定义好的值即为滑动条的初始值。
@param count Maximal position of the slider. The minimal position is always 0. \\滑动条的最大位置
@param onChange Pointer to the function to be called every time the slider changes position. This function should be prototyped as void Foo(int,void\*); , where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is the NULL pointer, no callbacks are called, but only value is updated.
\\ 定义回调函数,每次滑动滑动条都会调用这个回调函数。回调函数的格式为 void Foo(int,void*)其中第一个参数为轨迹条的位置,第二个参数是用户数据userdata。
@param userdata User data that is passed as is to the callback. It can be used to handle trackbar events without using global variables.
\\ 用户传递给回调函数的数据userdata,这里使用的是全局变量,因此这一项可以忽略。

CV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname,
                              int* value, int count,
                              TrackbarCallback onChange = 0,
                              void* userdata = 0);
### Canny边缘检测

使用Canny边缘检测算法提取文本图像的边缘

`

```cpp

CV_EXPORTS_W void Canny( InputArray image, OutputArray edges,
                         double threshold1, double threshold2,
                         int apertureSize = 3, bool L2gradient = false );

边缘检测的结果,由于测试的样本图像比较理想,调节滑动条的位置影响不是很大。如果图像质量较差,也可以添加图像预处理步骤优化源图像。

形态学处理

使用形态学处理操作连接经过Canny边缘检测处理后字符缝隙,使其变成一个连通域。

步骤:创建结构元素(getStructuringElement)->膨胀处理

Mat src_dilate;
Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11), Point());
// 创建结构元素的大小,第一个参数为结构元素的形状(矩形MORPH_RECT,十字形结构MORPH_CROSS,椭圆形结构MORPH_ELLIPSE),第二个参数为结构元素的大小,第三个参数为锚点的位置。
dilate(Canny_edge, src_dilate, kernel, Point(-1, -1), 1, BORDER_DEFAULT);
// 膨胀图像,第一个参数为输入图像,第二个为输出图像,第三个参数为结构元素,第四个参数为锚点的位置,第五个参数为迭代的次数,最后一个参数为边界填充的类型

膨胀后的图像显示为:

查找轮廓

vector<vector<Point>> Contours;
// 定义边缘的点集
vector<Vec4i> hierarchy;
// 定义边缘的层次关系
findContours(src_dilate, Contours, hierarchy, RETR_TREE, CHaiN_APPROX_NONE, Point());

CV_EXPORTS_W void findContours( InputArray image, OutputArrayOfArrays contours,
                              OutputArray hierarchy, int mode,
                              int method, Point offset = Point());

最小外接矩形

旋转矩形对象类型 RotatedRect

轮廓的最小外接矩形 minAreaRect


CV_EXPORTS_W RotatedRect minAreaRect( InputArray points );

计算旋转矩阵

Mat Rotation = getRotationMatrix2D(center,RRect_degree,1.0);
Mat output;
warpAffine(src,output,Rotation,src.size(),INTER_CUBIC,BORDER_CONSTANT,Scalar(255,255,255));
// 输入要变换图像,输出图像,定义旋转矩阵,定义插值方式,边界类型(边界类型需要注意)

完整代码

#include <iOStream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/calib3D.hpp>

using namespace std;
using namespace cv;

// Define Mat
Mat src, gray_src, dst;
const char *IWindow = "InputWindow";
const char *OWindow = "OutputWindow";
int canny_threshold = 100;
int threshold_level = 255;

void Canny_function(int, void *);

int main(int arGC, char **argv) {
    src = imread("D:/Delete/imageTextR.png");
    if (src.empty()) {
        cout << "Could not load image" << endl;
        return -1;
    }
    // Covert to GrayScale
    cvtColor(src, gray_src, COLOR_BGR2GRAY);
    namedWindow(IWindow, WINDOW_AUTOSIZE);
    imshow(IWindow, src);
    namedWindow(OWindow, WINDOW_AUTOSIZE);
    createTrackbar("Canny_Threshold", IWindow, &canny_threshold, threshold_level, Canny_function);

    waiTKEy();
    return 0;
}

void Canny_function(int, void *) {
    Mat Canny_edge;
    Canny(gray_src, Canny_edge, canny_threshold, canny_threshold * 2, 3, false);
    //Display Canny_edge
    //imshow(OWindow,Canny_edge);

    Mat src_dilate;
    Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11), Point());
    dilate(Canny_edge, src_dilate, kernel, Point(-1, -1), 1, BORDER_DEFAULT);
    //Display Dilate image
    imshow(OWindow,src_dilate);

    // Find Contour
    vector<vector<Point>> Contours;
    vector<Vec4i> hierarchy;
    findContours(src_dilate, Contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE, Point());

    // Select the Max area Contour
    double MaxAreaRRect = 0;
    int SizeContour = 0;
    for (size_t t = 0; t < Contours.size(); t++) {
        RotatedRect RRect = minAreaRect(Contours[t]);
        double AreaRRect = 0;
        AreaRRect = RRect.size.area();
        MaxAreaRRect = max(MaxAreaRRect, AreaRRect);
    }

    double RRect_degree = 0;
    dst = src.clone(); // 这里涉及是否复制数据的问题
    for (size_t t = 0; t < Contours.size(); t++) {
        RotatedRect RRect = minAreaRect(Contours[t]);
        double AreaRRect = RRect.size.area();
        if (AreaRRect == MaxAreaRRect ) {
            SizeContour = SizeContour + 1;
            // Rotate degree
            RRect_degree = RRect.angle;
            // Draw this rectangle
            Point2f vertex[4];
            RRect.points(vertex);
            for (int i = 0; i < 4; i++) {
                line(dst, Point(vertex[i]), Point(vertex[(i + 1) % 4]), Scalar(0, 255, 0), 2, LINE_8);
            }
        }
    }
    cout << "SizeContour : \t "<< SizeContour <<endl;
    cout << "Rotated Rectangle angle : " << RRect_degree << endl;

    //imshow(OWindow, dst);

    Point2f center(src.cols/2,src.rows/2);
    Mat Rotation = getRotationMatrix2D(center,RRect_degree,1.0);
    Mat output;
    warpAffine(src,output,Rotation,src.size(),INTER_CUBIC,BORDER_CONSTANT,Scalar(255,255,255));


    // Display Rotate Rectangle
    namedWindow("Final_Result",WINDOW_AUTOSIZE);
    imshow("Final_Result", output);


}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: OpenCV实现倾斜文字校正

本文链接: https://www.lsjlt.com/news/171320.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • OpenCV实现倾斜文字校正
    基于OpenCV的倾斜文字校正,供大家参考,具体内容如下 使用OpenCV里example中的的倾斜文本作为输入,本文的目的即将该倾斜的文本校正成水平方向的文本。 主要思路为: 读取...
    99+
    2022-11-13
    OpenCV倾斜文字校正 OpenCV倾斜校正 OpenCV文字校正
  • opencv实现图像倾斜校正
    本文实例为大家分享了opencv实现图像倾斜校正的具体代码,供大家参考,具体内容如下 今天的任务是如图这两种情况,我现在的情况是和如图一样的,左图左边倾斜一点儿,那么我需要把左边压...
    99+
    2022-11-13
    opencv图像倾斜校正 opencv图像校正 opencv倾斜校正
  • python中opencv实现图片文本倾斜校正
    本项目为python项目需要安装python及python的opencv模块:opencv_python-4.0.1-cp37-cp37m-win32.whl 和 python的矩阵...
    99+
    2022-11-12
  • Opencv实现倾斜图片转正示例
    今天是我们来玩一个钉子。通过一个钉子来学习一个opencv中的一个函数,这个函数我网上也有搜过,不过遗憾的是,各路好手都是写的是有点不堪入目,现在这个学习氛围是越来越差了,很多人都直...
    99+
    2022-11-11
  • Android自定义TextView实现文字倾斜效果
    前言 由于Android自带的TextView控件没有提供倾斜的(我暂时没有找到),我们可以自定义控件来实现,下面首先来看我们实现的效果图。 TextView文字倾斜 其实...
    99+
    2022-06-06
    Android
  • css怎么实现字体倾斜效果
    这篇文章主要讲解了“css怎么实现字体倾斜效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“css怎么实现字体倾斜效果”吧!首先,在页面中创建两个p标签,并添加文字用于对比;<!DOC...
    99+
    2023-07-04
  • OpenCV实现相机校正
    本文实例为大家分享了OpenCV实现相机校正的具体代码,供大家参考,具体内容如下 1. 相机标定 根据张正友校正算法,利用棋盘格数据校正对车载相机进行校正,计算其内参矩阵,外参矩阵和...
    99+
    2022-11-12
  • opencv实现图像校正
    本文实例为大家分享了opencv实现图像校正的具体代码,供大家参考,具体内容如下 1.引言:python实现倾斜图像校正操作 2.思路流程: (1)读入,灰度化;(2)高斯模糊;(3...
    99+
    2022-11-11
  • OpenCV实现相机校正的方法
    这篇文章主要介绍OpenCV实现相机校正的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体内容如下1. 相机标定根据张正友校正算法,利用棋盘格数据校正对车载相机进行校正,计算其内参矩阵,外参矩阵和畸变系数。标定...
    99+
    2023-06-15
  • opencv实现文档矫正
    本文实例为大家分享了opencv实现文档矫正的具体代码,供大家参考,具体内容如下 原始文档 矫正后文档 思路: 只要获得倾斜文档的倾斜角度,然后通过仿射变化旋转一下就可以实现矫正...
    99+
    2022-11-11
  • python中opencv实现文字分割的实践
    图片文字分割的时候,常用的方法有两种。一种是投影法,适用于排版工整,字间距行间距比较宽裕的图像;还有一种是用OpenCV的轮廓检测,适用于文字不规则排列的图像。 投影法 对文字图片作...
    99+
    2022-11-12
  • 怎么用C++ OpenCV实现文档矫正功能
    这篇文章主要介绍了怎么用C++ OpenCV实现文档矫正功能的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用C++ OpenCV实现文档矫正功能文章都会有所收获,下面我们一起来看看吧。需...
    99+
    2023-06-29
  • python实现图片加文字水印OPenCV和PIL库
    目录一:openCV给图片添加水印二:使用PIL给图片添加水印在python中我们可以使用openCV给图片添加水印,这里注意openCV无法添加汉字水印,添加汉字水印上可使用PIL...
    99+
    2022-11-12
  • python+opencv实现文字颜色识别与标定功能
            最近接了一个比较简单的图像处理的单子,花了一点时间随便写了一下:  数据集客户没有是自...
    99+
    2022-11-12
  • HTML写链接的时候如何实现始终将正斜杠添加到子文件夹减少HTTP请求
    这篇文章给大家分享的是有关HTML写链接的时候如何实现始终将正斜杠添加到子文件夹减少HTTP请求的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。因为如果子文件夹的末尾没有正斜杠,就会产生两次HTTP请求,就会对效率...
    99+
    2023-06-08
  • css如何实现从右往左读的文字正写竖排效果
    小编给大家分享一下css如何实现从右往左读的文字正写竖排效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!从右往左读的文字正写竖排效果.text {la...
    99+
    2023-06-27
  • 如何实现弹出一个遮罩层有正在加载效果的文字
    这篇文章主要讲解了“如何实现弹出一个遮罩层有正在加载效果的文字”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现弹出一个遮罩层有正在加载效果的文字”吧!...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作