I have a list of images with the following names 47A, 33B, 2C, etc all alphnumeric with characters length until 10. The extension of all images is .png
I've created a python program to read one by one this images and extract information (contours area etc etc ). To do this, inside the script I always use the replacement crtl + H to change the names in the following codes:
#open image
img = cv2.imread("A.png", 0) in this case A is the name of an image
#save image
cv2.imwrite("A_copy.png", img)
#assign name into ID column
dframe['ID'] = 'A'
#save data into this path
dframe.to_csv(r'D:\\NBC_new2020_\\data\\A_data.txt', index = False, sep='\t')
I'm trying to open an image, save image, assign name to ID column and save the dataframe by changing the A to 47B and run the program then for 33B and run the program etc etc with replace crtl + H in the script.
For the moment is the only way to change it.
Is there any other way to change it? I was trying with the following code:
A = input('Insert the name of file in png extension:')
A = str(A)
47
img = cv2.imread("A.png", 0)
###########################################################
The A value is considered as a string but the program doesn"t allow to run it well
I would like to know how to replace the "A" as an input before start the python program (like ask me as an input)
Someone please help?
Thanks
You should replace "A.png" with A + ".png".
When inside quotes, everything is treated as their literal string value. You can concatenate strings with the plus operator to use variables.
Related
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.
Directory I would need to save to:
DataBase-Faces\name
Directory where the code is saving:
DataBase-Faces
My code:
cv2.imwrite("DataBase-Faces\\"+name+str(frames)+".png",Faceimage)
My program creates a folder with the typed name, I have to record these images in that folder, and the name of each image will be called Nome Typed + (frame number) .png
It looks like you're forgetting to put a directory separator between name and str(frames).
Try
image_path = '\\'.join(['DataBase-Faces', name, str(frames) + '.png'])
cv2.imwrite(image_path, Faceimage)
As a side note, you should not be concatenating paths by hand. Consider looking into the os.path module, which can save you from this sort of headache in the future.
General the Code to save the image is something like that
cv2.imwrite('file.png',img)
For the 'file.png' u want to be
EXAMPLE
name = 'my_photo_album_name'
frames = 500
frame_name = f'{name}\{frames}'
cv2.imwrite(f'DataBase-Faces\{frame_name}.png', img)
I'm currently working on converting breastcancer scans into black and white photos. This code needs to scan every file in the directory, process it, and save it with a unique name. My code looks like this:
wd = os.getcwd()
lencounter = 0
for file in os.listdir(wd):
lencounter += 1
for x in range(lencounter):
for file in os.listdir(wd):
if file.endswith("class0.png"):
image_file = Image.open(file)
image_file= image_file.convert('L')
image_file= image_file.convert('1')
print(image_file, x)
image_file.save("result1.png")
This code only allows me to save the last transformed picture, as "result1". Somehow the .save function doesn't let me include any iterationumber, just like you would expect when using the write() function.
I need something like "originalname_blackandwhite1.png" for every picture. I hope someone could help me out!
Thanks
What about image_file.save("{}_blackandwhite1.png".format(x))?
It can be more specific if you elaborate on how do you want your originalname to be
Hi i'm working on a program where a user selects an image, then it gets turned into an ASCII version of the picture, which displays in both the console and then gets saved to a notepad .txt file. The code below currently does this but I think the way I am using my returns in the functions is messing up the code. Instead of asking for the image and background colour once, it asks for it 3 times before actually drawing out the ASCII image. Then after it has drawn it, it again asks for a 4th time for the image and background colour, before finally asking for the name to give the .txt file then creating the text file.
How do I change this so that it only asks each question once without repeating itself(and what exactly is this happening?). Thanks
def inputs():
image = input('What image file?')
return (image)
def pictureConvert():
a = inputs()
# codefollows
Call the inputs function only once, and store that everywhere. This ensures that the user will be asked for input only once:
def inputs():
image = input('What image file?')
return (image)
def pictureConvert():
a = inputs()
# codefollows
I am writing an image processing program, which works well, but I need to process multiple images.
First, I made an array of images:
images = ((image1.tif),
(image2.tif),
(image3.tif))
Then, I created a for loop:
for image in images:
dna = cv2.imread(image)
{code}
The problem is, whenever I run the code, the console returns an error of
TypeError: expected string or Unicode object, tuple found
At this line:
dna = cv2.imread(image)
It seems that the program is trying to process the whole array at once. I thought that the loop worked by processing one image in the array at a time? Can anybody help me with this?
You should wrap the filenames using single or double quotes:
images = (('image1.tif'),
('image2.tif'),
('image3.tif'))
You can also use list instead of tuples:
images = ['image1.tif', 'image2.tif', image3.tif']
Use:
images = (("image1.tif"),
("image2.tif"),
("image3.tif"))