2015-12-01 33 views
1

我是OpenCV的新手,我看到很多OpenCV文本提取的解决方案,但没有一个解决了我的问题。我正在使用visual studio 2013与tesseract OCR,C++和OpenCV。OpenCV中的文本提取OpenCV

我的问题是从倾斜的图像中提取文本。这里是一个我想去倾斜的示例图片,我需要提取整个文本。 enter image description here

+0

http://felix.abecassis.me/2011/09/opencv-detect-skew-angle/ 。这不适用于我已经看到它的问题。 –

回答

2

您可以看到本教程检测图像中的倾斜角度并处理它们。本教程彻底说明了如何解决你的问题:

http://felix.abecassis.me/2011/09/opencv-detect-skew-angle/

包括下面的链接教程JIST:

实现与OpenCV的

首先,让我们来声明一个函数compute_skew,它以图像的路径作为输入,并将检测到的角度输出到标准输出。 首先我们加载图像并将其大小存储在变量中,非常简单。

void compute_skew(const char* filename) 
{ 
    // Load in grayscale. 
    cv::Mat src = cv::imread(filename, 0); 
    cv::Size size = src.size(); 

在图像处理中,对象是白色,背景是黑色的,我们有相反,我们需要反转我们的图像的颜色:

cv::bitwise_not(src, src); 

,这里是结果:

enter image description here

为了计算偏斜,我们必须在文本中找到直线。在文本行中,我们并排放置几个字母,因此应该通过在图像中查找长长的白色像素来形成线条。这是下面一个例子:

enter image description here

当然作为人物有一个高度,我们发现几行从文本中的每个实际线路。通过稍后使用的参数或使用预处理,我们可以减少行数。

那么,我们如何找到图像中的行?我们使用一种称为霍夫变换的强大数学工具。我不会深入研究数学细节,但霍夫变换的主要思想是使用2D累加器来计算图像中发现给定线条的次数,整个图像被扫描并通过投票系统确定了“最佳”线。 我们使用了称为概率霍夫变换(PHT)的标准霍夫变换(SHT)的更高效变体。在OpenCV中,PHT是以HoughLinesP的名称实现的。

除霍夫变换的标准参数变换,我们有两个附加参数:

minLineLength - 最低行的长度。比这更短的线段将被拒绝。这是一个很好的工具,以删除小的残留线。 maxLineGap - 同一行上的点之间允许的最大间隙以链接它们。 这对于多列文本可能很有趣,例如我们可以选择不链接来自不同文本列的行。 现在回到C++,在OpenCV中,PHT存储线的端点,而SHT将线存储在极坐标(相对于原点)中。我们需要一个矢量以存储所有的终点:

std::vector<cv::Vec4i> lines; 

我们准备霍夫现在变换:

cv::HoughLinesP(src, lines, 1, CV_PI/180, 100, size.width/2.f, 20); 

我们使用的1的步长为ρ和π/ 180为θ,阈值(最小投票数)是100. minLineLength是宽度/ 2,如果文本很好地隔离,这不是一个不合理的假设。 maxLineGap是20,它似乎是一个差距的声音值。

在剩下的代码中,我们使用atan2数学函数简单计算每条线与水平线之间的角度,然后计算所有线的平均角度。 为了进行调试,我们还在一个名为disp_lines的新图像中绘制了所有的线条,并在新窗口中显示此图像。

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. 

    std::cout << "File " << filename << ": " << angle * 180/CV_PI << std::endl; 

    cv::imshow(filename, disp_lines); 
    cv::waitKey(0); 
    cv::destroyWindow(filename); 
} 

我们只需要一个主要功能,以调用compute_skew几个图片:

const char* files[] = { "m8.jpg", "m20.jpg", "p3.jpg", "p16.jpg", "p24.jpg"}; 

int main() 
{ 
    unsigned nb_files = sizeof(files)/sizeof(const char*); 
    for (unsigned i = 0; i < nb_files; ++i) 
     compute_skew(files[i]); 
} 
+0

尽管这个链接可能回答这个问题,但最好在这里包含答案的重要部分,并提供参考链接。如果链接页面更改,则仅链接答案可能会失效。 - [来自评论](/ review/low-quality-posts/10401352) –

+0

感谢您的想法我编辑了答案 –

+0

这不适合我,我已经看到了。 –