如何在Python中使用OpenCV和Tesseract处理信用卡字体

如何在Python中使用OpenCV和Tesseract处理信用卡字体,python,opencv,image-processing,tesseract,python-tesseract,Python,Opencv,Image Processing,Tesseract,Python Tesseract,我正在用OpenCV读取卡片并输出卡号和有效期 import cv2 import pytesseract filename = 'image1.png' img = cv2.imread(filename) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) canny = cv2.Canny(gray, 50, 150, apertureSize=3) result = pytesseract.image_to_string(canny) print(

我正在用OpenCV读取卡片并输出卡号和有效期

import cv2
import pytesseract

filename = 'image1.png'
img = cv2.imread(filename)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(gray, 50, 150, apertureSize=3)
result = pytesseract.image_to_string(canny)
print(f"OCR Results: {result}")

cv2.imshow('img', img)
cv2.imshow('canny', canny)

if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

  • 处理前的图像
  • 精明后的形象
  • 结果文本看起来不太好。请参见下面的屏幕截图:

    问题:如何正确处理卡片字体以获得更好的效果。任何想法都将受到高度赞赏


    谢谢。

    在传递文本边缘时,OCR似乎无法正常工作。
    您最好应用阈值,而不是使用Canny

    我建议分以下几个阶段:

    • 从BGR转换到HSV颜色空间,得到HSV的S(饱和度)颜色通道。
      S中的所有灰色像素为零,彩色像素高于零
    • 使用自动阈值转换为二进制(使用cv2.THRESH_OTSU)
    • 以最大尺寸裁剪轮廓。
      因为您发布的图像包含一些背景
    • 在裁剪区域应用OCR
    代码如下:

    import numpy as np
    import cv2
    import imutils  # https://pypi.org/project/imutils/
    import pytesseract
    
    pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'  # I am using Windows
    
    img = cv2.imread('image1.png')  # Read input image
    
    # Convert from BGR to HSV color space
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    
    # Get the saturation color channel - all gray pixels are zero, and colored pixels are above zero.
    s = hsv[:, :, 1]
    
    # Convert to binary using automatic threshold (use cv2.THRESH_OTSU)
    ret, thresh = cv2.threshold(s, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    
    # Find contours (in inverted thresh)
    cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    cnts = imutils.grab_contours(cnts)
    
    # Find the contour with the maximum area.
    c = max(cnts, key=cv2.contourArea)
    
    # Get bounding rectangle
    x, y, w, h = cv2.boundingRect(c)
    
    # Crop the bounding rectangle out of thresh
    thresh_card = thresh[y:y+h, x:x+w].copy()
    
    # OCR
    result = pytesseract.image_to_string(thresh_card)
    print(f"OCR Results:\n {result}")
    
    
    # Show images for debugging
    cv2.imshow('s', s)
    cv2.imshow('thresh', thresh)
    cv2.imshow('thresh_card', thresh_card)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    光学字符识别结果:

    Visa经典
    |(由)
    4000 1234 Sb18 9010
    持卡母马
    签证
    
    还是不完美


    s:

    脱粒:

    脱粒卡:

    我假设您已经用足够的字体样本训练了分类器。请注意,您的输入图像至少有三种不同的字体。如果您试图将注意力集中在数字和有效期上,那么最好消除额外的噪音。还有,为什么要处理边?字体的实际(白色实心)斑点不是更有用吗?谢谢你,@Rotem。我正在深入研究Python中的Opencv实现。对于我需要注意的事情,这显然是一个令人大开眼界的发现。我觉得tesseract也应该调整以获得更好的结果。我会随时通知你的。@Cheruitfelix嗨,你有什么突破吗?@pravir这对我没用。当我换卡的时候,它是非常不一致的,特别是在有很多图形和不同图案的地方。我决定用AI而不是OpenCV构建自己的文本提取引擎。现在我用的是YOLO。请检查这篇文章的工作原理。我花了3天时间进行训练,早期的成绩令人鼓舞。