1
0
Эх сурвалжийг харах

basic frame differencing notebook

Felix Kleinsteuber 3 жил өмнө
parent
commit
2faf3966fd

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 113 - 0
approach1a_basic_frame_differencing.ipynb


BIN
exp1a_annotations.npy


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 5 - 5
frame_differencing.ipynb


+ 52 - 0
py/ImageAnnotator.py

@@ -0,0 +1,52 @@
+import ipywidgets as widgets
+from IPython.display import display
+from py.Session import Session
+from py.ImageClassifier import AbstractImageClassifier
+import numpy as np
+
+class ImageAnnotator():
+    def __init__(self, classifier: AbstractImageClassifier, session: Session, initial_scores = [], initial_annotations = [], load_from = None):
+        self.scores = initial_scores
+        self.annotations = initial_annotations
+        self.score = -1
+        self.classifier = classifier
+        self.session = session
+
+        if load_from is not None:
+            data = np.load(load_from, allow_pickle=True)
+            self.annotations = data[0]
+            self.scores = data[1]
+
+        normal_btn = widgets.Button(description = "Normal")
+        anomalous_btn = widgets.Button(description = "Anomalous")
+        self.button_box = widgets.HBox([normal_btn, anomalous_btn])
+        self.output = widgets.Output(layout={"height": "400px"})
+        display(self.button_box, self.output)
+        normal_btn.on_click(self.mark_as_normal)
+        anomalous_btn.on_click(self.mark_as_anomalous)
+        self.next_image()
+    
+    def mark_as_normal(self, _):
+        with self.output:
+            print("Marking as normal...")
+        self.annotations.append(True)
+        self.scores.append(self.score)
+        self.next_image()
+    
+    def mark_as_anomalous(self, _):
+        with self.output:
+            print("Marking as anomalous...")
+        self.annotations.append(False)
+        self.scores.append(self.score)
+        self.next_image()
+    
+    def next_image(self):
+        img = self.session.get_random_motion_image(day_only=True)
+        self.score = self.classifier.evaluate(img)
+        self.output.clear_output()
+        with self.output:
+            display(img.to_ipython_image())
+            print(f"score = {self.score}")
+
+    def save(self, filename: str):
+        np.save(filename, [self.annotations, self.scores])

+ 8 - 6
py/ImageUtils.py

@@ -15,19 +15,21 @@ def get_image_date(img_path: str) -> datetime:
     date_raw = img.getexif()[306]
     return datetime.strptime(date_raw, "%Y:%m:%d %H:%M:%S")
 
-def display_images(images: list, titles: list, colorbar=False, size=8, **imshowargs):
+def display_images(images: list, titles: list, colorbar=False, size=(8, 5), row_size=2, **imshowargs):
     """Displays the given images next to each other.
 
     Args:
         images (list of np.ndarray): list of image arrays
         titles (list of str): list of titles
         colorbar (bool, optional): Display colorbars. Defaults to False.
-        size (int, optional): plt size per image. Defaults to 8.
+        size (tuple of ints, optional): plt size (width, height) per image. Defaults to (8, 5).
     """
-    numImgs = len(images)
-    plt.figure(figsize=(numImgs * size, size))
-    for i, image, title in zip(range(numImgs), images, titles):
-        plt.subplot(1, numImgs, i + 1)
+    num_imgs = len(images)
+    num_cols = row_size
+    num_rows = (num_imgs - 1) // num_cols + 1
+    plt.figure(figsize=(num_cols * size[0], num_rows * size[1]))
+    for i, image, title in zip(range(num_imgs), images, titles):
+        plt.subplot(num_rows, num_cols, i + 1)
         plt.imshow(image, **imshowargs)
         plt.title(title)
         if colorbar:

+ 28 - 4
py/Session.py

@@ -165,18 +165,42 @@ class Session:
         return img
     
     def get_closest_lapse_images(self, motion_file: str):
+        """Returns the lapse images taken closest before and after this image, respectively.
+        If no such image is found, the corresponding returned image will be None.
+
+        Args:
+            motion_file (str): Filename of the motion image
+
+        Returns:
+            (MotionImage or None, MotionImage or None): Closest lapse images. Each image can be None if not found.
+        """
         date: datetime = self.motion_dates[motion_file]
         previous_date = date.replace(minute=0, second=0)
         next_date = previous_date + timedelta(hours=1)
+        i = 0
         while not previous_date in self.lapse_map:
             previous_date -= timedelta(hours=1)
-        while not next_date in self.lapse_map:
+            i += 1
+            if i > 24:
+                # no previous lapse image exists
+                previous_date = None
+                break
+        i = 0
+        while not next_date in self.lapse_map and i < 24:
             next_date += timedelta(hours=1)
-        if len(self.lapse_map[previous_date]) > 1:
+            i += 1
+            if i > 24:
+                # no next lapse image exists
+                next_date = None
+                break
+        if previous_date is not None and len(self.lapse_map[previous_date]) > 1:
             warn(f"There are multiple lapse images for date {previous_date}! Choosing the first one.")
-        if len(self.lapse_map[next_date]) > 1:
+        if next_date is not None and len(self.lapse_map[next_date]) > 1:
             warn(f"There are multiple lapse images for date {next_date}! Choosing the first one.")
-        return LapseImage(self, self.lapse_map[previous_date][0], previous_date), LapseImage(self, self.lapse_map[next_date][0], next_date)
+        
+        previous_img = None if previous_date is None else LapseImage(self, self.lapse_map[previous_date][0], previous_date)
+        next_img = None if next_date is None else LapseImage(self, self.lapse_map[next_date][0], next_date)
+        return previous_img, next_img
 
 class SessionImage:
     def __init__(self, session: Session, subfolder: str, filename: str, date: datetime):

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно