dir*_*lta 5 python ocr opencv tesseract computer-vision
我正在尝试使用 Python 和 OpenCV 开发一个脚本,以检测扫描的仪器图上的一些突出显示区域,并使用 Tesseract 的 OCR 功能输出文本。我的工作流程是首先检测感兴趣区域的大体附近,然后应用处理步骤去除除文本块(线条、边框、噪声)之外的所有内容。然后将处理后的图像输入 Tesseract 的 OCR 引擎。
此工作流程适用于大约一半的图像,但由于文本接触边框而在其余图像上失败。我将在下面展示一些我的意思的例子:
步骤 1:通过使用 InRange 和荧光笔的颜色范围创建蒙版来查找感兴趣的区域。
第 2 步:绘制感兴趣区域的轮廓,裁剪并保存到文件。
--- 引用的代码从这里开始 ---
步骤 3:阈值图像并应用 Canny 边缘检测
步骤 4:轮廓边缘并使用 cv2.approxPolyDP 将它们过滤成圆形并查看顶点大于 8 的边缘。取第一或第二大轮廓通常对应于内边缘。
第 5 步:使用掩码和按位操作,轮廓内的所有内容都被转换为白色背景图像。膨胀和腐蚀用于对图像进行降噪并创建输入 OCR 引擎的最终图像。
import cv2
import numpy as np
import pytesseract
pytesseract.pytesseract.tesseract_cmd = 'C:/Program Files (x86)/Tesseract-OCR/tesseract'
d_path = "Test images\\"
img_name = "cropped_12.jpg"
img = cv2.imread(d_path + img_name) # Reads the image
## Resize image before calculating contour
height, width = img.shape[:2]
img = cv2.resize(img,(2*width,2*height),interpolation = cv2.INTER_CUBIC)
img_orig = img.copy() # Makes copy of original image
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # Convert to grayscale
# Apply threshold to get binary image and write to file
_, img = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Edge detection
edges = cv2.Canny(img,100,200)
# Find contours of mask threshold
_, contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Find contours associated w/ polygons with 8 sides or more
cnt_list = []
area_list = [cv2.contourArea(c) for c in contours]
for j in contours:
poly_pts = cv2.approxPolyDP(j,0.01*cv2.arcLength(j,True),True)
area = cv2.contourArea(j)
if (len(poly_pts) > 8) & (area == max(area_list)):
cnt_list.append(j)
cv2.drawContours(img_orig, cnt_list, -1, (255,0,0), 2)
# Show contours
cv2.namedWindow('Show',cv2.WINDOW_NORMAL)
cv2.imshow("Show",img_orig)
cv2.waitKey()
cv2.destroyAllWindows()
# Zero pixels outside circle
mask = np.zeros(img.shape).astype(img.dtype)
cv2.fillPoly(mask, cnt_list, (255,255,255))
mask_inv = cv2.bitwise_not(mask)
a = cv2.bitwise_and(img,img,mask = mask)
wh_back = np.ones(img.shape).astype(img.dtype)*255
b = cv2.bitwise_and(wh_back,wh_back,mask = mask_inv)
res = cv2.add(a,b)
# Get rid of noise
kernel = np.ones((2, 2), np.uint8)
res = cv2.dilate(res, kernel, iterations=1)
res = cv2.erode(res, kernel, iterations=1)
# Show final image
cv2.namedWindow('result',cv2.WINDOW_NORMAL)
cv2.imshow("result",res)
cv2.waitKey()
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)
当代码工作时,这些是输出的图像: 工作
但是,在文本接触圆形边框的情况下,代码假定文本的一部分是较大轮廓的一部分并忽略最后一个字母。例如: 不工作
是否有任何处理步骤可以帮助我绕过此问题?或者也许是一种不同的方法?我曾尝试使用 Hough Circle Transforms 来尝试检测边界,但它们非常挑剔,并且效果不如轮廓。
我对 OpenCV 和 Python 还是很陌生,所以任何帮助将不胜感激。
小智 1
如果霍夫圆变换对您不起作用,我认为您最好的选择是近似边界形状。我知道的最好的方法是:Douglas-Peucker 算法,它可以通过减少图片的周长来使轮廓更简单。
您可以从 OpenCV 检查此参考文件,以了解可以应用于您的寄宿生的后处理类型。他们还提到了 Douglas-Peucker: OpenCV 边界处理
| 归档时间: |
|
| 查看次数: |
2477 次 |
| 最近记录: |