After training a model for handwritten digit recognition, when I provide the input image it shows the wrong contours and the wrong output. The input data contains 5 digits, but the output say 10-15 digits. Even it does not create right triangle. Following is the code to train the model and the code to give new image input
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')
and to give new image input and make predictions
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())
now given an image with digits 504192 it outputs 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 8 2 5 4 5 0 the output after threshhold and drawing contours is !https://drive.google.com/file/d/1-H5Ov3SKyuCCkUUsSuq9gXqyn99J2c7T/view?usp=sharing