From e1084cb38f9752774aa4194e3d255a2d18e94297 Mon Sep 17 00:00:00 2001 From: Anuj Date: Tue, 14 Sep 2021 22:45:45 -0700 Subject: [PATCH] Changing the way the corpus is created to a single user. As a result we've added a new reader, and modified some of the processing code. Seems like a major change in processing behavior. --- data/readers/SingleCorpusReader.py | 27 +++++++++++++ data/readers/default.py | 2 +- photocollage/dialogs/ConfigSelectorDialog.py | 2 +- photocollage/gtkgui.py | 19 +++++---- photocollage/render.py | 3 +- yearbook/Corpus.py | 41 ++------------------ 6 files changed, 43 insertions(+), 51 deletions(-) create mode 100644 data/readers/SingleCorpusReader.py diff --git a/data/readers/SingleCorpusReader.py b/data/readers/SingleCorpusReader.py new file mode 100644 index 0000000..390c481 --- /dev/null +++ b/data/readers/SingleCorpusReader.py @@ -0,0 +1,27 @@ +from yearbook.Corpus import Corpus +from yearbook.Photograph import Photograph + + +def single_corpus_processor(corpus_file) -> {}: + face_to_image_map = {} + event_to_image_map = {} # For a given event, we can track the images + + all_images_map = {} + + # read the corpus file + with open(corpus_file, 'r') as reader: + for line in reader.readlines(): + values = line.split("\t") + event_name = values[0] + img_name = values[1].strip() + + photograph = Photograph(img_name, [], event_name) + + if event_name in event_to_image_map: + event_to_image_map[event_name].append(img_name) + else: + event_to_image_map[event_name] = [img_name] + + all_images_map[photograph.name] = photograph + + return Corpus(image_map=all_images_map, events_to_images=event_to_image_map) diff --git a/data/readers/default.py b/data/readers/default.py index 7d04094..5315c9e 100644 --- a/data/readers/default.py +++ b/data/readers/default.py @@ -46,4 +46,4 @@ def corpus_processor(corpus_file) -> {}: sorted_images = sorted(imgs, key=lambda x: x[1], reverse=True) face_to_image_map[face] = sorted_images - return Corpus(image_map=all_images_map, child_to_images=face_to_image_map, events_to_images=event_to_image_map) + return Corpus(image_map=all_images_map, events_to_images=event_to_image_map) diff --git a/photocollage/dialogs/ConfigSelectorDialog.py b/photocollage/dialogs/ConfigSelectorDialog.py index c4eacdb..8dd01f7 100644 --- a/photocollage/dialogs/ConfigSelectorDialog.py +++ b/photocollage/dialogs/ConfigSelectorDialog.py @@ -41,7 +41,7 @@ def __init__(self, parent): self.btn_select_corpus = Gtk.Button(label=_("Select Processed Corpus...")) self.corpus_entry = Gtk.Entry() - self.corpus_entry.set_text("/Users/ashah/GoogleDrive/Rilee4thGrade/processedCorpus_rilee_recognizer.out") + self.corpus_entry.set_text("/Users/ashah/GoogleDrive/Rilee4thGrade/corpus_faces.out") self.config_parameters[PROCESSED_CORPUS_FILE] = self.corpus_entry.get_text() self.btn_select_corpus_dir = Gtk.Button(label=_("Select Corpus Dir...")) diff --git a/photocollage/gtkgui.py b/photocollage/gtkgui.py index 14e5e16..03264de 100644 --- a/photocollage/gtkgui.py +++ b/photocollage/gtkgui.py @@ -31,6 +31,7 @@ from photocollage.dialogs.SettingsDialog import SettingsDialog from data.readers.default import corpus_processor +from data.readers.SingleCorpusReader import single_corpus_processor from yearbook.Yearbook import create_yearbook_metadata gi.require_version('Gtk', '3.0') @@ -318,14 +319,14 @@ def setup_yearbook_config(self, button): response = dialog.run() if response == Gtk.ResponseType.OK: self.yearbook_parameters = dialog.config_parameters - self.corpus = corpus_processor(self.yearbook_parameters["processed_corpus_file"]) + self.corpus = single_corpus_processor(self.yearbook_parameters["processed_corpus_file"]) # Read the config file self.yearbook = create_yearbook_metadata(self.yearbook_parameters["config_file"], "", "") # Reset page to first self.current_page_index = 0 current_page = self.yearbook.pages[self.current_page_index] - page_images = self.choose_page_images_for_child(current_page, self.child) + page_images = self.choose_page_images(current_page) self.update_photolist(current_page, page_images) dialog.destroy() @@ -334,15 +335,14 @@ def setup_yearbook_config(self, button): else: dialog.destroy() - def choose_page_images_for_child(self, page, child, max_count=12): - corpus_dir = self.yearbook_parameters["corpus_dir"] + def choose_page_images(self, page, max_count=12): if not page.personalized: print("Load image as is, %s, %s" % (page.event_name, page.image)) images = [page.image] else: print("Working on: (%s, %s, %s)" % (page.image, page.event_name, page.number)) - images = self.corpus.get_filenames_child_images_for_event(child, page.event_name, corpus_dir) + images = self.corpus.get_child_images_for_event(page.event_name) return images[:max_count] @@ -376,7 +376,7 @@ def render_preview(self, yearbook_page): try: page_collage = yearbook_page.history[yearbook_page.history_index] except IndexError: - page_images = self.choose_page_images_for_child(yearbook_page, self.child) + page_images = self.choose_page_images(yearbook_page) self.update_photolist(yearbook_page, page_images) # If the desired ratio changed in the meantime (e.g. from landscape to @@ -453,6 +453,7 @@ def publish_book(self, button): # Display a "please wait" dialog and do the job. compdialog = ComputingDialog(self) count_completed = 0 + def on_update(img, fraction_complete): compdialog.update(fraction_complete) @@ -464,13 +465,11 @@ def on_complete(img, out_file_name): print("Time to destroy this dialog, and save the final file") all_final_images = [page.final_img for page in self.yearbook.pages] all_final_images[0].save(os.path.join(output_dir, self.child + "_version0.pdf"), save_all=True, - append_images=all_final_images[1:]) + append_images=all_final_images[1:]) compdialog.destroy() return - - for yearbook_page in self.yearbook.pages: out_file = os.path.join(self.yearbook_parameters['output_dir'], str(yearbook_page.number) + ".jpg") page_collage = yearbook_page.history[yearbook_page.history_index] @@ -509,7 +508,7 @@ def select_next_page(self, button): current_page = self.yearbook.pages[self.current_page_index] if not current_page.history: max_count = self.yearbook_parameters['max_count'] - new_page_images = self.choose_page_images_for_child(current_page, self.child, 100) + new_page_images = self.choose_page_images(current_page, 100) remaining_images = [x for x in new_page_images if x not in used_images][:max_count] self.update_photolist(current_page, remaining_images) diff --git a/photocollage/render.py b/photocollage/render.py index 8556227..eb6d85b 100644 --- a/photocollage/render.py +++ b/photocollage/render.py @@ -99,8 +99,9 @@ def build_photolist(filelist): for name in filelist: try: img = PIL.Image.open(name) - except OSError: + except OSError as err: # raise BadPhoto(name) + print("OS error: {0}".format(err)) print("Skipping a photo: %s" % name) continue diff --git a/yearbook/Corpus.py b/yearbook/Corpus.py index e781610..bbc59b0 100644 --- a/yearbook/Corpus.py +++ b/yearbook/Corpus.py @@ -1,9 +1,8 @@ class Corpus: - def __init__(self, image_map: {}, events_to_images: {}, child_to_images: {}): + def __init__(self, image_map: {}, events_to_images: {}): self.image_map = image_map self.events_to_images = events_to_images - self.child_to_images = child_to_images def get_children(self): return self.child_to_images.keys() @@ -14,39 +13,5 @@ def get_events(self): def is_image_from_event(self, image, event): return image in self.events_to_images[event] - def get_child_images_for_event(self, child, event): - - child_images_per_event = [] - childs_image_names = [image_tuple[0] for image_tuple in self.child_to_images[child]] - - for image in self.events_to_images[event]: - if image in childs_image_names: - child_images_per_event.append(image) - - return child_images_per_event - - def get_filenames_child_images_for_event(self, child, event, corpus_dir): - import os - child_images_per_event = self.get_child_images_for_event_with_scores(child, event) - - # TODO: Figure out what should the fallback be in cases where there are no images of this child - # in this event. For now we're returning everything from that event - if len(child_images_per_event) < 2: - child_images_per_event = self.events_to_images[event] - return [os.path.join(corpus_dir, event, a_tuple) for a_tuple in child_images_per_event] - - return [os.path.join(corpus_dir, event, a_tuple[0]) for a_tuple in child_images_per_event] - - def get_child_images_for_event_with_scores(self, child, event): - - child_images_per_event = [] - - for image in self.child_to_images[child]: - if image[0] in self.events_to_images[event]: - child_images_per_event.append(image) - - return child_images_per_event - - def get_images_with_face_count(self, face_count: int): - - return {k:v for k,v in self.image_map.items() if len(v.faces) == face_count} + def get_child_images_for_event(self, event): + return self.events_to_images[event]