【问题标题】:iOS + Tesseract Ocr + OpenCViOS + 正方体 Ocr + OpenCV
【发布时间】:2013-02-08 02:53:25
【问题描述】:

我为 ios 编写了一个数字 OCR。 我有一个带有两位数字 5 和 4 的测试图像 png。 我找到了轮廓。如何在 tesseract 转移轮廓一?

初始化正方体:

    tess = new tesseract::TessBaseAPI();
    tess->Init([dataPath cStringUsingEncoding:NSUTF8StringEncoding], "eng");
    tess->SetPageSegMode(tesseract::PSM_SINGLE_CHAR); //<-- !!!!
    tess->tesseract::TessBaseAPI::SetVariable("tessedit_char_whitelist", "0123456789");

轮廓检测功能:

- (std::vector<std::vector<cv::Point> >)findSquaresInImage:(cv::Mat)_image {
std::vector<std::vector<cv::Point> > squares;
cv::Mat pyr, timg, gray0(_image.size(), CV_8U), gray;
int thresh = 50, N = 11;
cv::pyrDown(_image, pyr, cv::Size(_image.cols/2, _image.rows/2));
cv::pyrUp(pyr, timg, _image.size());
std::vector<std::vector<cv::Point> > contours;
    int ch[] = {0, 0};
    mixChannels(&timg, 1, &gray0, 1, ch, 1);
    for( int l = 0; l < N; l++ ) {
        if( l == 0 ) {
            cv::Canny(gray0, gray, 0, thresh, 5);
            cv::dilate(gray, gray, cv::Mat(), cv::Point(-1,-1));
        }
        else {
            gray = gray0 >= (l+1)*255/N;
        }
        cv::findContours(gray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
        std::vector<cv::Point> approx;

        CvRect rec1;
        std::string str;
        std::map<int,IplImage*> pic_list;

        for( size_t i = 0; i < contours.size(); i++ )
        {

            rec1 = cv::boundingRect(contours[i]);

            if (rec1.height > 0.5*gray.rows && rec1.width < 0.756*gray.cols) {
                NSLog(@"%d %d %d %d", rec1.width, rec1.height, rec1.x, rec1.y);
                cv::approxPolyDP(cv::Mat(contours[i]), approx, arcLength(cv::Mat(contours[i]), true)*0.02, true);
                squares.push_back(approx);
            }
        }
    }

return squares;  }

绘制轮廓函数:

cv::Mat debugSquares( std::vector<std::vector<cv::Point> > squares, cv::Mat image ) {
for ( int i = 0; i< squares.size(); i++ ) {
    // draw contour
    cv::drawContours(image, squares, i, cv::Scalar(255,0,0), 1, 8, std::vector<cv::Vec4i>(), 0, cv::Point());

    // draw bounding rect
    cv::Rect rect = boundingRect(cv::Mat(squares[i]));
    cv::rectangle(image, rect.tl(), rect.br(), cv::Scalar(0,255,0), 2, 8, 0);

    // draw rotated rect
    cv::RotatedRect minRect = minAreaRect(cv::Mat(squares[i]));
    cv::Point2f rect_points[4];
    minRect.points( rect_points );
    for ( int j = 0; j < 4; j++ ) {
        cv::line( image, rect_points[j], rect_points[(j+1)%4], cv::Scalar(0,0,255), 1, 8 ); // blue
    }
}

return image;
}

btn 点击方法:

- (IBAction)onMath:(id)sender {
    UIImage *image = [UIImage imageNamed:@"test1.png"];

    cv::Mat iMat = [self cvMatFromUIImage:image];
    std::vector<std::vector<cv::Point> > sq = [self findSquaresInImage:iMat];
    cv::Mat hui = debugSquares(sq, iMat);

    image = [self UIImageFromCVMat:hui];
    self.imView.image = image;
}

之后的图片:

github上的项目链接:https://github.com/MaxPatsy/iORC

【问题讨论】:

  • 您可以使用 SetImage 然后使用 SetRectangle 只使用轮廓边界框;你知道如何给 tesseract 一个它可以读取的图像吗?
  • 你能更新你的问题吗? github 用户/项目在 Internet 存档上被删除,没有任何痕迹。我能找到的最佳相关链接是cyberforum.ru/ios-dev/thread788840.html

标签: ios objective-c opencv ocr tesseract


【解决方案1】:

你能检查这个答案here

我在这里描述了一些为 Tesseract 准备图像的技巧:使用 tesseract 识别车牌

在您的示例中,发生了几件事...

您需要将文本设置为黑色,将图像的其余部分设置为白色(而不是相反)。这就是字符识别的重点。灰度是可以的,只要背景多为全白,文字多为全黑即可;文本的边缘可能是灰色的(抗锯齿),这可能有助于识别(但不一定 - 你必须尝试)

您看到的其中一个问题是,在图像的某些部分,文字真的很“薄”(并且在阈值处理后出现了字母中的间隙),而在其他部分,它真的很“厚”(和字母开始合并)。 Tesseract 不喜欢这样 :) 发生这种情况是因为输入图像的光照不均匀,因此单个阈值并不适用于任何地方。解决方案是执行“局部自适应阈值”,其中为图像的每个邻域计算不同的阈值。有很多方法可以做到这一点,但请查看以下示例:

OpenCV 中使用 cv2.adaptiveThreshold(...,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,...) 的自适应高斯阈值 当地大津法 局部自适应直方图均衡 您遇到的另一个问题是线条不直。根据我的经验,Tesseract 可以处理非常有限程度的非直线(百分之几的透视失真、倾斜或歪斜),但它实际上不适用于波浪线。如果可以,请确保源图像具有直线 :) 不幸的是,对此没有简单的现成答案;您必须查看研究文献并自己实现一种最先进的算法(如果可能的话,开源它 - 确实需要一个开源解决方案)。 Google Scholar 搜索“曲线 OCR 提取”将帮助您入门,例如:

弯曲文档图像的文本行分割 最后:我认为使用 python 生态系统(ndimage、skimage)比使用 C++ 中的 OpenCV 会做得更好。 OpenCV python 包装器适用于简单的东西,但对于你想要做的事情,它们不会完成这项工作,你需要抓取许多不在 OpenCV 中的部分(当然你可以混合和匹配)。在 C++ 中实现曲线检测之类的东西将比在 python 中长一个数量级(* 即使你不了解 python,也是如此)。

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-10
    • 2015-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多