Added multi-line tagging, and arg parseing

master
Jonathan Chan 2 years ago
parent 7d1df4b942
commit 34bfe4eec9

@ -2,10 +2,13 @@ from pathlib import Path
import pandas as pd import pandas as pd
import os import os
os.chdir(Path(__file__).parent.resolve()) os.chdir(Path(__file__).parent.resolve())
from utils import datenum_to_datetime, RegisteredImage from utils import datenum_to_datetime, RegisteredImage, get_site_tide_data
import openpyxl import openpyxl
import scipy.io as sio import scipy.io as sio
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
from loguru import logger
import argparse
''' '''
SCRIPT LOGIC SCRIPT LOGIC
@ -18,49 +21,37 @@ For each site in Images Parent Directory:
If yes, skip to the next site If yes, skip to the next site
''' '''
#-----------------------------------------------------------------------------#
# Get command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument("--tag_deleted", action='store_true', required=False)
parser.add_argument("--overwrite", action='store_true', required=False)
parser.add_argument("--site", type=str, required=False)
args = parser.parse_args()
#-----------------------------------------------------------------------------# #-----------------------------------------------------------------------------#
# Update this file path for Image Tagging - Tide Data # Retrieve coastsnap/images directory set in coastsnap_sites.csv
# Example: images_dir = '/Users/admin/OneDrive - UNSW/My files/CoastSnap/'
code_images_dir = str(Path(os.getcwd()).parent) code_images_dir = str(Path(os.getcwd()).parent)
sites_csv_path = os.path.join(code_images_dir, "coastsnap_sites.csv") sites_csv_path = os.path.join(code_images_dir, "coastsnap_sites.csv")
# RETRIEVE IMAGES PARENT DIRECTORY IN coastsnap_sites.csv
coastsnap_sites_csv = pd.read_csv(sites_csv_path) coastsnap_sites_csv = pd.read_csv(sites_csv_path)
images_parent_dir = coastsnap_sites_csv.parent_directory[0] images_parent_dir = coastsnap_sites_csv.parent_directory[0]
images_dir = os.path.join(images_parent_dir, "Images") images_dir = os.path.join(images_parent_dir, "Images")
#-----------------------------------------------------------------------------#
def get_site_tide_data(images_parent_dir, site):
# Retrieve tide data for the given site
db = openpyxl.load_workbook(images_parent_dir + "/Database/CoastSnapDB.xlsx")
beach_data = db[site]
tide_filename = beach_data["B24"].value
if tide_filename == 'NO_TIDE.mat':
return False
tide_filename_pkl = tide_filename[:-4] + '.pkl'
tides_path = images_parent_dir + '/Tide Data/Tide_Data_Python/' + tide_filename_pkl
tides_df = pd.read_pickle(tides_path)
return tides_df
#-----------------------------------------------------------------------------#
# Tag image function
def tag_image(image2tag): def tag_image(image2tag):
image = Image.open(image2tag.pathname) image = Image.open(image2tag.pathname)
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
image2tag.get_dimensions()
# White Text Box # White Text Box
rect_height = image2tag.height/20 if image2tag.large_filename:
rect_height = image2tag.height/13
else:
rect_height = image2tag.height/20
# Create white text box # Create white text box
draw.rectangle((0, 0, image2tag.width, rect_height), fill='white') draw.rectangle((0, 0, image2tag.width, rect_height), fill='white')
@ -75,62 +66,69 @@ def tag_image(image2tag):
image.save(registered_path) image.save(registered_path)
#-----------------------------------------------------------------------------# #-----------------------------------------------------------------------------#
# This is the main function # Main function (called below)
image2tag = None def main(site):
for site in os.listdir(images_dir): # Loop through SITES
print(site)
i=0 i=0
site_complete = False # A flag to stop tagging images when found site_complete = False # A flag to stop tagging images when found
tide_data = False tide_data = False
font = None font = None
image2tag = None
photoshop_path = images_dir +'/'+ site + '/Photoshop' photoshop_path = images_dir +'/'+ site + '/Photoshop'
try: # Check if site contains 'Processed' directory try: # Check if site contains 'Processed' directory
years_list = os.listdir(photoshop_path) years_list = os.listdir(photoshop_path)
years_list.reverse() years_list.reverse()
except: # Site doesn't contain 'Processed'. Go to next site. except: # Site doesn't contain 'Processed'. Go to next site.
continue return
for year in years_list: # Loop through YEARS
# Loop through YEARS
for year in years_list:
if site_complete: break if site_complete: break
year_path = photoshop_path + '/' + year year_path = photoshop_path + '/' + year
image_list = os.listdir(year_path) image_list = os.listdir(year_path)
image_list.reverse() image_list.reverse()
for image_filename in image_list: # Loop through IMAGES # Loop through IMAGES
for image_filename in image_list:
registered_year_path = year_path.replace('Photoshop', 'Registered') registered_year_path = year_path.replace('Photoshop', 'Registered')
registered_image_path = registered_year_path + '/' + image_filename[:-4] + '_registered.jpg' registered_image_path = registered_year_path + '/' + image_filename[:-4] + '_registered.jpg'
if site not in image_filename: # Check the filename has the site in it if site not in image_filename: # Check the filename has the site in it
continue continue
if os.path.isfile(registered_image_path): # Image already tagged. Go to next site. # Case: Image already tagged
site_complete = True; if os.path.isfile(registered_image_path):
if i == 0: if args.tag_deleted: # If 'tag_deleted' = True, continue to next image
print(site + ": " + str(i) + " images tagged") continue
elif image2tag and image2tag.tide: elif args.overwrite: # If 'overwrite' = True, pass and tag image
print(site + ": " + str(i) + " images tagged with tide") pass
else: else: # Otherwise, stop tagging and go to the next site
print(site + ": " + str(i) + " images tagged no tide") site_complete = True;
break if i == 0:
print(site + ": " + str(i) + " images tagged")
else: # Image not tagged. Tag it. elif image2tag and image2tag.tide:
if not os.path.exists(registered_year_path): # Chech that registered/year directory exists print(site + ": " + str(i) + " images tagged with tide")
os.makedirs(registered_year_path) # if not, create it else:
i += 1 print(site + ": " + str(i) + " images tagged no tide")
pathname = os.path.join(year_path, image_filename) return
image2tag = RegisteredImage(pathname, image_filename) # Create image object
if i == 1: # Retrieve Tide Data once for each site # Case: Image not tagged or 'overwrite' = True
tides_df = get_site_tide_data(images_parent_dir, site) if not os.path.exists(registered_year_path): # Chech that registered/year directory exists
os.makedirs(registered_year_path) # if not, create it
font = image2tag.get_font() i += 1
if tides_df: image2tag.get_tide(tides_df) pathname = os.path.join(year_path, image_filename)
image2tag.create_tag() image2tag = RegisteredImage(pathname, image_filename) # Create image object
if i == 1: # Retrieve Tide Data once for each site
tag_image(image2tag) tides_df = get_site_tide_data(images_parent_dir, site)
# No images previously tagged font = image2tag.get_font()
# print result image2tag.get_dimensions()
if isinstance(tides_df, pd.DataFrame): image2tag.get_tide(tides_df)
image2tag.create_tag()
tag_image(image2tag)
# Case: All images tagged
if not site_complete: if not site_complete:
if i == 0: if i == 0:
print(site + ": " + str(i) + " images tagged") print(site + ": " + str(i) + " images tagged")
@ -138,3 +136,15 @@ for site in os.listdir(images_dir): # Loop through SITES
print(site + ": " + str(i) + " images tagged with tide") print(site + ": " + str(i) + " images tagged with tide")
else: else:
print(site + ": " + str(i) + " images tagged no tide") print(site + ": " + str(i) + " images tagged no tide")
#-----------------------------------------------------------------------------#
# Calling the main function with the two cases
if args.site: # Case 1: User specifies a site
main(args.site)
else: # Case 2: No site specified. Tag all images
for site in os.listdir(images_dir):
main(site)

@ -3,6 +3,8 @@ from datetime import datetime, timedelta
import sys import sys
from time import strptime from time import strptime
from PIL import Image, ImageFont from PIL import Image, ImageFont
import pandas as pd
import openpyxl
def divide_chunks(l, n): def divide_chunks(l, n):
""" """
@ -51,6 +53,22 @@ def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.3+
print("\n", flush=True, file=out) print("\n", flush=True, file=out)
def get_site_tide_data(images_parent_dir, site):
# Retrieve tide data for the given site
db = openpyxl.load_workbook(images_parent_dir + "/Database/CoastSnapDB.xlsx")
beach_data = db[site]
tide_filename = beach_data["B24"].value
if tide_filename == 'NO_TIDE.mat':
return False
tide_filename_pkl = tide_filename[:-4] + '.pkl'
tides_path = images_parent_dir + '/Tide Data/Tide_Data_Python/' + tide_filename_pkl
tides_df = pd.read_pickle(tides_path)
return tides_df
class RegisteredImage(): class RegisteredImage():
def __init__(self, pathname, filename): def __init__(self, pathname, filename):
@ -77,6 +95,7 @@ class RegisteredImage():
self.width = None self.width = None
self.height = None self.height = None
self.font = None self.font = None
self.large_filename = False
def get_tide(self, tides_df): def get_tide(self, tides_df):
@ -97,18 +116,33 @@ class RegisteredImage():
hour = self.hour.zfill(2) hour = self.hour.zfill(2)
minute = self.minute.zfill(2) minute = self.minute.zfill(2)
if self.tide: if self.tide: # Tag with tide data
tide = self.tide tide = self.tide
if float(self.tide) >= 0: if float(self.tide) >= 0:
tide = '+' + self.tide tide = '+' + self.tide
self.tag = ('Date:' + self.year + '/' + self.month + '/' + self.day + tag = ('Date:' + self.year + '/' + self.month + '/' + self.day +
' Time:' + hour + ':' + minute +
' Tide:' + tide + 'm AHD' +
' Contributor:' + self.contributor)
if(self.font.getsize(tag)[0] > self.width): # Check if text is wider than the image
self.large_filename = True
tag = ('Date:' + self.year + '/' + self.month + '/' + self.day +
' Time:' + hour + ':' + minute + ' Time:' + hour + ':' + minute +
' Tide:' + tide + 'm AHD' + ' Tide:' + tide + 'm AHD' + '\n' +
' Contributor:' + self.contributor) 'Contributor:' + self.contributor)
else: self.tag = tag
self.tag = ('Date:' + self.year + '/' + self.month + '/' + self.day +
else: # Tag without tide data
tag = ('Date:' + self.year + '/' + self.month + '/' + self.day +
' Time:' + hour + ':' + minute + ' Time:' + hour + ':' + minute +
' Contributor:' + self.contributor) ' Contributor:' + self.contributor)
if(self.font.getsize(tag)[0] > self.width): # Check if text is wider than the image
self.large_filename = True
tag = ('Date:' + self.year + '/' + self.month + '/' + self.day +
' Time:' + hour + ':' + minute + '\n' +
'Contributor:' + self.contributor)
self.tag = tag
def get_dimensions(self): def get_dimensions(self):
image = Image.open(self.pathname) image = Image.open(self.pathname)
@ -124,11 +158,15 @@ class RegisteredImage():
img_fraction = 0.95 img_fraction = 0.95
else: else:
img_fraction = 0.85 img_fraction = 0.85
font = ImageFont.truetype("fonts/Courier New Bold.ttf", fontsize) font = ImageFont.truetype("fonts/LiberationMono.ttf", fontsize)
generic_large_tag = "1641775682.Mon.Jan.10_11_48_02.AEDT.2022.byron.snap.KateThornborough123" generic_large_tag = "1641775682.Mon.Jan.10_11_48_02.AEDT.2022.byron.snap.KateThornborough123"
while font.getsize(generic_large_tag)[0] < img_fraction*image.size[0]: while font.getsize(generic_large_tag)[0] < img_fraction*image.size[0]:
# iterate until the text size is just larger than the criteria # iterate until the text size is just larger than the criteria
fontsize += 1 fontsize += 1
font = ImageFont.truetype("fonts/Courier New Bold.ttf", fontsize) font = ImageFont.truetype("fonts/LiberationMono.ttf", fontsize)
self.font = ImageFont.truetype("fonts/Courier New Bold.ttf", fontsize) self.font = ImageFont.truetype("fonts/LiberationMono.ttf", fontsize)
Loading…
Cancel
Save