storing and retrieving images in dictionary - python - python

Can anyone tell me how to store images in python dictionary (dict), and how to retrieve images from the dictionary based on the key value ?

It is better to store images in files and then reference them with a filename:
pictures = {'mary': '001.jpg', 'bob', '002.jpg'}
filename = pictures['mary']
with open(filename. 'rb') as f:
image = f.read()
That said, if you want to store images directly in a dictionary, just add them:
pictures = {}
with open('001.jpg', 'rb') as f:
image = f.read()
pictures['mary'] = image
Images aren't special, they are just data.

Personally, if I had to go down that road, I would load the image into a variable and then add it to dictionary as a value {key:value} as you would with any other variable. If you are using Pygame you don't need to load it as a file and can already load the image using pygame.image.load(file) .
Just a note : Loading image files, especially JPEGs in binary as suggested is tricky. Python on Windows makes a distinction between text and binary files; the end-of-line characters in text files are automatically altered slightly when data is read or written. This behind-the-scenes modification to file data is fine for ASCII text files, but it’ll corrupt binary data like that in JPEG or EXE files. Be very careful to use binary mode when reading and writing such files.
As with images in dictionaries, you could even nest a list of images in the dictionary (along with a key), Having a list is one way to easily animate by looping the list within each key. {'key1' : ['value1', 'value2','value2']}
Remember however that once you pack a variable inside a dictionary, the value of the variable would not change and remain constant inside the dictionary, unless you specifically update the dictionary. Just updating the value outside of the dictionary, would not affect it's original value that it was given when it was placed inside the dictionary.
Example: (using pygame, load images into a list, and nest it into a dictionary for recall)
def load_image(file):
"""loads and prepares image from data directory"""
file = os.path.join(main_dir, 'data', file)
try:
surface = pygame.image.load(file)
except pygame.error:
raise SystemExit('Could not load image "%s" %s'%(file, pygame.get_error()))
return surface.convert()
def load_images(*files):
""" function to load a list of images through an *arg and return a list
of images"""
images = []
for file in files:
images.append(load_image(file))
return images
bomb_images = load_images('bomb.gif', 'bomb2.gif','bomb3.gif')
explosion_images = load_images('ex1.gif', 'ex2.gif', 'ex3.gif')
# now all the images are inside a list and you can pack them in a dictionary
image_dict = {'bomb' : bomb_images, 'explode' :explosion_images}
# to call the image would be the same as you call any value from the dict
bombs = image_dict['bomb']
image_ready_for_blit = bombs[0]
# changing the slice position allows animation loops [0]

Related

How to check if Image Data can be returned from a Dictionary?

I am currently writing a Python module, in one portion of the function I am saving a tiff image to a dictionary. However I am not sure how to actually validate that this is happening? How do I call or return the array from the dictionary the tiff file is saved in? Do I simply need to end my function with return optional_dict?
optional_dict={}
if showMaps==True:#Conditional argument for saving the tiff image
#Tiff image saved in a temporary directory
with open(outputdir+f"ROI-{NAME}-thickness_tif", 'rb') as f:
thickness_tif = f.read()# Read tiff image
thickness_tif = optional_dict["thickness_tif"] #Save to dictionary with keyword
If you want to save thickness_tif to a dictionary optional_dict, you have to reverse the expression:
# Save to dictionary with keyword
# INCORRECT: thickness_tif = optional_dict["thickness_tif"]
optional_dict["thickness_tif"] = thickness_tif
And if you want to check what was written, you may simply print the value stored in your dictionary:
print(optional_dict["thickness_tif"])

update data set after extracting features from face in python using pickle

I am new in python and following this article https://www.mygreatlearning.com/blog/face-recognition/#whatsopencv to extract features from face. After trying it, I realise that I do looping inside directory Images for each image and then save it inside face_enc:
datas = {"encodings": knownEncodings, "names": knownNames}
f = open("face_enc", "wb")
f.write(pickle.dumps(datas))
f.close()
So, the thing that makes me confused is, let's say that I have 50 images inside Images directory then I add another 100 images (just for example), so I will do looping from the start (1-150 images) and then save it in face_enc. Is there a way to update data inside face_enc without saving it from the start to saving time?

How to get the images and load it in the variable name same as the image name

I want my code to load all the images automatically. For now I have to
write code for each images separately, but i want it to automatically get all the images from the directory, use the image name as the variable to load image file and also modify the image name to store the encodings.
p_image = face_recognition.load_image_file("p.jpg")
P_face_encoding = face_recognition.face_encodings(p_image)[0]
Source for the face recognition code ( this is not my original code)
https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam_faster.py
import glob
p_image_list = []
for each_image in glob.glob("*.jpg"):
p_image_list.append(face_recognition.load_image_file(each_image)
p_image_list contains all the images in current folder
You can use a dictionary where items will be your variable names and have corresponding values of file names:
import os
files = os.listdir()
file_dict = {file : os.path.splitext(file) for file in files}

Why is the encoding from Exif tags fail after updating image

I have to in to a problem with adding new tags to Exif data for an image.
The setting
I have created a PySimpleGUI python script for simple image manipulation and worked out all but the last steps.
The script displays an image (jpg, jepg) and a key Exif data. The script uses a series of checkboxes to 'tag' and image quickly from a selection (list). I have the array of checkboxes, image updating properly. So I can decode the Exif data properly, but when I want to update the image I run into problems.
I use Windows 10 with Python3, with Imports from PIL, PySimpleGUI.
The meta data:
40094 (Exif ID for the key I want to update)
Exif.Image.XPKeywords
Byte (variable type)
Keywords tag used by Windows (encoded in UCS2)
I found some help: Encode UCS2
Using the help from above I can get this:
Exif: b'O\x00u\x00t\x00d\x00o\x00o\x00r\x00;\x00a\x00r\x00t\x00\x00\x00'
Converts to Outdoor;art
<i = 40094>
img = Image.open(pathname + '\\' + filename)
exifDataRaw = img._getexif()
if exifDataRaw.get(i):
if exifDataRaw[i]:
print("Exif:", exifDataRaw[i])
return str(exifDataRaw[i].decode('utf-16'))
Good, I can convert that str to a list and update the checkboxes.
Updating the Tags (Keywords)
I add more keywords to the str. Now:Outdoor;art;box;machine;
To update the keys I have this function. Checkboxes selected are True, and unselected are False.
PySimpleGUI as collects events and vales. The function scans the values for selected "True".
TaggerList is the master list of tags I use in the script. When a checkbox is True the loop adds the Tags to the InsertString. Shown above.
def PushTags(pathname, filename):
InsertString = ""
img = Image.open(pathname + '\\' + filename)
for Tag in TaggerList[:-1]:
if values[Tag]:
InsertString = InsertString + Tag + ";"
first = False
#Get whole dataset
exifDataRaw = img._getexif()
i = 40094
# Set new data to Exif
exifDataRaw[i] = InsertString[:-1].encode('utf-16') # remove the last ";" and encode
img.save(pathname + '\\' + filename, exif=exifDataRaw) #Update image with new values
I can use Image.Exif.__setitem__(i, InsertString[:-1].encode('utf-16')) to save just the updated keywords.
But the encoding still give an error.
The original: Exif: b'O\x00u\x00t\x00d\x00o\x00o\x00r\x00;\x00a\x00r\x00t\x00\x00\x00'
Saved Tags: b'\xff\xfeu\x00t\x00d\x00o\x00o\x00r\x00;\x00a\x00r\x00t\x00;\x00b\x00o\x00x\x00;\x00m\x00a\x00c\x00h\x00i\x00n\x00e\x00'
The encoding does not seem to be mutual both ways. The encoded string adds '\xff\xfeu I assume \xfeu is a capital 'O'.
The encoding is wrong and breaks the image. General image viewers error out the updated image.
If I can fix this I can then finish the script.
I figured out what was at issue.
The encoding is a priory to byte order.
To get the format I wanted I needed little endian notation. In python utf_16_le little and utf_16_be for big endian codecs.
utf_16_le puts the first 8 bits of the data at the head and then the last 8 bits at the tail.
i = 40094
img = Image.open(pathname + '\\' + filename)
exifDataRaw = img._getexif()
if exifDataRaw.get(i):
if exifDataRaw[i]:
print("Exif:", exifDataRaw[i])
return str(exifDataRaw[i].decode('utf_16_le'))
In this code I get the expected results. b'a\x00b\x00c\x00d\x00...
So Image Exif data is little endian byte ordered.

save multi directory images in a single file after preprocessing

I am working on DICOM images, I have 5 scans(folders) each scan contain multiple images, after working some preprocessing on the images, I want to save the processed images in a single file using "np.save", I have the code below that save each folder in a separate file:
data_path = 'E:/jupyter/test/LIDC-IDRI/'
patients_data = os.listdir(data_path)
for pd in range(len(patients_data)):
full_path = load_scan(data_path + patients_data[pd])
after_pixel_hu = get_pixels_hu(full_path)
after_resample, spacing = resample(after_pixel_hu, full_path, [1,1,1])
np.save(output_path + "images_of_%s_patient.npy" % (patients_data[pd]), after_resample)
load_scan is a function for loading(reading) DICOM files, what I want to do with this code is to save all processed images in a single file, not in five files, can anyone tell me how to do that, please?
The first thing to notice is that you are using %s with patients_data[pd]. I assume patients_data is a list of the names of the patients, which means you are constructing a different output path for each patient - you are asking numpy to save each of your processed images to a new location.
Secondly, .npy is probably not the file type you want to use for your purposes, as it does not handle appending data. You probably want to pick a different file type, and then np.save() to the same file path each time.
Edit: Regarding file type, a pdf may be your best option, where you can make each of your images a separate page.

Categories