opencv2.4.13文本分割(文字大小不一致的情形,存在旋转的情形)
2017-12-14 20:02
281 查看
问题:如果文字大小存在比较大的差异时,怎么办?
答:这里给出另外一种策略,不是使用投影直方图,而是使用膨胀以及寻找连通区域。进行分割。
1)对图像二值化
2)对二值化之后的图像进行膨胀操作(dilate)
3)在2)得到的结果上寻找联通区域的边界(findContours)。
4)利用3)得到的结果画出方框。
本文是对这里的文章的另一种实现。使用C++。
首先,读取图片
第一步:1)对图像二值化
第二步:2)对二值化之后的图像进行膨胀操作(dilate)
腐蚀之后的结果:
问题:getStructuringElement是一个什么样的存在?
答:获取形态学滤波中使用的“结构元”
问题:dilate表示什么意思?
答:对图像进行“膨胀”操作
问题:是否有其他形态学算法?
答:有,比如腐蚀(erode),开(open),。。。
还有一个高大上的函数“morphologyEx”,只需要在其中选择参数就可以实现各种形态学操作。
第三步:3)在2)得到的结果上寻找联通区域的边界(findContours)。
第四步:4)利用3)得到的结果画出方框。
找出的边界结果:
最后的方框结果:
问题:vector< vector> contours; 是什么鬼?好可怕
答:见这里。
问题:如果文字存在旋转,怎么办?比如下面这张图
答:在代码中有一段“// 如果有旋转的话,需要使用下面的方法画出旋转的方框”,这一段就是处理旋转的情况的。
对上图的处理结果如下:
放大招,整体代码如下:
答:这里给出另外一种策略,不是使用投影直方图,而是使用膨胀以及寻找连通区域。进行分割。
1)对图像二值化
2)对二值化之后的图像进行膨胀操作(dilate)
3)在2)得到的结果上寻找联通区域的边界(findContours)。
4)利用3)得到的结果画出方框。
本文是对这里的文章的另一种实现。使用C++。
首先,读取图片
Mat img = imread(IMG_PATH); if (img.empty()) { cerr<<"can not read image"<<endl; } imshow("original image", img); Mat img_erode = img.clone();
第一步:1)对图像二值化
第二步:2)对二值化之后的图像进行膨胀操作(dilate)
void step_1_erode(Mat& img){ cvtColor(img,img,CV_BGR2GRAY,1); threshold(img,img,90,255,THRESH_OTSU); img = 255 - img; imshow("after otsu",img); Mat ker = Mat::ones(3,7,CV_8U); //Mat ker = getStructuringElement(MORPH_ELLIPSE,Size(3,3)); dilate(img,img,ker,Point(0,1)); imshow("after dilate",img); }
腐蚀之后的结果:
问题:getStructuringElement是一个什么样的存在?
答:获取形态学滤波中使用的“结构元”
问题:dilate表示什么意思?
答:对图像进行“膨胀”操作
问题:是否有其他形态学算法?
答:有,比如腐蚀(erode),开(open),。。。
还有一个高大上的函数“morphologyEx”,只需要在其中选择参数就可以实现各种形态学操作。
第三步:3)在2)得到的结果上寻找联通区域的边界(findContours)。
第四步:4)利用3)得到的结果画出方框。
void step_2_find_conection(const Mat& original_img, Mat& img_erode){ // find contours of img vector<vector<Point>> contours; findContours(img_erode,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE); Scalar color = Scalar(0,0,255); // 在原图上画出边界 Mat img1 = original_img.clone(); drawContours(img1,contours,-1,color); imshow("img with contours",img1); // 在原图上画出,包括边界的最大矩形 Mat img2 = original_img.clone(); Rect ri; vector<vector<Point>>::iterator itcon; for (itcon = contours.begin(); itcon != contours.end(); itcon++) { ri = boundingRect(*itcon); if (ri.height >10 && (ri.width * 1.0 / ri.height) > 0.2) rectangle(img2,ri,color); } imshow("img with rectangle",img2); // 如果有旋转的话,需要使用下面的方法画出旋转的方框 Mat img3 = original_img.clone(); vector<RotatedRect> minRect(contours.size()); for (int i = 0; i < contours.size(); i++){ minRect[i] = minAreaRect(Mat(contours[i])); Point2f rect_points[4]; minRect[i].points(rect_points); for (int j = 0; j < 4; j++) line(img3,rect_points[j],rect_points[(j+1)%4],color,1,8); } imshow("img with rotated rectangle",img3); }
找出的边界结果:
最后的方框结果:
问题:vector< vector> contours; 是什么鬼?好可怕
答:见这里。
问题:如果文字存在旋转,怎么办?比如下面这张图
答:在代码中有一段“// 如果有旋转的话,需要使用下面的方法画出旋转的方框”,这一段就是处理旋转的情况的。
对上图的处理结果如下:
放大招,整体代码如下:
// csdn_code.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
#define IMG_PATH "..//figures//222_angle.jpg"
void step_1_erode(Mat& img){ cvtColor(img,img,CV_BGR2GRAY,1); threshold(img,img,90,255,THRESH_OTSU); img = 255 - img; imshow("after otsu",img); Mat ker = Mat::ones(3,7,CV_8U); //Mat ker = getStructuringElement(MORPH_ELLIPSE,Size(3,3)); dilate(img,img,ker,Point(0,1)); imshow("after dilate",img); }
void step_2_find_conection(const Mat& original_img, Mat& img_erode){ // find contours of img vector<vector<Point>> contours; findContours(img_erode,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE); Scalar color = Scalar(0,0,255); // 在原图上画出边界 Mat img1 = original_img.clone(); drawContours(img1,contours,-1,color); imshow("img with contours",img1); // 在原图上画出,包括边界的最大矩形 Mat img2 = original_img.clone(); Rect ri; vector<vector<Point>>::iterator itcon; for (itcon = contours.begin(); itcon != contours.end(); itcon++) { ri = boundingRect(*itcon); if (ri.height >10 && (ri.width * 1.0 / ri.height) > 0.2) rectangle(img2,ri,color); } imshow("img with rectangle",img2); // 如果有旋转的话,需要使用下面的方法画出旋转的方框 Mat img3 = original_img.clone(); vector<RotatedRect> minRect(contours.size()); for (int i = 0; i < contours.size(); i++){ minRect[i] = minAreaRect(Mat(contours[i])); Point2f rect_points[4]; minRect[i].points(rect_points); for (int j = 0; j < 4; j++) line(img3,rect_points[j],rect_points[(j+1)%4],color,1,8); } imshow("img with rotated rectangle",img3); }
int main()
{
Mat img = imread(IMG_PATH);
if (img.empty())
{
cerr<<"can not read image"<<endl;
}
imshow("original image", img);
Mat img_erode = img.clone();
step_1_erode(img_erode);
step_2_find_conection(img,img_erode);
waitKey();
system("pause");
return 0;
}
相关文章推荐
- Python + OpenCV实现基于傅里叶变换(FFT)的旋转文本校正(文字方向检测)
- OpenCV2.4.13 文本分割(水平垂直,直方图投影)
- 如何旋转在Visio中的文字(或文本)
- 仿快手编辑视频页面添加贴纸和文字,有移动、旋转、放大、文字大小自动适应的功能
- Android EditText 中hint文字大小以及与输入文字颜色保存一致
- 移动端多行文本在横向屏和竖向屏下如何保持字号大小一致
- OpenCV实现基于傅里叶变换的旋转文本校正
- [置顶] Android 开发 Tip 11 -- TabLayout 设置文字大小一致
- 利用OpenCV实现旋转文本图像矫正的原理及OpenCV代码
- OpenCV基于傅里叶变换进行文本的旋转校正 推荐
- OpenCV实现基于傅里叶变换的旋转文本校正
- OpenCV实现基于傅里叶变换的旋转文本校正
- python-opencv 旋转文本校正
- python+opencv图片旋转矩形分割
- OpenCV-基于傅里叶变换的旋转文本图像矫正实现
- OpenCV基于傅里叶变换进行文本的旋转校正
- 【OpenCV】一种基于阈值的图片中的文字分割
- Java 组件及事件处理实训 实训1: 编写一个窗体程序,能够对文本区中的文字设置字体和大小。
- OpenCv调整图像大小及仿射变换(旋转)
- html文本分割文字和图片