如何在 Python 中使用 OpenCV 和 Tesseract 处理信用卡字体
How to handle Credit Cards fonts with OpenCV and Tesseract in Python
我正在尝试使用 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()
- 处理前的图像
- Canny 之后的图片
结果文本看起来不太好。请参阅下面的屏幕截图:
问:如何正确处理好卡片字体,才能获得更好的效果。非常感谢任何想法。
谢谢。
看起来 OCR 在传递文本边缘时效果不佳。
您最好应用阈值而不是使用 Canny。
我建议以下阶段:
- 将 BGR 颜色转换为 HSV 颜色space,并获得 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()
OCR 结果:
Visa Classic
| By)
4000 1234 Sb18 9010
CARDHOLDER MARE
VISA
还不够完美...
s:
阈值:
thresh_card:
我正在尝试使用 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()
- 处理前的图像
- Canny 之后的图片
结果文本看起来不太好。请参阅下面的屏幕截图:
问:如何正确处理好卡片字体,才能获得更好的效果。非常感谢任何想法。
谢谢。
看起来 OCR 在传递文本边缘时效果不佳。
您最好应用阈值而不是使用 Canny。
我建议以下阶段:
- 将 BGR 颜色转换为 HSV 颜色space,并获得 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()
OCR 结果:
Visa Classic
| By)
4000 1234 Sb18 9010
CARDHOLDER MARE
VISA
还不够完美...
s:
阈值:
thresh_card: