to do: debug existing JSON file feature
This commit is contained in:
40
config.py
40
config.py
@@ -3,10 +3,16 @@ import psycopg2
|
|||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
# store all user input
|
# store all user input
|
||||||
def __init__(self):
|
def __init__(self, format=None):
|
||||||
self.data_path = None
|
if format:
|
||||||
self.pg_config = None
|
self = format
|
||||||
self.sort_by_match_strength = False
|
else:
|
||||||
|
self.data_path: str = ""
|
||||||
|
self.pg_config = None
|
||||||
|
self.sort_by_match_strength: bool = False
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"data path: {self.data_path}, pg_config: {self.pg_config}, sorted: {str(self.sort_by_match_strength)}"
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Completes new config process or uses an existing one. Dumps new data into a JSON file if it is generated, and returns either an old instance of `Config` or the new one as `self`"""
|
"""Completes new config process or uses an existing one. Dumps new data into a JSON file if it is generated, and returns either an old instance of `Config` or the new one as `self`"""
|
||||||
@@ -15,14 +21,14 @@ class Config:
|
|||||||
if prev_config is not None:
|
if prev_config is not None:
|
||||||
return prev_config
|
return prev_config
|
||||||
else:
|
else:
|
||||||
self.get_data_path()
|
self.receive_data_path()
|
||||||
self.set_pg_config()
|
self.set_pg_config()
|
||||||
self.output_formatting()
|
self.output_formatting()
|
||||||
with open("./config.json", "w") as outfile:
|
with open("./config.json", "w") as outfile:
|
||||||
json.dump(self.__encode(), outfile)
|
json.dump(self.__encode(), outfile)
|
||||||
return self
|
return self
|
||||||
else:
|
else:
|
||||||
self.get_data_path()
|
self.receive_data_path()
|
||||||
self.set_pg_config()
|
self.set_pg_config()
|
||||||
self.output_formatting()
|
self.output_formatting()
|
||||||
with open("./config.json", "w") as outfile:
|
with open("./config.json", "w") as outfile:
|
||||||
@@ -35,26 +41,33 @@ class Config:
|
|||||||
response_for_prev_config = input("Use existing configuration file? y/n " ).lower()
|
response_for_prev_config = input("Use existing configuration file? y/n " ).lower()
|
||||||
|
|
||||||
if response_for_prev_config == "y":
|
if response_for_prev_config == "y":
|
||||||
prev_data: Config = open("./config.json")
|
with open("./config.json", "r") as infile:
|
||||||
prev_data = json.load(prev_data)
|
config_data = json.load(infile)
|
||||||
return prev_data
|
|
||||||
|
return Config(config_data)
|
||||||
elif response_for_prev_config == "n":
|
elif response_for_prev_config == "n":
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
print("Invalid response.")
|
print("Invalid response.")
|
||||||
self.handle_prev_config()
|
self.handle_prev_config()
|
||||||
|
|
||||||
def get_data_path(self):
|
def receive_data_path(self):
|
||||||
"""Locates a valid directory from user input and stores it in Config state as `self.data_path`."""
|
"""Locates a valid directory from user input and stores it in Config state as `self.data_path`."""
|
||||||
data_path = input("Provide the location of the directory where we can find your photos: ")
|
data_path = input("Provide the location of the directory where we can find your photos: ")
|
||||||
|
|
||||||
if not os.path.exists(data_path):
|
if not os.path.exists(data_path):
|
||||||
print("We didn't find a directory by this name.")
|
print("We didn't find a directory by this name.")
|
||||||
self.data_path = self.get_data_path()
|
self.receive_data_path()
|
||||||
else:
|
else:
|
||||||
print("Got it!")
|
print("Got it!")
|
||||||
self.data_path = data_path
|
self.data_path = data_path
|
||||||
|
|
||||||
|
def get_data_path(self):
|
||||||
|
return self.data_path
|
||||||
|
|
||||||
|
def set_data_path(self, value):
|
||||||
|
self.data_path = value
|
||||||
|
|
||||||
def set_pg_config(self):
|
def set_pg_config(self):
|
||||||
"""Determine if data should be associated with a PostgreSQL instance, and, if so, record the required connection info"""
|
"""Determine if data should be associated with a PostgreSQL instance, and, if so, record the required connection info"""
|
||||||
elect_for_pg = input("Connect this program to a PostgreSQL instance? y/n ").lower()
|
elect_for_pg = input("Connect this program to a PostgreSQL instance? y/n ").lower()
|
||||||
@@ -107,7 +120,4 @@ class Config:
|
|||||||
self.output_formatting()
|
self.output_formatting()
|
||||||
|
|
||||||
def __encode(self):
|
def __encode(self):
|
||||||
return json.dumps(self, default=lambda x: x.__dict__)
|
return json.dumps(self, default=lambda x: x.__dict__)
|
||||||
|
|
||||||
new_config = Config()
|
|
||||||
new_config.run()
|
|
||||||
@@ -1,47 +1,74 @@
|
|||||||
import json, os, shutil
|
import json, os, shutil
|
||||||
|
from config import Config
|
||||||
|
|
||||||
def format_result(src_path, json_path):
|
def format_result(app_config: Config, json_path):
|
||||||
|
# dictionary to hold and later display our results
|
||||||
insertions_by_label = {}
|
insertions_by_label = {}
|
||||||
|
|
||||||
|
data_path = app_config.data_path
|
||||||
|
|
||||||
|
# if pg_config is not None, run the postgres prediction[0] of this code
|
||||||
|
pg_config = app_config.pg_config
|
||||||
|
|
||||||
|
# if this is True, run the prediction[0] "for line in contents:" below
|
||||||
|
sort_by_match_strength = app_config.sort_by_match_strength
|
||||||
|
|
||||||
weak_results = 0
|
weak_results = 0
|
||||||
total_count = 0
|
total_count = 0
|
||||||
|
|
||||||
|
# store analysis results in contents
|
||||||
with open(json_path) as results:
|
with open(json_path) as results:
|
||||||
contents = json.load(results)
|
contents = json.load(results)
|
||||||
|
|
||||||
for qualifier in ['strong', 'moderate', 'fair', 'weak']:
|
# prepare individual locations for match strengths if sort is enabled
|
||||||
if not os.path.exists("./predictions/" + qualifier):
|
if sort_by_match_strength:
|
||||||
os.makedirs('./predictions/' + qualifier)
|
for qualifier in ['strong', 'moderate', 'fair', 'weak']:
|
||||||
|
if not os.path.exists("./predictions/" + qualifier):
|
||||||
|
os.makedirs('./predictions/' + qualifier)
|
||||||
|
|
||||||
|
# handles data for each photo
|
||||||
for line in contents:
|
for line in contents:
|
||||||
img_path = src_path + line['path']
|
img_path = data_path + line['path']
|
||||||
prediction = line['prediction']
|
prediction = line['prediction']
|
||||||
for section in prediction:
|
|
||||||
total_count += 1
|
|
||||||
guess_label = section[0][1]
|
|
||||||
match_strength = 'weak/'
|
|
||||||
|
|
||||||
if float(section[0][2]) > 0.9:
|
# handles data for first prediction for a given photo
|
||||||
match_strength = 'strong/'
|
total_count += 1
|
||||||
elif float(section[0][2]) > 0.75:
|
guess_label = prediction[0][0][1]
|
||||||
match_strength = 'moderate/'
|
match_strength = 'weak'
|
||||||
elif float(section[0][2]) > 0.5:
|
|
||||||
match_strength = 'fair/'
|
|
||||||
elif match_strength == 'weak/':
|
|
||||||
weak_results += 1
|
|
||||||
|
|
||||||
if not guess_label in insertions_by_label:
|
# assign value for match strength
|
||||||
insertions_by_label[guess_label] = 0
|
if float(prediction[0][0][2]) > 0.9:
|
||||||
|
match_strength = 'strong'
|
||||||
|
elif float(prediction[0][0][2]) > 0.7:
|
||||||
|
match_strength = 'moderate'
|
||||||
|
elif float(prediction[0][0][2]) > 0.4:
|
||||||
|
match_strength = 'fair'
|
||||||
|
elif match_strength == 'weak':
|
||||||
|
weak_results += 1
|
||||||
|
|
||||||
|
# modify variable for path
|
||||||
|
match_strength = match_strength + "/"
|
||||||
|
|
||||||
|
if not guess_label in insertions_by_label:
|
||||||
|
insertions_by_label[guess_label] = 0
|
||||||
|
|
||||||
|
# copy file to appropriate location, depending on if sorting
|
||||||
|
if sort_by_match_strength:
|
||||||
if (not os.path.exists("./predictions/" + match_strength + guess_label)):
|
if (not os.path.exists("./predictions/" + match_strength + guess_label)):
|
||||||
os.makedirs("./predictions/" + match_strength + guess_label)
|
os.makedirs("./predictions/" + match_strength + guess_label)
|
||||||
|
|
||||||
if (not os.path.exists('./predictions/' + match_strength + guess_label + '/' + img_path)):
|
if (not os.path.exists('./predictions/' + match_strength + guess_label + '/' + img_path)):
|
||||||
shutil.copy(img_path, "./predictions/" + match_strength + guess_label)
|
shutil.copy(img_path, "./predictions/" + match_strength + guess_label)
|
||||||
insertions_by_label[guess_label] = insertions_by_label[guess_label] + 1
|
insertions_by_label[guess_label] = insertions_by_label[guess_label] + 1
|
||||||
|
else:
|
||||||
|
if (not os.path.exists("./predictions/" + guess_label)):
|
||||||
|
os.makedirs("./predictions/" + guess_label)
|
||||||
|
if (not os.path.exists('./predictions/' + guess_label + '/' + img_path)):
|
||||||
|
shutil.copy(img_path, "./predictions/" + guess_label)
|
||||||
|
insertions_by_label[guess_label] = insertions_by_label[guess_label] + 1
|
||||||
|
|
||||||
|
|
||||||
print(str(weak_results) + " weak result(s) of a total " + str(total_count) + " input(s)\n")
|
print(str(weak_results) + " weak result(s) of a total " + str(total_count) + " input(s)\n")
|
||||||
print("By subject:\n\n")
|
print("By subject:\n")
|
||||||
|
|
||||||
for k, v in insertions_by_label.items():
|
for k, v in insertions_by_label.items():
|
||||||
print(k + ": " + str(v) + " file(s) found")
|
print(k + ": " + str(v) + " file(s) found")
|
||||||
|
|||||||
34
main.py
34
main.py
@@ -6,36 +6,30 @@
|
|||||||
import os, json
|
import os, json
|
||||||
from config import Config
|
from config import Config
|
||||||
from time import time
|
from time import time
|
||||||
from predict import predict
|
|
||||||
from formatresult import format_result
|
|
||||||
from keras.applications.vgg16 import VGG16
|
|
||||||
|
|
||||||
print("\n\nImage Sorting Utility\n")
|
print("\nImage Sorting Utility\n")
|
||||||
print("Script by Mikayla Dobson\n")
|
print("Script by Mikayla Dobson\n")
|
||||||
print("\n\n")
|
print("\n\n")
|
||||||
|
|
||||||
############################## CONFIG
|
############################## CONFIG
|
||||||
|
|
||||||
print("Running app config...")
|
print("Running app config...")
|
||||||
appconfig = Config()
|
appconfig: Config = Config()
|
||||||
config_file = appconfig.run()
|
config_file = appconfig.run()
|
||||||
|
|
||||||
############################## SETUP
|
if (config_file.get_data_path()[-1] != "/"):
|
||||||
############################## SETUP
|
config_file.set_data_path(config_file.get_data_path() + "/")
|
||||||
############################## SETUP
|
|
||||||
|
|
||||||
# create the target directory if it doesn't exist
|
# create the target directory if it doesn't exist
|
||||||
if (not os.path.exists("./predictions")):
|
if (not os.path.exists("./predictions")):
|
||||||
print("Did not find predictions directory, creating...\n\n")
|
print("Did not find predictions directory, creating...\n\n")
|
||||||
os.makedirs("./predictions")
|
os.makedirs("./predictions")
|
||||||
|
|
||||||
# receive directory path as CLI argument and get a list of all files in path
|
############################## SETUP
|
||||||
src_path = config_file.data_path
|
############################## SETUP
|
||||||
|
############################## SETUP
|
||||||
|
|
||||||
if (src_path[-1] != "/"):
|
files = os.listdir(config_file.data_path)
|
||||||
src_path += "/"
|
|
||||||
|
|
||||||
files = os.listdir(src_path)
|
|
||||||
|
|
||||||
# generate current time for use in identifying outfiles
|
# generate current time for use in identifying outfiles
|
||||||
cur_time = str(int(time()))
|
cur_time = str(int(time()))
|
||||||
@@ -47,6 +41,14 @@ all_results = []
|
|||||||
############################## ANALYSIS
|
############################## ANALYSIS
|
||||||
############################## ANALYSIS
|
############################## ANALYSIS
|
||||||
|
|
||||||
|
print("Attempting TF imports...\n\n")
|
||||||
|
|
||||||
|
from predict import predict
|
||||||
|
from formatresult import format_result
|
||||||
|
from keras.applications.vgg16 import VGG16
|
||||||
|
|
||||||
|
print("Success!")
|
||||||
|
|
||||||
# declare model to be used for each prediction
|
# declare model to be used for each prediction
|
||||||
model = VGG16(weights='imagenet')
|
model = VGG16(weights='imagenet')
|
||||||
|
|
||||||
@@ -54,7 +56,7 @@ print("Running image analysis. This may take some time...\n\n")
|
|||||||
|
|
||||||
# for each file in directory, append its prediction result to main list
|
# for each file in directory, append its prediction result to main list
|
||||||
for file in files:
|
for file in files:
|
||||||
result = predict(model, src_path + file)
|
result = predict(model, config_file.data_path + file)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
all_results.append({ "path": file, "prediction": result })
|
all_results.append({ "path": file, "prediction": result })
|
||||||
|
|
||||||
@@ -72,6 +74,6 @@ print("Analysis complete! Beginning sort process...\n\n")
|
|||||||
############################## SORTING
|
############################## SORTING
|
||||||
############################## SORTING
|
############################## SORTING
|
||||||
|
|
||||||
format_result(src_path, json_path)
|
format_result(appconfig, json_path)
|
||||||
|
|
||||||
print("File sort successful! Process complete.")
|
print("File sort successful! Process complete.")
|
||||||
|
|||||||
Reference in New Issue
Block a user