Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从倾斜图像OpenCV中提取文本_C++_Opencv_Visual Studio 2013_Tesseract - Fatal编程技术网

C++ 从倾斜图像OpenCV中提取文本

C++ 从倾斜图像OpenCV中提取文本,c++,opencv,visual-studio-2013,tesseract,C++,Opencv,Visual Studio 2013,Tesseract,我是OpenCV的新手,我见过许多通过OpenCV提取文本的解决方案,但没有一个解决了我的问题。我使用Visual Studio 2013与TestSerACT OCR、C++和OpenCV。< /P> 我的问题是从倾斜的图像中提取文本。这里是一个示例图像,我想反扭曲,我需要提取整个文本 您可以查看本教程来检测图像中的倾斜角度并对其进行处理。本教程完全说明了如何解决您的问题: 包括以下链接教程的jist: 用OpenCV实现 首先,让我们声明一个函数compute_skew,它将图像的路径作为

我是OpenCV的新手,我见过许多通过OpenCV提取文本的解决方案,但没有一个解决了我的问题。我使用Visual Studio 2013与TestSerACT OCR、C++和OpenCV。< /P>
我的问题是从倾斜的图像中提取文本。这里是一个示例图像,我想反扭曲,我需要提取整个文本

您可以查看本教程来检测图像中的倾斜角度并对其进行处理。本教程完全说明了如何解决您的问题:

包括以下链接教程的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);
结果如下:

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

当然,由于字符有一个高度,我们可以为文本中的每一行找到几行。通过微调稍后使用的参数或使用预处理,我们可以减少行数

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

除了Hough变换的标准参数外,我们还有两个附加参数:

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

std::vector<cv::Vec4i> lines;
对于ρ,我们使用1的步长,对于θ,使用π/180,阈值(最小投票数)是100。 minLineLength是width/2,如果文本被很好地隔离,这不是一个不合理的假设。 maxLineGap是20,它似乎是一个音高值

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

    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);
}
cv::Mat disp_行(大小,cv_8UC1,cv::Scalar(0,0,0));
双角度=0。;
无符号nb_行=行。大小();
对于(无符号i=0;i    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);
}
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]);
}