利用OpenCV的功能可以方便快捷的将图片里面的文字纠正过来:

文章是参考国外帖子来写的:http://felix.abecassis.me/2011/09/opencv-detect-skew-angle/

这里有我的一些iOS, Mac代码和测试结果,可以方便的自动旋转文字方向,旋转图片。

图片有一些前提,或者处理缺陷:

1、图片没有外边框干扰

2、倒立或者竖着的图片,纠正后还是倒立,或者竖着的。

比如以下这2个图片,纠正后结果都不理想:

会旋转,但是纠正后会竖立,需要进一步判断。

计算的纠正角度为0,纠正失败。

方法一、利用线条横线计算角度,然后再纠正。

// 参考 Félix Abecassis - OpenCV - Detect skew angle
// http://felix.abecassis.me/2011/09/opencv-detect-skew-angle/
+ (double)cvMatImageSkewAngleUsingSHT:(cv::Mat)gray;
{// Load in grayscale.//cv::Mat src = cv::imread(filename, cv::IMREAD_GRAYSCALE);if(gray.data == NULL){fprintf(stderr, "error: src.data == NULL\n");return 0.0f;}if(gray.channels() != 1){fprintf(stderr, "error: src.channels() != 1\n");return 0.0f;}cv::bitwise_not(gray, gray);cv::Size size = gray.size();// 需要的是黑色背景std::vector<cv::Vec4i> lines;cv::HoughLinesP(gray, lines, 1, CV_PI/180, 100, size.width / 2.f, 20);cv::Mat disp_lines(size, CV_8UC1, cv::Scalar(0, 0, 0));double angle = 0.;unsigned nb_lines = lines.size();for (unsigned i = 0; i < nb_lines; ++i){cv::line(disp_lines, cv::Point(lines[i][0], lines[i][1]), cv::Point(lines[i][2], lines[i][3]), cv::Scalar(255, 0 ,0));angle += atan2((double)lines[i][3] - lines[i][1], (double)lines[i][2] - lines[i][0]);}angle /= nb_lines; // mean angle, in radians.angle = angle * 180 / CV_PI;cv::imwrite("/Users/James/Desktop/skew-lines.bmp", disp_lines);fprintf(stderr, "ImageSkewAngle result: %f\n", angle);return angle;
}

方法二、利用文字最小区域获取矩形计算角度,然后再纠正。

// 参考 Félix Abecassis - OpenCV - Bounding Box & Skew Angle
// http://felix.abecassis.me/2011/10/opencv-bounding-box-skew-angle/
+ (double)cvMatImageSkewAngleWithImageBin:(cv::Mat)image_bin
{// 输入的是黑底白字图片cv::Mat image = image_bin.clone();if(image.data == NULL){fprintf(stderr, "error: src.data == NULL\n");return 0.0f;}if(image.channels() != 1){fprintf(stderr, "error: src.channels() != 1\n");return 0.0f;}cv::imwrite("/Users/James/Desktop/skew-bin.bmp", image);// Size(23, 3)); Size(5, 3));,使用Size(3, 3)最好cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));// 最基本的形态学操作有二:腐蚀与膨胀(Erosion 与 Dilation)cv::erode(image, image, element);cv::imwrite("/Users/James/Desktop/skew-erode.bmp", image);std::vector<cv::Point> points;cv::Mat_<uchar>::iterator it = image.begin<uchar>();cv::Mat_<uchar>::iterator end = image.end<uchar>();for (; it != end; ++it)if (*it)points.push_back(it.pos());cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));double angle = box.angle;if (angle < -45.)angle += 90.;if(1){cv::Point2f vertices[4];box.points(vertices);for(int i = 0; i < 4; ++i)cv::line(image, vertices[i], vertices[(i + 1) % 4], cv::Scalar(255, 0, 0), 1, CV_AA);cv::imwrite("/Users/James/Desktop/skew-rect.bmp", image);}fprintf(stderr, "ImageSkewAngle result: %f\n", angle);return angle;
}+ (double)cvMatImageSkewAngleWithImageGray:(cv::Mat)image_gray
{// 输入的是灰度图片// Load in grayscale.//cv::Mat img = cv::imread(filename, cv::IMREAD_GRAYSCALE);cv::Mat image = image_gray.clone();if(image.data == NULL){fprintf(stderr, "error: src.data == NULL\n");return 0.0f;}if(image.channels() != 1){fprintf(stderr, "error: src.channels() != 1\n");return 0.0f;}//中值滤波器是一种非线性滤波器,常用于消除图像中的椒盐噪声。与低通滤波不同的是,中值滤波有利于保留边缘的尖锐度,但它会洗去均匀介质区域中的纹理。//cv::medianBlur(img, img, 3);//cv::GaussianBlur(img, img, cv::Size(3, 3), 0);//GaussianBlur(img, img, cvSize(11,11), 0);//change from median blur to gaussian for more accuracy of square detection// Binarize//cv::threshold(img, img, 225, 255, CV_THRESH_BINARY_INV);cv::threshold(image, image, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY_INV); // 二值化效果好return [RecognitionManager cvMatImageSkewAngleWithImageBin:image];
}

最后是纠正图片的方法:

// 参考 Félix Abecassis - OpenCV - Rotation (Deskewing)
// http://felix.abecassis.me/2011/10/opencv-rotation-deskewing/
+ (cv::Mat)cvMatImageDeskew:(cv::Mat)src angle:(double)angle;
{cv::Mat img = src.clone();cv::imwrite("/Users/James/Desktop/deskew-src.bmp", img);cv::Mat cropped;cv::Mat rotated;// Load in grayscale.//cv::Mat img = cv::imread(filename, cv::IMREAD_GRAYSCALE);if(img.data == NULL){fprintf(stderr, "error: src.data == NULL");return rotated;}if(img.channels() != 1){fprintf(stderr, "error: src.channels() != 1");return rotated;}std::vector<cv::Point> points;cv::Mat_<uchar>::iterator it = img.begin<uchar>();cv::Mat_<uchar>::iterator end = img.end<uchar>();for (; it != end; ++it)if (*it)points.push_back(it.pos());cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));cv::Mat rot_mat = cv::getRotationMatrix2D(box.center, angle, 1);// 旋转cv::warpAffine(img, rotated, rot_mat, img.size(), cv::INTER_CUBIC); // 默认是黑色背景//cv::warpAffine(img, rotated, rot_mat, img.size(), CV_INTER_CUBIC, cv::BORDER_CONSTANT, cvScalarAll(0)); // 黑色背景//cv::warpAffine(img, rotated, rot_mat, img.size(), cv::INTER_CUBIC, cv::BORDER_CONSTANT, cvScalar(255, 255, 255)); // 白色背景cv::imwrite("/Users/James/Desktop/deskew-rotated.bmp", rotated);if(0){// 切割cv::Size box_size = box.size;if (box.angle < -45.)std::swap(box_size.width, box_size.height);cv::getRectSubPix(rotated, box_size, box.center, cropped);cv::imwrite("/Users/James/Desktop/deskew-cropped.bmp", cropped);}return rotated;}

测试代码:

- (void)deskew
{if(1){cv::Mat gray_image = [RecognitionManager cvMatImageFromCGImageRef_Grayscale:[[imageView image] CGImage_FPLib]];//double angle = [RecognitionManager cvMatImageSkewAngleWithImageGray:gray_image];double angle = [RecognitionManager cvMatImageSkewAngleUsingSHT:gray_image];cv::Mat img_deskew;img_deskew = [RecognitionManager cvMatImageDeskew:gray_image angle:angle];imageView.image = [NSImage imageWithCGImage_FPLib:[RecognitionManager CGImageRefFromCVMat:img_deskew]];}}

测试结果:

原图:

方法一、

方法二:

更多测试:

原图:

方法二结果:

结果是误旋转了:-(。

可以看出,方法一、对于边框有干扰,无法正确纠正。

方法二、要比方法一适应性强,但是也有边框干扰,都会有一些误操作。

其实还有一种方法就是利用findContours查找最大边框,然后利用图片裁剪函数纠正。

https://stackoverflow.com/questions/8667818/opencv-c-obj-c-detecting-a-sheet-of-paper-square-detection?noredirect=1&lq=1

OpenCV - 自动纠正图片的文字倾斜相关推荐

  1. python opencv 如何给图片添加文字?cv2.putText() PIL

    参考文章1:python如何在图片上添加文字(中文和英文)Python在图片上添加文字的两种方法:OpenCV和PIL 参考文章2:python之------如何在图片上面添加文字(多种类型的文字)[ ...

  2. 趣味应用 | 用OpenCV自动给图片添加彩虹特效---平淡的生活需要技术的点缀

    点击下方卡片,关注"OpenCV与AI深度学习"公众号! 视觉/图像重磅干货,第一时间送达! 导读 本文主要介绍如何使用OpenCV给图片和视频添加彩虹特效,给平淡的生活增添点色彩 ...

  3. 【Opencv实战】趣味应用 | 用OpenCV自动给图片添加虚拟特效---平淡的生活需要技术的点缀~

    前言

  4. php验证码只有图片没有文字_有没有免费好用的图片文字识别工具?在线就能使用超准确...

    一款真正好用的图片文字识别软件,需要的不仅仅是能识别印刷字体,手写字体如果也能胜任的话,才能得到认同! 而小编要推荐的这款图片文字识别工具,在提升了文字识别准确度的同时,还对软件功能进行了优化.旧有的 ...

  5. 手机端有没有好用的图片识别文字工具值得推荐?

    图片转文字,用到的就是OCR识别技术,针对网络上复杂字体实现精确识别功能,经常用于社交.电商.学习等场景.传统的将图片识别文字的方式选择手动书写,随着AI智能技术的应用,以OCR智能识别工具由于使用简 ...

  6. 将文件夹中的所有图片插入到Excel的单元格批注中,自动修正图片方向

    需求概述 文件夹中有若干图片,要求将所有图片插入到Excel的单元格批注中. 插入图片到批注中时,要求允许自定义图片的高度,按需调节尺寸. 解决办法一 使用"Excel插件E灵"可 ...

  7. Python OpenCV 自动生成快乐源泉小瓶子图片(OpenCV中文写字)

    目的 空间看到很多小瓶子,大部分是由P图产生的,会影响图片清晰和质量,而且速度较慢.所以打算使用OpenCV自动生成 步骤 瓶子 没有找到单独的瓶子原图,所以截取了一个,有很多的噪点和不清晰,所以Op ...

  8. c++ 调用opencv+tesseract做图片文字识别

    2020年12月28日22:08:08 环境:windows10 vscode cmake vcpkg vcpkg install opencv vcpkg install tesseract 参考手 ...

  9. opencv怎么在图片上添加文字?

    在 OpenCV 中,可以使用 cv2.putText() 函数在图像上添加文本.这个函数需要指定文本.文本位置.字体.字体比例.颜色.线宽等参数. opencv怎么在图片上添加文字? 下面是一个示例 ...

最新文章

  1. 什么是Busybox,简单使用
  2. SpaceX再送4人上太空,马斯克保证这次飞船厕所不会漏了
  3. SRM 721 DIV2
  4. php 字符串包含另一个字符串_leetcode1433_go_检查一个字符串是否可以打破另一个字符串...
  5. linux下51单片机开发解决方案
  6. C#-文件操作类 Directory 109
  7. 开启MSDTC的方法
  8. 【转】Android加密算法:AES、Base64加密算法
  9. git代码库迁移保留commit历史_svn 迁移到 git 仓库并保留 commit 历史记录
  10. 2018-2019-1 20165320 20165325 20165337 实验一 开发环境的熟悉
  11. Python3 不能直接导入reduce
  12. Mac 连不上华为 p9 处理历程(一)
  13. SqlParameter类中的两对好基友:SqlDbType与DbType、SqlValue与Value
  14. 中文版-动手学深度学习
  15. 领导与管理的区别与联系
  16. go mysql打印sql语句
  17. 详解ARM的AMBA设备中的DMA设备(Linux驱动之DMA)
  18. 高分影像批处理第一回——数据格式分析与整理
  19. samba 配置文件详解
  20. java web jsp页面跳转,【体育竞投网】-√[官网线路检测]

热门文章

  1. 写给程序员的UI设计书 (转) (二)
  2. Bugly SDK 集成使用
  3. 深度剖析移动游戏市场,论产品、研发、买量
  4. enumerate函数、self参数错误
  5. Themida是否支持PowerBuilder应用程序的保护?—— Themida常见问答集锦
  6. 关于嵌入式工程师薪资待遇
  7. 一份好的简历需要包含的内容(程序员)
  8. java学习网站http://how2j.cn/
  9. 美欧股市周一综述:美国股市走低,欧洲股市上涨
  10. 利用OVITO软件绘制团簇构型 (ICO, BCC, HCP, FCC及SC 多面体)