OpenCV二进制自适应阈值OCR [英] OpenCV binary adaptive threshold OCR

查看:207
本文介绍了OpenCV二进制自适应阈值OCR的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将一些图像转换为OCR二进制文件.

I need to convert some images to binary for OCR.

这是我正在使用的功能:

Here are the functions I am using:

Mat binarize(Mat & Img, Mat& res, float blocksize, bool inverse)
{
    Img.convertTo(Img,CV_32FC1,1.0/255.0);
    CalcBlockMeanVariance(Img,res, blocksize, inverse);
    res=1.0-res;
    res=Img+res;
    if (inverse) {
        cv::threshold(res,res,0.85,1,cv::THRESH_BINARY_INV);
    } else {
        cv::threshold(res,res,0.85,1,cv::THRESH_BINARY);
    }
    cv::resize(res,res,cv::Size(res.cols/2,res.rows/2));

    return res;
}

CalcBlockMeanVariance所在的位置:

void CalcBlockMeanVariance(Mat& Img,Mat& Res,float blockSide, bool inverse) //21 blockSide - the parameter (set greater for larger font on image)
{
    Mat I;
    Img.convertTo(I,CV_32FC1);
    Res=Mat::zeros(Img.rows/blockSide,Img.cols/blockSide,CV_32FC1);
    Mat inpaintmask;
    Mat patch;
    Mat smallImg;
    Scalar m,s;

    for(int i=0;i<Img.rows-blockSide;i+=blockSide)
    {
        for (int j=0;j<Img.cols-blockSide;j+=blockSide)
        {
            patch=I(Range(i,i+blockSide+1),Range(j,j+blockSide+1));
            cv::meanStdDev(patch,m,s);
            if(s[0]>0.01) // Thresholding parameter (set smaller for lower contrast image)
            {
                Res.at<float>(i/blockSide,j/blockSide)=m[0];
            }else
            {
                Res.at<float>(i/blockSide,j/blockSide)=0;
            }
        }
    }

    cv::resize(I,smallImg,Res.size());

    if (inverse) {
        cv::threshold(Res,inpaintmask,0.02,1.0,cv::THRESH_BINARY_INV);
    } else {
        cv::threshold(Res,inpaintmask,0.02,1.0,cv::THRESH_BINARY);
    }


    Mat inpainted;
    smallImg.convertTo(smallImg,CV_8UC1,255);

    inpaintmask.convertTo(inpaintmask,CV_8UC1);
    inpaint(smallImg, inpaintmask, inpainted, 5, INPAINT_TELEA);

    cv::resize(inpainted,Res,Img.size());
    Res.convertTo(Res,CV_32FC1,1.0/255.0);

}

当将1作为blockSide传递给CalcBlockMeanVariance时,我试图提高blockSide,但只会导致更差的结果.

When passing in 1 to CalcBlockMeanVariance as the blockSide I get this result, I have tried to raise the blockSide but it only results in worse results.

之前:

之后:

有人可以建议使用其他方法将该图像转换为二进制图像作为OCR的准备吗?

Can anyone suggest a different method for converting this image to binary as prep for OCR?

谢谢.

推荐答案

我认为您可以使用

I think you can do your thresholding using Otsu method. You can apply it on your whole image or on the blocks of the image. I did the following steps:

    在所需输入上使用Otsu方法的
  • 阈值.
  • Closing结果.
  • thresholding using Otsu method on desired input.
  • Closing the result.

Python代码

image = cv2.imread('image4.png', cv2.IMREAD_GRAYSCALE) # reading image
if image is None:
    print 'Can not find the image!'
    exit(-1)
# thresholding image using ostu method
ret, thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU) 
# applying closing operation using ellipse kernel
N = 3
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (N, N))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# showing the result
cv2.imshow('thresh', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()


说明

在第一部分中,我使用imread读取输入图像,并检查图像是否正确打开!.

In the first part I read the input image using imread and checked that the image opened correctly!.

image = cv2.imread('image4.png', cv2.IMREAD_GRAYSCALE) # reading image
if image is None:
    print 'Can not find the image!'
    exit(-1)

现在通过使用THRESH_BINARY_INV | THRESH_OTSU作为其参数输入thresh方法,使用otsu方法对图像进行阈值处理. otsu方法基于发现阈值的最佳值的优化问题而工作.因此,我通过给0下限和255上限提供了阈值的可能值范围.

Now thresholding the image with otsu method by feeding the thresh method with THRESH_BINARY_INV | THRESH_OTSU as its argument. The otsu method works base on an optimization problem finding the best value for thresholding. So I provided the range of possible value for the threshold value by giving it a lower bound by 0 and an upper bound by 255.

ret, thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)

然后使用Ellipse内核执行了关闭操作以去除图像中的黑洞.

And a closing operation is done for removing black holes in the image using an Ellipse kernel.

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (N, N))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)


结果

这篇关于OpenCV二进制自适应阈值OCR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆