How to read an image using imread? - python-3.x

I am trying to add gui to my deep learning project based on cnn..
So on clicking classify button ,I need to read an image and send the same to the same prediction function for futher processing. Kindly help me here. I have just shared the part of the code.
def sample_prediction(test_im):
feed_dict_test = {
x: test_im.reshape(1, img_size_flat),
y_true: np.array([[2,1,0]])
}
test_pred = session.run(y_pred_cls, feed_dict=feed_dict_test)
return classes[test_pred[0]]
def classify(file_path):
global label_packed
image = Image.open(file_path)
#image = image.resize((30,30))
#image = numpy.expand_dims(image, axis=0)
#image = numpy.array(image)
#cv2.imshow("frame",inputface)
#inputface = cv2.resize(inputface, (img_size, img_size), cv2.INTER_LINEAR) / 255
pred =sample_prediction(image)
sign = classes[pred+1]
print(sign)
def show_classify_button(file_path):
classify_b=Button(top,text="Classify X-ray Image",command=lambda: classify(file_path),padx=10,pady=5)
classify_b.configure(background='#364156', foreground='white',font=('arial',10,'bold'))
classify_b.place(relx=0.79,rely=0.46)
label.configure(foreground='#011638', text=sign)
When I run this,Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\DELL\anaconda3\envs\Pneu Packages\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "cnn_train_test.py", line 489, in <lambda>
classify_b=Button(top,text="Classify X-ray Image",command=lambda: classify(file_path),padx=10,pady=5)
File "cnn_train_test.py", line 482, in classify
pred =sample_prediction(image)
File "cnn_train_test.py", line 372, in sample_prediction
x: test_im.reshape(1, img_size_flat),
AttributeError: 'JpegImageFile' object has no attribute 'reshape'

You can read, write and process images as Numpy arrays or PIL Images and you can move between the two types as you go. Be aware that OpenCV uses BGR ordering, while PIL and most other packages assume RGB.
So, you can read your image into a Numpy array with OpenCV:
import cv2
# Load a file into a Numpy array - "na" will be BGR order
na = cv2.imread('image.png', cv2.IMREAD_COLOR)
And write that Numpy array to disk with OpenCV using:
import cv2
# Write Numpy array to disk as image - "na" must be BGR order
cv2.imwrite('result.jpg', na)
Or you can use PIL to load your image as a PIL Image:
from PIL import Image
# Load a file into a "PIL Image"
pi = Image.open('input.jpg')
And write that Image to disk with PIL:
from PIL import Image
# Save PIL Image to disk
pi.save('result.png')
You can convert a PIL Image to a Numpy array like this:
# Make Numpy array from PIL Image
na = np.array(pi)
And convert a Numpy array to a PIL Image like this:
# Make PIL Image from Numpy array
pi = Image.fromarray(na)
Bear in mind the channel ordering and potentially use this to re-order the channels:
BGRarray = cv2.cvtColor(RGBarray, cv2.COLOR_RGB2BGR)
or
RGBarray = cv2.cvtColor(BGRarray, cv2.COLOR_BGR2RGB)

Related

Numpy error trying to use difference hashing with the ImageHash library

I am trying to perform difference hashing with the python ImageHash library and keep getting a numpy error.
The error:
File "/Users/testuser/Desktop/test_folder/test_env/lib/python3.8/site-packages/imagehash.py", line 252, in dhash
image = image.convert("L").resize((hash_size + 1, hash_size), Image.ANTIALIAS)
AttributeError: 'numpy.ndarray' object has no attribute 'convert'
The code:
from PIL import Image
from cv2 import cv2
import imagehash
import numpy as np
def hash_and_compare(image1, image2):
image1 = image1
image2 = image2
# read images
image1 = cv2.imread(image1)
image2 = cv2.imread(image2)
# convert to grayscale
image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
# resize images
image1 = cv2.resize(image1, (9, 8))
image2 = cv2.resize(image2, (9, 8))
# hash images
image1_hash = imagehash.dhash(image1)
image2_hash = imagehash.dhash(image2)
# compute hamming distance
distance = image1_hash - image2_hash
if image1_hash <= 10:
print(distance)
print('match')
else:
print(distance)
print('no match')
hash_and_compare('/Users/testuser/Desktop/test_folder/game_name056496.png', '/Users/testuser/Desktop/test_folder/game_name499761.png')
as it is mentioned in imagehash library's document, #image must be a PIL instance.. so you cant set numpy array as input of the dshash function.if you want do some preprocess with opencv, you should convert it into PIL array before setting it into dhash, like this :
import numpy as np
from PIL import Image
...
some preprocess
...
# You may need to convert the color.
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(img)
image1_hash = imagehash.dhash(im_pil)

how to pass an array instead of path in keras preprocessor

I want to convert an image that was loaded by cv2 into an specific format with keras preprocessor.
The keras.preprocessing.image.load_image() function takes input as path but i have only the numpy array.
I need help in converting the image into specfic format
The code i want to do is:
def convert(img):
img = load_img(imge, grayscale=True, target_size=(28, 28))
img = img_to_array(imge)
img = img.reshape(1, 28, 28, 1)
img = img.astype('float32')
img = img / 255.0
return img
Is there any other way to get the above format with numpy array and not with image path.
i got the output by the following method
import numpy as np
import cv2
img=cv2.imread('check.jpg')
grey=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
resized=cv2.resize(grey,(28,28))
np_arr=np.array(resized)
np_arr=np_arr.astype('float32')/255
print(np_arr.size)

Python 3.x - Slightly Precise Optical Character Recognition. What should I use?

import time
# cv2.cvtColor takes a numpy ndarray as an argument
import numpy as nm
import pytesseract
# importing OpenCV
import cv2
from PIL import ImageGrab, Image
bboxes = [(1469, 1014, 1495, 1029)]
def imToString():
# Path of tesseract executable
pytesseract.pytesseract.tesseract_cmd = 'D:\Program Files (x86)\Tesseract-OCR' + chr(92) + 'tesseract.exe'
while (True):
for box in bboxes:
# ImageGrab-To capture the screen image in a loop.
# Bbox used to capture a specific area.
cap = ImageGrab.grab(bbox=box)
# Converted the image to monochrome for it to be easily
# read by the OCR and obtained the output String.
tesstr = pytesseract.image_to_string(
cv2.cvtColor(nm.array(cap), cv2.COLOR_BGR2GRAY), lang='eng', config='digits') # ,lang='eng')
cap.show()
#input()
time.sleep(5)
print(tesstr)
# Calling the function
imToString()
It captures an image like this:
It isn't always two digits it can be one or three digits too.
Pytesseract returns values like: asi and oli
So, which Image To Text (OCR) Algorithm should I use for this problem? And, how to use that? I need a very precise value in this example it's 53 so the output should be around 50.

how to show binary image data in python?

i can show the image using image.open, but how do i display from the binary data?
trying to use plot gets: ValueError: x and y can be no greater than 2-D, but have shapes (64,) and (64, 64, 3). this makes sense as that is what the result is supposed to be, but how do i display it?
import pathlib
import glob
from os.path import join
import matplotlib.pyplot as plt
from PIL import Image
import tensorflow as tf
def parse(image): # my like ings, but with .png instead of .jpeg.
image_string = tf.io.read_file(image)
image = tf.image.decode_png(image_string, channels=3)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, [64, 64])
return image
root = "in/flower_photos/tulips"
path = join(root,"*.jpg")
files = sorted(glob.glob(path))
file=files[0]
image = Image.open(file)
image.show()
binary=parse(file)
print(type(binary))
# how do i see this?
#plt.plot(binary) # does not seem to work
#plt.show() # does not seem to work
found a nice pillow tutorial.
from matplotlib import image
from matplotlib import pyplot
from PIL import Image
# load the image
filename='Sydney-Opera-House.jpg'
im = Image.open(filename)
# summarize some details about the image
print(im.format)
print(im.mode)
print(im.size)
# show the image
#image.show()
# load image as pixel array
data = image.imread(filename)
# summarize shape of the pixel array
print(data.dtype)
print(data.shape)
# display the array of pixels as an image
pyplot.imshow(data)
pyplot.show()

python cv2.imread return none on 6th image

I am trying to import and read all images in a folder. However, when I have more than 5 images, cv2.imread returns none for the 6th image. I have tried using different file names, different files, etc, but I can't get it to work.
import cv2
import numpy as np
import matplotlib.pyplot as plt
from tkinter import filedialog
import os
from mpl_toolkits.mplot3d import Axes3D
global scan_dir
scan_dir = filedialog.askdirectory()
print(scan_dir)
x=os.listdir(scan_dir)
img={}
print(x)
for i in range(0,len(x)):
print(i)
img[i] = cv2.imread(x[i], cv2.IMREAD_GRAYSCALE)
indices[i] = np.where(img[i]<100)
I get the following error...(None is the return of print(img[i] on 6th iteration of the loop)
None
Traceback (most recent call last):
File "C:\CodeRepository\US-3D\GettingCloser.py", line 55, in <module>
indices[i] = np.where(img[i]<100)
TypeError: '<' not supported between instances of 'NoneType' and 'int'
I have the same problem if I try this
global scan_dir
scan_dir = filedialog.askdirectory()
print(scan_dir)
x=os.listdir(scan_dir)
img = cv2.imread(x[5], cv2.IMREAD_GRAYSCALE)
It will return that img is None. This is true for anything beyond the 5th image.
Must be something wrong with the file. dicts are an unordered Data structure. Should not give error always on 5th iteration. However, I have made the changes which will not throw the error. But you need to debug that image
for i in range(0,len(x)):
print(i)
img[i] = cv2.imread(x[i], cv2.IMREAD_GRAYSCALE)
if img[i]:
indices[i] = np.where(img[i]<100)

Resources