If image has (28,28,3) shape, how do i convert it to (28.28,1)?
Asked Answered
A

2

2

I'm using the mnist dataset of handwritten digits and I am trying to predict a digit that I wrote. The problem is that my digit is of shape (28,28,3) and the expected shape for my neural network is (28,28,1). How can I convert it?

my code:

import tensorflow as to
from tensorflow import keras
from keras.datasets import mnist
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import cv2

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

classes = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

x_train = x_train / 255
x_test = x_test / 255

model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=(28,28)))
model.add(keras.layers.Dense(128, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))

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

model.fit(x_train, y_train, epochs=7)
test_loss, test_acc = model.evaluate(x_test, y_test)
print('\nTest Loss:', test_loss)
print('Test accuracy:', test_acc)

img = Image.open("7.jpg").convert('L')
img_array = cv2.imread('7.jpg')
new_array = cv2.cvtColor(img_array, cv2.COLOR_BGR2GRAY)
new_array = cv2.resize(new_array, (28,28))
print(new_array.shape)
print(x_test[0].shape)
plt.imshow(new_array, cmap='gray')
plt.show()

predictions = model.predict(new_array)

plt.grid(False)
plt.imshow(new_array, cmap='gray')
plt.title("Prediction: " + classes[np.argmax(predictions)])
plt.show()
Adamsite answered 1/5, 2020 at 23:29 Comment(5)
You want to reduce your color space to black-and-white?Tollman
If you want to reduce the color depth from 24-bit (3 channels) to 8-bit (1 channel) convert the image to grayscale using cvtColor. If you want to further reduce the info to black and white (1 channel) threshold the gray output.Packthread
After using cvtColor, it says: expected flatten_input to have 3 dimensions, but got array with shape (28, 28)Adamsite
It's hard to guess where the error is without ANY of your code. My guess is that you are giving a bad mat to cvtColor and/or giving the wrong conversion code.Packthread
Just added my code. thanks for helping 👍🏻Adamsite
S
2

Assuming img has shape of (28, 28, 3) you can do this:

gray = cv2. cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.expand_dims(gray, 2)

This will convert it to a shape of (28, 28, 1)

Stockdale answered 2/5, 2020 at 17:58 Comment(0)
H
0

Even though you want a (28,28) shape, tensors need to have 3 dimensions, so you have to expand that to (28,28,1). Something like this should be enough:

new_array = cv2.resize(new_array, (28,28,1))

Or expand it using new_array=new_array[..., None].

Henka answered 2/5, 2020 at 9:26 Comment(2)
after using: new_array=new_array[..., None] I get an error: expected flatten_input to have shape (28, 28) but got array with shape (28, 1)Adamsite
What about the first option I suggested? Also where's the error coming from?Henka

© 2022 - 2024 — McMap. All rights reserved.