[英]OpenCV binary adaptive threshold OCR
I need to convert some images to binary for OCR.我需要将一些图像转换为二进制以进行 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;
}
Where CalcBlockMeanVariance
:其中
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);
}
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.当将
1
作为blockSide
传递给CalcBlockMeanVariance
,我得到了这个结果,我试图提高blockSide
但它只会导致更糟的结果。
Before:前:
After:后:
Can anyone suggest a different method for converting this image to binary as prep for OCR?任何人都可以建议一种不同的方法来将此图像转换为二进制作为 OCR 的准备吗?
Thanks.谢谢。
I think you can do your thresholding using Otsu method.我认为您可以使用Otsu方法进行阈值处理。 You can apply it on your whole image or on the blocks of the image.
您可以将其应用于整个图像或图像块。 I did the following steps:
我做了以下步骤:
Otsu
method on desired input.Otsu
方法对所需输入进行阈值处理。Closing
the result. Closing
结果。 Python Code 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()
Explanation解释
In the first part I read the input image using imread
and checked that the image opened correctly!.在第一部分中,我使用
imread
读取输入图像并检查图像是否正确打开!。
image = cv2.imread('image4.png', cv2.IMREAD_GRAYSCALE) # reading image
if image is None:
print 'Can not find the image!'
exit(-1)
Now thresholding the image with otsu
method by feeding the thresh
method with THRESH_BINARY_INV | THRESH_OTSU
现在阈值处理与图像
otsu
喂养方法thresh
与方法THRESH_BINARY_INV | THRESH_OTSU
THRESH_BINARY_INV | THRESH_OTSU
as its argument. THRESH_BINARY_INV | THRESH_OTSU
作为其参数。 The otsu
method works base on an optimization problem finding the best value for thresholding. otsu
方法基于一个优化问题来寻找阈值的最佳值。 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
.因此,我通过给阈值下限
0
和上限255
来提供阈值的可能值范围。
ret, thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
And a closing operation is done for removing black holes in the image using an Ellipse
kernel.并且使用
Ellipse
内核完成关闭操作以去除图像中的黑洞。
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (N, N))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
Result结果
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.