首页 > 解决方案 > 手写数字识别AI模型的错误轮廓和错误输出

问题描述

在训练了一个手写数字识别模型后,当我提供输入图像时,它显示了错误的轮廓和错误的输出。输入数据包含 5 位,但输出为 10-15 位。即使它不会创建直角三角形。以下是训练模型的代码和提供新图像输入的代码

import cv2
import numpy as np
from keras.datasets import mnist
from keras.layers import Dense, Flatten
from keras.layers.convolutional import Conv2D
from keras.models import Sequential
from keras.utils import to_categorical
 import matplotlib.pyplot as plt

(X_train, y_train), (X_test, y_test) = mnist.load_data()

 print ("Shape of X_train: {}".format(X_train.shape))
 print ("Shape of y_train: {}".format(y_train.shape))
 print ("Shape of X_test: {}".format(X_test.shape))
 print ("Shape of y_test: {}".format(y_test.shape))

 X_train = X_train.reshape(60000, 28, 28, 1)
 X_test = X_test.reshape(10000, 28, 28, 1)

y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

## Declare the model
model = Sequential()

## Declare the layers
layer_1 = Conv2D(32, kernel_size=3, activation='relu', input_shape=(28, 28, 1))
layer_2 = Conv2D(64, kernel_size=3, activation='relu')
layer_3 = Flatten()
layer_4 = Dense(10, activation='softmax')

## Add the layers to the model
model.add(layer_1)
model.add(layer_2)
model.add(layer_3)
model.add(layer_4)

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

model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=3)

model.save('Digit_Recognition_Model_2.model')

并提供新的图像输入并进行预测

import tensorflow as tf
import numpy as np
import cv2
import matplotlib.pyplot as plt

model=tf.keras.models.load_model('Digit_Recognition_Model_2.model')

image = cv2.imread('test_images/test3.jpeg')
grey = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(grey.copy(), 75, 255, cv2.THRESH_BINARY_INV)
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, 
cv2.CHAIN_APPROX_SIMPLE)
preprocessed_digits = []
for c in contours:
    x,y,w,h = cv2.boundingRect(c)

    # Creating a rectangle around the digit in the original image (for displaying the digits fetched via contours)
cv2.rectangle(image, (x,y), (x+w, y+h), color=(0, 255, 0), thickness=2)

# Cropping out the digit from the image corresponding to the current contours in the for loop
digit = thresh[y:y+h, x:x+w]

# Resizing that digit to (18, 18)
resized_digit = cv2.resize(digit, (18,18))

# Padding the digit with 5 pixels of black color (zeros) in each side to finally produce the image of (28, 28)
padded_digit = np.pad(resized_digit, ((5,5),(5,5)), "constant", constant_values=0)

# Adding the preprocessed digit to the list of preprocessed digits
preprocessed_digits.append(padded_digit)
print("\n\n\n----------------Contoured Image--------------------")
plt.imshow(image, cmap="gray")
plt.show()

inp = np.array(preprocessed_digits)

for digit in preprocessed_digits:
    prediction = model.predict(digit.reshape(1, 28, 28, 1))  
    print(prediction.argmax())

现在给定一个带有数字 504192 的图像,它输出 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 8 2 5 4 5 0 阈值和绘制轮廓后的输出是!https://drive.google.com/file/d/1-H5Ov3SKyuCCkUUsSuq9gXqyn99J2c7T/view?usp=sharing

标签: pythonopencvkerasartificial-intelligencehandwriting-recognition

解决方案


做一些改变

orig=cv2.imread('numbers.png')
img=cv2.imread('numbers.png',0)

ret, thresh = cv2.threshold(img.copy(), 150, 255, cv2.THRESH_BINARY_INV)
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
digits=[]
for c in contours:
   x,y,w,h = cv2.boundingRect(c)
   cv2.rectangle(orig, (x,y), (x+w, y+h), color=(0, 255, 0), thickness=2)
   digit = thresh[y:y+h, x:x+w]
   padded_digit = np.pad(digit, ((10,10),(10,10)), "constant", constant_values=0)
   digit=cv2.resize(padded_digit,(28,28))
   digits.append(digit)
inp = np.array(digits).reshape((len(digits),28,28,1))
y_pred = model.predict(inp)  #instead of one by one predict, all at once 

轮廓 检测到 这些是分段数字

如果你愿意,你可以使用小膨胀以获得更好的结果


推荐阅读