From 3c5b7cbf7b42ae3b16b0266bfda774219ef5705b Mon Sep 17 00:00:00 2001 From: Folorunsho Samuel <77319818+sof-danny@users.noreply.github.com> Date: Sat, 24 Feb 2024 11:39:35 -0600 Subject: [PATCH 1/5] Add files via upload --- Spannotation/cli.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Spannotation/cli.py b/Spannotation/cli.py index 65522ff..fd0a9f9 100644 --- a/Spannotation/cli.py +++ b/Spannotation/cli.py @@ -23,3 +23,7 @@ def main(): if __name__ == "__main__": main() + + + + From 91b21420bb24fcbc2f44e53536e8651140f16434 Mon Sep 17 00:00:00 2001 From: Folorunsho Samuel <77319818+sof-danny@users.noreply.github.com> Date: Sat, 24 Feb 2024 11:43:24 -0600 Subject: [PATCH 2/5] Add files via upload --- dist/spannotation-0.1.11.tar.gz | Bin 0 -> 6055 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dist/spannotation-0.1.11.tar.gz diff --git a/dist/spannotation-0.1.11.tar.gz b/dist/spannotation-0.1.11.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e3673921d1733f718b4ef0f629d3b5c447dd160e GIT binary patch literal 6055 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 YylcBG#Gi)X8Vmq&p|dwL=mG@#AJz!v Date: Sat, 24 Feb 2024 11:56:59 -0600 Subject: [PATCH 3/5] Update mask_generator.py --- build/lib/Spannotation/mask_generator.py | 41 +++++++++++++++--------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/build/lib/Spannotation/mask_generator.py b/build/lib/Spannotation/mask_generator.py index e9b80ac..5a40c82 100644 --- a/build/lib/Spannotation/mask_generator.py +++ b/build/lib/Spannotation/mask_generator.py @@ -3,15 +3,18 @@ import os import glob + class MaskGenerator: def __init__(self): self.points = [] self.image = None self.mask_generated = False + self.window_name = 'Image Mask Generator' + def click_event(self, event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: - if len(self.points) < 3: + if len(self.points) < 3: self.points.append((x, y)) cv2.circle(self.image, (x, y), 5, (0, 255, 0), -1) cv2.imshow('image', self.image) @@ -20,35 +23,41 @@ def click_event(self, event, x, y, flags, param): mask = self.generate_mask(self.points) cv2.imshow('mask', mask) self.mask_generated = True + self.save_mask(mask, param['save_path'], param['image_path']) + cv2.waitKey(500) + cv2.destroyAllWindows() + cv2.waitKey(1) - @staticmethod - def generate_mask(image, points): - mask = np.zeros(image.shape[:2], dtype=np.uint8) + def generate_mask(self, points): + mask = np.zeros(self.image.shape[:2], dtype=np.uint8) cv2.fillPoly(mask, [np.array(points)], 255) return mask + def save_mask(self, mask, save_path, image_path): + base_name = os.path.basename(image_path) + save_file = os.path.join(save_path, base_name) + cv2.imwrite(save_file, mask) + print(f"Mask saved to {save_file}") + + def process_image(self, image_path, save_path): self.image = cv2.imread(image_path) - if self.image is None: - raise ValueError("Could not read the image.") self.points = [] self.mask_generated = False cv2.imshow('image', self.image) - cv2.setMouseCallback('image', self.click_event) - cv2.waitKey(0) + cv2.setMouseCallback('image', self.click_event, param={'image_path': image_path, 'save_path': save_path}) + + while not self.mask_generated: + if cv2.waitKey(1) & 0xFF == ord('q'): + break - if self.mask_generated: - mask = self.generate_mask(self.image, self.points) - base_name = os.path.basename(image_path) - cv2.imwrite(os.path.join(save_path, base_name), mask) + cv2.destroyAllWindows() + cv2.waitKey(1) def process_folder(self, folder_path, save_path): if not os.path.exists(save_path): os.makedirs(save_path) for image_file in glob.glob(os.path.join(folder_path, '*')): - try: - self.process_image(image_file, save_path) - except ValueError as e: - print(f"Error processing {image_file}: {e}") + self.process_image(image_file, save_path) From 7a1cd0667ddd5b234676a1bac587c9e277c8e166 Mon Sep 17 00:00:00 2001 From: Folorunsho Samuel <77319818+sof-danny@users.noreply.github.com> Date: Sat, 24 Feb 2024 11:57:27 -0600 Subject: [PATCH 4/5] Update cli.py --- build/lib/Spannotation/cli.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/build/lib/Spannotation/cli.py b/build/lib/Spannotation/cli.py index a83a92a..65522ff 100644 --- a/build/lib/Spannotation/cli.py +++ b/build/lib/Spannotation/cli.py @@ -1,11 +1,25 @@ from Spannotation.mask_generator import MaskGenerator -def main(): +def process_single_image(generator): + image_path = input("Enter the path to your image: ") + save_path = input("Enter the path to save the mask: ") + generator.process_image(image_path, save_path) + +def process_image_folder(generator): folder_path = input("Enter the path to your images folder: ") save_path = input("Enter the path to save masks: ") + generator.process_folder(folder_path, save_path) +def main(): generator = MaskGenerator() - generator.process_folder(folder_path, save_path) + choice = input("Do you want to process a single image (1) or a folder (2)? [1/2]: ") + + if choice == '1': + process_single_image(generator) + elif choice == '2': + process_image_folder(generator) + else: + print("Invalid choice. Please enter 1 or 2.") if __name__ == "__main__": main() From 6137a5d46fc5c81abfda0805c5e17d91e4d52540 Mon Sep 17 00:00:00 2001 From: Folorunsho Samuel <77319818+sof-danny@users.noreply.github.com> Date: Sat, 24 Feb 2024 11:58:02 -0600 Subject: [PATCH 5/5] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a36e60..909d1fb 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ or If you want to install a specific version: -``` pip install spannotation==0.1.9 ``` +``` pip install spannotation==0.1.11 ``` ## Usage on Python code Editor @@ -60,7 +60,7 @@ or If you want to install a specific version: -``` pip install spannotation==0.1.9 ``` +``` pip install spannotation==0.1.11 ```