我想将扫描的图像转换为黑白图像,目标是在图像通过互联网传输以进行 OCR 之前减小文件大小。
由扫描仪/通用图像编辑软件创建的正常二值化/黑白图像会产生不良结果。
留下许多随机黑色像素,这实际上只是二值化的噪声,这导致 OCR 尝试识别没有字符的字符,或者在字符后插入句号、冒号等。
我可以在 OpenCV 中使用什么来对图像进行二值化,保持线条、字符和暗区为实心,并减少白色区域中的像素噪声?
我玩过 cvThreshold 和 cvAdaptiveThreshold 但结果还不是很好。
我想将扫描的图像转换为黑白图像,目标是在图像通过互联网传输以进行 OCR 之前减小文件大小。
由扫描仪/通用图像编辑软件创建的正常二值化/黑白图像会产生不良结果。
留下许多随机黑色像素,这实际上只是二值化的噪声,这导致 OCR 尝试识别没有字符的字符,或者在字符后插入句号、冒号等。
我可以在 OpenCV 中使用什么来对图像进行二值化,保持线条、字符和暗区为实心,并减少白色区域中的像素噪声?
我玩过 cvThreshold 和 cvAdaptiveThreshold 但结果还不是很好。
你可以试试这个,但是你仍然需要调整一些参数。
#define ALPHA_SCALE 2
#define THRESHOLD_VAL 40
#define MAX_VAL_FOR_THRESHOLD 250
#define PIXEL_MISMATCH_COUNT 10 //9, 7
Mat current_frame_t2;
IplImage *img = cvLoadImage("Original.tiff", CV_LOAD_IMAGE_UNCHANGED );
cvNamedWindow("My_Win", CV_WINDOW_AUTOSIZE);
// namedWindow("My_Win", 1);
cvShowImage("My_Win", img);
cvWaitKey(10);
Mat current_frame_t1(img);
cvtColor(current_frame_t1, current_frame_t2, CV_RGB2GRAY);
current_frame_t1.release();
imshow("My_Win", current_frame_t2);
cvWaitKey(10);
equalizeHist(current_frame_t2, current_frame_t1);
current_frame_t2.release();
convertScaleAbs(current_frame_t1, current_frame_t2,ALPHA_SCALE);
threshold(current_frame_t2, current_frame_t1, THRESHOLD_VAL, MAX_VAL_FOR_THRESHOLD, CV_THRESH_BINARY);
medianBlur(current_frame_t1,current_frame_t2,1);
imshow("My_Win", current_frame_t2);
imwrite("outimg.tiff", current_frame_t2),
cvWaitKey(0);
您可以使用连接组件标记算法并删除未填充图像中合理数量像素的组件。
在 OpenCV 中实现它的一种非常简单的方法是使用轮廓:
1. Do the preliminary bizariztion of the OCR, that will give you a very noise output.
2. Find all contours on that noise image.
3. For each found contour:
3.1. Fill the contour with a color different of the two options in the binarized image.
3.2. Count the ammount of pixels filled with that color.
3.3. If the ammount of pixels are smaller than a given treshold, fill the contour with the void collor of the binary image.
供参考:cv::findContours和cv::drawContours。
可以优化在 3.1 上对多个轮廓进行分类的循环。并在 3.2 中对所有这些颜色进行一次像素计数。. 我没有使用优化版本,因为您可能有超过 253 个不同的组(255 种颜色 - 二进制图像的 2 种默认颜色),并且考虑到这一点并不是那么简单。