Python+OpenCV实现信用卡数字识别的方法详解

  

Python+OpenCV实现信用卡数字识别的方法详解

介绍

本文将介绍如何使用Python和OpenCV(Open Source Computer Vision Library)来实现信用卡数字的识别。首先,我们需要从信用卡的照片中提取数字图像,然后使用数字识别模型来识别它们。本文将演示使用轮廓检测和二值化等技术来提取数字图像,以及使用深度学习方法构建数字识别模型。

环境

  • Python 3.x
  • OpenCV 4.x
  • Numpy
  • Tensorflow 2.x

提取数字图像

首先,我们需要按照以下步骤从信用卡图像中提取数字:

1. 加载图像

使用OpenCV加载信用卡照片。我们可以使用cv2.imread()函数。

import cv2

image = cv2.imread('credit_card.jpg')

2. 灰度化

将图像转换为灰度图像,这可以简化我们的处理过程。

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

3. 边缘检测

使用canny边缘检测算法查找数字的轮廓。由于数字是黑色的,我们可以使用高亮轮廓的形式查找它们。因此,我们需要把图像颜色反转(将黑色变为白色,将白色变为黑色),以便于找到数字的轮廓。

edged = cv2.Canny(gray, 100, 200)
edged = cv2.bitwise_not(edged)

4. 提取数字区域的轮廓

使用cv2.findContours() 函数来提取数字区域的轮廓。该函数返回一组轮廓,并且我们可以通过选择特定的阈值来获得我们感兴趣的数字的轮廓。我们可以使用cv2.RETR_EXTERNAL 标记来找到仅包围数字的轮廓。

contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

5. 确定数字区域位置和大小

对于每个找到的数字轮廓,我们可以使用cv2.boundingRect()函数计算其位置和大小。

digit_rects = []
for contour in contours:
    (x, y, w, h) = cv2.boundingRect(contour)
    digit_rects.append((x, y, w, h))

6. 显示数字区域

现在,我们可以使用cv2.rectangle()函数在原始图像中显示数字区域。

for rect in digit_rects:
    x, y, w, h = rect
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)

数字识别模型

接下来,我们将介绍如何使用深度学习方法构建数字识别模型。

1. 数据预处理

首先,我们需要准备数据集。我们可以使用MNIST(Modified National Institute of Standards and Technology)手写数字数据集来训练我们的模型。MNIST数据集包含70,000个手写数字的图像,其中60,000个用于训练,10,000个用于测试。

from tensorflow.keras.datasets import mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()

2. 构建模型

本文将使用深度卷积神经网络来训练模型,使用TensorFlow 2.x编写代码。

import tensorflow as tf

model = tf.keras.Sequential([
    tf.keras.layers.Reshape((28, 28, 1), input_shape=(28, 28,)),
    tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
    tf.keras.layers.Conv2D(filters=64, kernel_size=(3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(10, activation='softmax')
])

3. 训练模型

现在,我们可以使用MNIST数据集来训练我们的模型。

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit(x_train, y_train, epochs=10, batch_size=32, validation_data=(x_test, y_test))

示例

接下来,我们将提供两个示例来展示本文所述的技术:

示例1:提取信用卡上的数字

import cv2

# 加载图像
image = cv2.imread('credit_card.jpg')

# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 边缘检测
edged = cv2.Canny(gray, 100, 200)
edged = cv2.bitwise_not(edged)

# 提取数字区域的轮廓
contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 确定数字区域位置和大小
digit_rects = []
for contour in contours:
    (x, y, w, h) = cv2.boundingRect(contour)
    digit_rects.append((x, y, w, h))

# 显示数字区域
for rect in digit_rects:
    x, y, w, h = rect
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)

# 显示结果图像
cv2.imshow('Result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

示例2:识别手写数字

import cv2
import numpy as np
import tensorflow as tf

# 加载模型
model = tf.keras.models.load_model('mnist_model.h5')

# 加载图像
image = cv2.imread('digit.jpg', cv2.IMREAD_GRAYSCALE)

# 二值化
_, image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 提取轮廓
cnts, _ = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 提取每个数字并进行识别
for cnt in cnts:
    x, y, w, h = cv2.boundingRect(cnt)

    # 调整数字大小
    if w > h:
        h = w
    else:
        w = h

    cx = x + w // 2
    cy = y + h // 2
    roi = image[cy - 28 // 2:cy + 28 // 2, cx - 28 // 2:cx + 28 // 2]

    # 调整图像大小
    roi = cv2.resize(roi, (28, 28), interpolation=cv2.INTER_AREA)

    # 归一化
    roi = roi.astype('float32') / 255

    # 展开成一维向量
    roi = np.reshape(roi, (1, 28, 28, 1))

    # 进行预测
    predictions = model.predict(roi)
    print(np.argmax(predictions[0]))

# 显示图像
cv2.imshow('Result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

以上就是Python+OpenCV实现信用卡数字识别的方法详解,希望对你有所帮助。

相关文章