I want to predict from image url. In the past, I use ImageDatagenerator().flow_from_directory() methods, but now I have only one image. so I want to predict from this single image.
I have tried the below code, but failed. (Dimension error)
url = "http://3.36.149.28/uploads/WEBUPLOADprofile.png"
img = Image.open(requests.get(url, stream=True).raw)
img = img_to_array(img)
img = img/255.
#Predict
pred = model.predict(img)
so I tried reshape & retrying, but failed (cannot reshape array of size 1048576 into shape (28,28,1))
img = img.reshape(-1, 28, 28, 1)
img = img/255.
#Predict
pred = model.predict(img)
for getting reshape & get colored predict image, what can I do ? please help..
Additional : I trained srcnn model, and inputs :
inputs = Input((None, None, 3), dtype='float')
I resolved this problem.
First, my url image shape is (None, None, 4), but my trained shape is (None, None, 3).
So I tried another jpg image (None, None, 3) and expand dimension via np,
and result shape = (1, None, None, 3)
image = np.expand_dims(image, axis=0)
model.predict(image)
from link
and now I get predict image successfully.
Related
I'm decoding a base64 image with the following code:
def string_to_image(base64_string):
decoded = base64.b64decode(base64_string)
np_data = np.frombuffer(decoded, np.uint8)
img = cv2.imdecode(np_data, cv2.IMREAD_UNCHANGED)
return img
The goal is to receive an image from the request body, decode it, resize it with tensorflow, predict it with a model, and return a response saying what is that image:
image_base64 = request.json['image']
decoded_image = string_to_image(image_base64)
image_resized = tf.image.resize(decoded_image, (256, 256))
model = load_model('src/models/mymodel.h5')
result = model.predict(np.expand_dims(image_resized/255, 0))
However, I'm getting the error ValueError: Input 0 of layer "sequential_2" is incompatible with the layer: expected shape=(None, 256, 256, 3), found shape=(None, 256, 256, 4).
I don't know how to change the Shape value from '4' to '3'.
I tried the following:
image_resized = tf.image.resize(decoded_image, (256, 256, 3))
But I get 'size' must be a 1-D Tensor of 2 elements: new_height, new_width.
I also tried:
image_resized = cv2.resize(decoded_image, (256,256,3))
But I get OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'resize'
Overload resolution failed:
- Can't parse 'dsize'. Expected sequence length 2, got 3
- Can't parse 'dsize'. Expected sequence length 2, got 3
Please help :(
You could reshape the array by using tf.squeeze after reshaping the tensor. According to documentation, tf.squeeze will remove axis with dimensions 1.
image_resized = tf.reshape(decoded_image, (-1, 256, 256, 3, 1))
image_resized = tf.squeeze(image_resized)
With vijayachandran mariappan comment and AndreaYolo answer I figured out a solution. First, change the channels of the image and then resize its dimensions:
decoded_image = string_to_image(image_base64)
decoded_image = decoded_image[:,:,:3]
image_resized = tf.image.resize(decoded_image, (256, 256))
My model then was able to predict perfectly!
When feeding an image to a pretrained InceptionResNetV2 network, I have the following results.
from keras.applications.inception_resnet_v2 import InceptionResNetV2
INPUT_SHAPE = (200, 250, 3)
img = load_img() # loads a 200x250 rgb image into a (200, 250, 3) numpy array
assert img.shape == INPUT_SHAPE # just fine
model = InceptionResNetV2(include_top=False, input_shape=INPUT_SHAPE)
model.predict(img)
ValueError: Error when checking input: expected input_1 to have 4 dimensions, but got array with shape (200, 150, 3)
I don't understand why and how the model expects a 4 dimension input. What must be done to adapt the (200, 250, 3) image so that it can be processed by the model?
try reshape your input with shapes (1, 200, 150, 3) or (200, 150, 3, 1).
You can use image = np.expand_dims(image, axis=0)) or
image = input_data.reshape((-1, image_side1, image_side2, channels))
You need to feed a batch of images. If your batch has one image, it should also have the same format.
try img.reshape((1, 200, 150, 3))
I am trying to extract features from a convolution layer of the VGGFace model, using TensorFlow & Keras.
This is my code:
# Layer Features
layer_name = 'conv1_2' # Edit this line
vgg_model = VGGFace() # Pooling: None, avg or max
out = vgg_model.get_layer(layer_name).output
vgg_model_new = Model(vgg_model.input, out)
def main():
img = image.load_img('myimage.jpg', target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = utils.preprocess_input(x, version=1)
preds = vgg_model_new.predict(x)
print('Predicted:', utils.decode_predictions(preds))
exit(0)
However, at the print('Predicted:', utils.decode_predictions(preds)) line I am getting the following error:
Message=decode_predictions expects a batch of predictions (i.e. a
2D array of shape (samples, 2622)) for V1 or (samples, 8631) for
V2.Found array with shape: (1, 224, 224, 64)
I just want to extract features, I don't need to classify my images at this point. This code is based on https://github.com/rcmalli/keras-vggface
You shouldn't use utils.decode_predictions(preds) there because it's only for classification. You can see the definition of the function here https://github.com/rcmalli/keras-vggface/blob/master/keras_vggface/utils.py#L66
If you want to print the features, use print('Predicted:',preds)
I am using Transfer learning for recognizing objects. I used trained VGG16 model as the base model and added my classifier on top of it using Keras. I then trained the model on my data, the model works well. I want to see the feature generated by the intermediate layers of the model for the given data. I used the following code for this purpose:
def ModeloutputAtthisLayer(model, layernme, imgnme, width, height):
layer_name = layernme
intermediate_layer_model = Model(inputs=model.input,
outputs=model.get_layer(layer_name).output)
img = image.load_img(imgnme, target_size=(width, height))
imageArray = image.img_to_array(img)
image_batch = np.expand_dims(imageArray, axis=0)
processed_image = preprocess_input(image_batch.copy())
intermediate_output = intermediate_layer_model.predict(processed_image)
print("outshape of ", layernme, "is ", intermediate_output.shape)
In the code, I used np.expand_dims to add one extra dimension for the batch as the input matrix to the network should be of the form (batchsize, height, width, channels). This code works fine. The shape of the feature vector is 1, 224, 224, 64.
Now I wish to display this as image, for this I understand there is an additional dimension added as batch so I should remove it. Following this I used the following lines of the code:
imge = np.squeeze(intermediate_output, axis=0)
plt.imshow(imge)
However it throws an error:
"Invalid dimensions for image data"
I wonder how can I display the extracted feature vector as an image. Any suggestion please.
Your feature shape is (1,224,224,64), you cannot directly plot a 64 channel image. What you can do is plot the individual channels independently like following
imge = np.squeeze(intermediate_output, axis=0)
filters = imge.shape[2]
plt.figure(1, figsize=(32, 32)) # plot image of size (32x32)
n_columns = 8
n_rows = math.ceil(filters / n_columns) + 1
for i in range(filters):
plt.subplot(n_rows, n_columns, i+1)
plt.title('Filter ' + str(i))
plt.imshow(imge[:,:,i], interpolation="nearest", cmap="gray")
This will plot 64 images in 8 rows and 8 columns.
A possible way to go consists in combining the 64 channels into a single-channel image through a weighted sum like this:
weighted_imge = np.sum(imge*weights, axis=-1)
where weights is an array with 64 weighting coefficients.
If you wish to give all the channels the same weight you could simply compute the average:
weighted_imge = np.mean(imge, axis=-1)
Demo
import numpy as np
import matplotlib.pyplot as plt
intermediate_output = np.random.randint(size=(1, 224, 224, 64),
low=0, high=2**8, dtype=np.uint8)
imge = np.squeeze(intermediate_output, axis=0)
weights = np.random.random(size=(imge.shape[-1],))
weighted_imge = np.sum(imge*weights, axis=-1)
plt.imshow(weighted_imge)
plt.colorbar()
In [33]: intermediate_output.shape
Out[33]: (1, 224, 224, 64)
In [34]: imge.shape
Out[34]: (224, 224, 64)
In [35]: weights.shape
Out[35]: (64,)
In [36]: weighted_imge.shape
Out[36]: (224, 224)
I am new to OpenCV and TensorFlow. I am trying to get a live camera preview and use the live camera feed for TensorFlow prediction. Here is the part of code for live preview and prediction:
image = np.zeros((64, 64, 3))
softmax_pred = tf.nn.softmax(conv_net(x, weights, biases, image_size, 1.0))
cam = cv2.VideoCapture(0)
while True:
ret_val, img = cam.read()
img = cv2.flip(img,1)
cv2.imshow('my webcam',img)
img = img.resize((64,64))
image = array(img).reshape(1,64,64,3)
image.astype(float)
result = sess.run(softmax_pred, feed_dict={x: image})
I am not sure what's wrong here. I am getting this error:
image = array(img).reshape(1,64,64,3)
ValueError: total size of new array must be unchanged
My Tensor placeholder for image has the shape Tensor '(?, 64, 64, 3)'. I did the same for jpeg image by manually loading an image from disk and reshaping that image to (1,64,643) and it works fine.Here is the code for manually loading an image and then predicting:
img = Image.open('/home/pragyan/Documents/miniProject/PredictImages/IMG_4804.JPG')
img = img.resize((64, 64))
image = array(img).reshape(1,64,64,3)
image.astype(float)
result = sess.run(softmax_pred, feed_dict={x: image})
The above code works but while reshaping a live frame from webcam gives me this error(ValueError: total size of new array must be unchanged). Is there a way to fix this? I am not able to understand how to fix it.