How to print prediction by category inside a loop - python-3.x

I'm having a problem with printing pictures with labels of prediction in my project.
i = 1
for image in DATADIR:
prediction = model.predict
([prepare(r'MY_DIR\manual_testing\{}.jpg'.format(i))])
img = mpimg.imread(r'MY_DIR\manual_testing\{}.jpg'.format(i))
imgplot = plt.imshow(img)
plt.show()
print(CATEGORIES[int(prediction[0][0])])
i += 1
Here MY_DIR replaces the actual directory.
I'm having the following error: TypeError: 'method' object is not subscriptable
I don't really understand what should be changed. If I try to put print('Hello world') in the for loop everything is working.
p.s. If you have an example of how to make the output look more beautiful you are welcome.
Thank you in advance.

I found the solution:
i = 1
for item in os.listdir(DATADIR):
prediction = model.predict([prepare(r'MY_DIR\manual_testing\{}.jpg'.format(i))])
img = mpimg.imread(r'MY_DIR\manual_testing\{}.jpg'.format(i))
imgplot = plt.imshow(img)
plt.show()
print(CATEGORIES[int(prediction[0][0])])
i += 1

Related

How to apply a function to convert the paths to arrays using cv2 in tensorflow data pipeline?

Any help will be highly appreciated
I'm trying to load two lists containing image paths and their corresponding labels. Something like this:
p0 = ['a','b',....] #paths to images .tif format
p1 = [1,2,3,......] #paths to images .tif format
labels = [0,1,1,...] #corresponding labels w.r.t both the lists
I used a tf.data in the following way:
def TFData(p_0, p_1, batch_size, labels=None, is_train=True):
dset = tf.data.Dataset.from_tensor_slices((p_0,p_1))
if labels is not None:
label = tf.data.Dataset.from_tensor_slices(labels)
AUTO = tf.data.experimental.AUTOTUNE
final_dset = tf.data.Dataset.zip((dset, label))
final_dset = final_dset.batch(batch_size, drop_remainder=is_train).prefetch(AUTO)
return final_dset
This returns:
<PrefetchDataset shapes: (((64,), (64,)), (64,)), types: ((tf.string, tf.string), tf.int32)>
My question is how to apply a function to convert the paths to arrays using cv2 as the images are .tif files? such that the result will be:
<PrefetchDataset shapes: (((64,256,256,3), (64,256,256,3)), (64,)), types: ((tf.float64, tf.float64), tf.int32)>
I'm using a dataset.map. However it's throwing error:
def to_array(p_0):
im_1 = cv2.imread(p_0,1)
#im = tfio.experimental.image.decode_tiff(paths)
im_1 = cv2.resize(im_1,(img_w,img_h)) #img_w=img_h=256
im_1 = np.asarray(im_1, dtype=np.float64)
im_1 /= 255
return im_1
def parse_fn(p_0):
[p_0,] = tf.py_function(to_array, [p_0], [tf.float64])
return p_0
def TFData(p_0, p_1, batch_size, labels=None, is_train=True):
dset_1 = tf.data.Dataset.from_tensor_slices(p_0)
dset_1 = dset_1.map(parse_fn)
dset_2 = tf.data.Dataset.from_tensor_slices(p_1)
dset_2 = dset_2.map(parse_fn)
if labels is not None:
label = tf.data.Dataset.from_tensor_slices(labels)
AUTO = tf.data.experimental.AUTOTUNE
final_dset = tf.data.Dataset.zip((dset_1, dset_2, label))
final_dset = final_dset.batch(batch_size, drop_remainder=is_train).prefetch(AUTO)
return final_dset
print(train_data) #where train_data is defined as TFData()
<PrefetchDataset shapes: ((<unknown>, <unknown>), (64,)), types: ((tf.float64, tf.float64), tf.int32)>
This throws an error:
for (t,p),l in train_data.as_numpy_iterator():
print(t)
print(p)
print(l)
print(type(t))
break
SystemError: <built-in function imread> returned NULL without setting an error
[[{{node EagerPyFunc}}]] [Op:IteratorGetNext]
Any help will be highly appreciated
I think your problem is in cv2.imread.
Have you checked outside the functions to see if it is reading and plotting the data accordingly?
Please, try with -1 instead:
im_1 = cv2.imread(p_0,-1)

Why do I get this cv2.error when I set the net.forward output?

I'm doing some machine learning object detection with cv2 and I always get a cv2.error:
OpenCV(4.0.0) C:\projects\opencv-python\opencv\modules\dnn\src\layers\convolution_layer.cpp:1114: error: (-215:Assertion failed) inputs[0].size[1] % blobs[0].size[1] == 0 in function 'cv::dnn::ConvolutionLayerImpl::forward'
net = cv2.dnn.readNet("yolov3.weights","yolov3.cfg")
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0]-1] for i in net.getUnconnectedOutLayers()]
img = op('null1').numpyArray(delayed=True)
#print(img.dtype)#float32
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
gray = (gray *255).astype(np.uint8)
#print(gray.dtype)#uint8
blob = cv2.dnn.blobFromImage(img,1/255,(416,416),(0,0,0),swapRB=True,crop=False)
net.setInput(blob)
out = net.forward(output_layers)#!!! HERE OCCURS MY ERROR
Anyone a suggestion what causes this error?
Do I have to change the pixelformat?
You should change 1/255 to be 1.0/255 so that it doesn't be zero.
Also I think this line should be like this
output_layers=[]
for i in net.getUnconnectedOutLayers():
output_layers.append(layer_names[i[0]-1])
#you should add these 2 lines of code:
net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
#below this:
net = cv.dnn.readNetFromDarknet('yolov3.cfg', 'yolov3.weights')
outputNames = [layerNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]

How to fix "TypeError: Expected Ptr<cv::UMat> for argument '%s'"

I'm writing codes to accelerate my program using CUDA, but I got a tricky error. I have no idea about it.My environment is OpenCV 4.1.1, python 3.6.
Here is my code.
I define a function to rotate the img,
def rotate(img, angle):
'''
'''
if len(img.shape) == 3:
(rows, cols, channels) = img.shape
out_size = (cols, rows, channels)
else:
(rows, cols) = img.shape
out_size = (cols, rows)
if angle == 0:
dst = img
else:
# img_gpu = cv2.cuda_GpuMat()
img_gpu = cv2.cuda_GpuMat()
out_gpu = cv2.cuda_GpuMat()
# M_gpu = cv2.cuda_GpuMat()
# out_size_gpu = cv2.cuda_GpuMat()
# border_value_gpu = cv2.cuda_GpuMat()
m = cv2.getRotationMatrix2D((cols/2, rows/2), angle, 1)
img_gpu.upload(img)
# M_gpu.upload(M)
# out_size_gpu.upload((12000, 6000))
# border_value_gpu.upload((0, 0, 0))
cols_gpu = cv2.cuda_GpuMat()
rows_gpu = cv2.cuda_GpuMat()
cols_gpu.upload(cols)
rows_gpu.upload(rows)
print(type(img))
print(img.shape)
(row,col) = img.shape
print([img_gpu.size()[0],img_gpu.size()[1]])
# M = np.float32([[1,0,100],[0,1,50]])
# out=cv2.UMat(out_gpu,(284,284))
out_gpu = cv2.cuda.warpAffine(img_gpu, m, (col,row))
dst = out_gpu.download()
return dst
then I call it.
img = cv2.imread('../FengZhan/temp.png',0)
img_rotate = rotate(img, -10)
it cannot work and has the following error:
<ipython-input-48-41cd06952793> in rotate(img, angle)
36 # M = np.float32([[1,0,100],[0,1,50]])
37 # out=cv2.UMat(out_gpu,(284,284))
---> 38 out_gpu = cv2.cuda.warpAffine(img_gpu, m, (col,row))
39
40 dst = out_gpu.download()
TypeError: Expected Ptr<cv::UMat> for argument '%s'
I tried to replace img_gpu with cv2.UMat(img_gpu), but it still cannot work.
Anybody help me?
I got this error: TypeError: Expected Ptr<cv::UMat> for argument '%s'
code:
image = cv2.imread("image_path")
image = cv2.cvtColor(np.array(image), cv2.COLOR_BGR2GRAY)
Simply because the image path was incorrect and I was loading an image which wasn't there. I realize it might not be your case however I hope it may help others who encounter this error.
I don't understand why do you define in the beginning out_gpu = cv2.cuda_GpuMat(). And in the end you set it again to: out_gpu = cv2.cuda.warpAffine(img_gpu, m, (col,row)).
The reason why you get this error may be because of your code out_gpu = cv2.cuda.warpAffine(img_gpu, m, (col,row)) argument img_gpu is supposed to be a string link to an image, yet it is defined previously as img_gpu = cv2.cuda_GpuMat(). Try to correct this by replacing the line img_gpu.upload(img) by uploaded_img = img_gpu.upload(img)
Change your image to be numpy array
np.array(image)
It seems to be one bug for OpenCV as I issued at OpenCV cuda bindings for python seem receive wrong param types for cudawarping/src/warp.cpp #2393.
However, even I fix this bug the speed is not satisying (slower than CPU version), if there are some other tricks, maybe we can share with each other.
Good Luck.

Basic classification in tensorflow tutorial

I just started learning tensorflow and am working on the basic classification tutorial in their official page.
Basic Classification Tutorial
From the below piece of code
def plot_image(i, predictions_array, true_label, img):
predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img, cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array)
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
100*np.max(predictions_array),
class_names[true_label]),
color=color)
def plot_value_array(i, predictions_array, true_label):
predictions_array, true_label = predictions_array[i], true_label[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
The below are the sample results of the test data.
Case 1:
Case 2
Even though the system predicted it with 100%, then why did it displayed the results with the red color?
In the predicted label, it is not showing any other classes.
There is a bug in the code.
"i" will for predictions_array, take the first array element(which is an array). This part is ok, but it is always going to be index 0 you need for the prediction array. Two ways to fix this: either pass it as "predictions_array[0]" when calling like I did below. Or modify the function to include "predictions_array = predictions_array[0]"
Since "i" must be 0 for the predictions array it will in the original code always check test_labels[0]. This will then for all cases when you predict something else than 9 give a red (since it thinks its a wrong prediction). Therefore passing i as the index of the test image will give you the correct label.
Suggestion of a modified function:
def plot_value_array(i, predictions_array, true_label):
print(true_label)
true_label = true_label[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
And modified calling where "1" is the image I am in this case testing (make this a variable so you dont have to type it twice when testing).
In other words: in case img = test_images[1] I have to pass 1 to the function.
plot_value_array(1, predictions_single[0], test_labels)
plt.xticks(range(10), class_names, rotation=45)
plt.show()

'Word2Vec' object has no attribute 'index2word'

I'm getting this error "AttributeError: 'Word2Vec' object has no attribute 'index2word'" in following code in python. Anyone knows how can I solve it?
Acctually "tfidf_weighted_averaged_word_vectorizer" throws the error. "obli.csv" contains line of sentences.
Thank you.
from feature_extractors import tfidf_weighted_averaged_word_vectorizer
dataset = get_data2()
corpus, labels = dataset.data, dataset.target
corpus, labels = remove_empty_docs(corpus, labels)
# print('Actual class label:', dataset.target_names[labels[10]])
train_corpus, test_corpus, train_labels, test_labels = prepare_datasets(corpus,
labels,
test_data_proportion=0.3)
tfidf_vectorizer, tfidf_train_features = tfidf_extractor(train_corpus)
vocab = tfidf_vectorizer.vocabulary_
tfidf_wv_train_features = tfidf_weighted_averaged_word_vectorizer(corpus=tokenized_train,
tfidf_vectors=tfidf_train_features,
tfidf_vocabulary=vocab,
model=model,
num_features=100)
def get_data2():
obli = pd.read_csv('db/obli.csv').values.ravel().tolist()
cl0 = [0 for x in range(len(obli))]
nonObli = pd.read_csv('db/nonObli.csv').values.ravel().tolist()
cl1 = [1 for x in range(len(nonObli))]
all = obli + nonObli
db = Db(all,cl0 + cl1)
db.data = all
db.target = cl0 + cl1
return db
This is code from chapter 4 of Text Analytics for Python by Dipanjan Sarkar.
index2word in gensim has been moved since that text was published.
Instead of model.index2word you should use model.wv.index2word.

Resources