cv2.adaptiveThreshold(...,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,...)
- 局部 Otsu 方法
- 局部自适应直方图均衡化
另一个问题是,这些行不是直的。在我的经验中,Tesseract可以处理非常有限程度的非直线(一些透视畸变、倾斜或扭曲),但它无法处理波浪形的线条。如果可能的话,请确保源图像具有直线:)不幸的是,对于这个问题,没有简单的现成答案;您需要研究文献并自己实现最先进的算法之一(如果可能的话,开源 - 这方面真的需要一个开源解决方案)。例如,使用Google Scholar搜索“曲线线OCR提取”即可开始查找:
最后:我认为与使用C++的OpenCV相比,您最好使用Python生态系统(ndimage,skimage)进行工作。 OpenCV Python包装器对于简单的东西来说还可以,但对于您要尝试的内容,它们无法胜任,您需要获取许多不在OpenCV中的组件(当然,您可以混合和匹配)。 在C ++中实现诸如曲线线检测之类的东西将需要比Python长一个数量级的时间(*即使您不知道Python也是如此)。
以300 dpi(每英寸点数)的分辨率扫描不是正式的OCR(光学字符识别)标准,但被认为是黄金标准。
将图像转换为灰度有助于提高一般文本阅读精度。
我编写了一个模块,可以读取图片中的文本,并对图像进行处理以获得最佳的OCR结果,Image Text Reader 。
import tempfile
import cv2
import numpy as np
from PIL import Image
IMAGE_SIZE = 1800
BINARY_THREHOLD = 180
def process_image_for_ocr(file_path):
# TODO : Implement using opencv
temp_filename = set_image_dpi(file_path)
im_new = remove_noise_and_smooth(temp_filename)
return im_new
def set_image_dpi(file_path):
im = Image.open(file_path)
length_x, width_y = im.size
factor = max(1, int(IMAGE_SIZE / length_x))
size = factor * length_x, factor * width_y
# size = (1800, 1800)
im_resized = im.resize(size, Image.ANTIALIAS)
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.jpg')
temp_filename = temp_file.name
im_resized.save(temp_filename, dpi=(300, 300))
return temp_filename
def image_smoothening(img):
ret1, th1 = cv2.threshold(img, BINARY_THREHOLD, 255, cv2.THRESH_BINARY)
ret2, th2 = cv2.threshold(th1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
blur = cv2.GaussianBlur(th2, (1, 1), 0)
ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return th3
def remove_noise_and_smooth(file_name):
img = cv2.imread(file_name, 0)
filtered = cv2.adaptiveThreshold(img.astype(np.uint8), 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 41,
3)
kernel = np.ones((1, 1), np.uint8)
opening = cv2.morphologyEx(filtered, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)
img = image_smoothening(img)
or_image = cv2.bitwise_or(img, closing)
return or_image
我猜你使用了通用的二值化方法,这就是整个图像不能均匀地进行二值化的原因。您可以使用自适应阈值技术进行二值化。您还可以进行一些倾斜校正、透视校正和噪声去除来获得更好的结果。
参考这篇中文 文章 ,了解上述技术以及代码示例。