Browse Source

get closest lapse images

Felix Kleinsteuber 3 years ago
parent
commit
f8ca6ea43b
2 changed files with 190 additions and 1 deletions
  1. 125 0
      frame_differencing.ipynb
  2. 65 1
      py/Session.py

+ 125 - 0
frame_differencing.ipynb

@@ -0,0 +1,125 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The autoreload extension is already loaded. To reload it, use:\n",
+      "  %reload_ext autoreload\n"
+     ]
+    }
+   ],
+   "source": [
+    "%load_ext autoreload\n",
+    "%autoreload 2\n",
+    "\n",
+    "from tqdm.notebook import tqdm\n",
+    "import os\n",
+    "from datetime import datetime\n",
+    "\n",
+    "from py.Dataset import Dataset\n",
+    "from py.DatasetStatistics import DatasetStatistics\n",
+    "from py.Session import Session\n",
+    "from py.FileUtils import list_folders, list_jpegs_recursive"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Found 32 sessions\n",
+      "Session 'Beaver_01' at folder: /home/AMMOD_data/camera_traps/BayerWald/Vielkadaver-Projekt/VIELAAS_Spring_Session01-VIELAAS_Beaver_01\n",
+      "Loaded scans.\n"
+     ]
+    }
+   ],
+   "source": [
+    "DIR = '/home/AMMOD_data/camera_traps/BayerWald/Vielkadaver-Projekt/'\n",
+    "\n",
+    "ds = Dataset(DIR)\n",
+    "session = ds.create_session(\"beaver_01\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "img = session.get_random_motion_image()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "previous_img, next_img = img.get_closest_lapse_images()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Opening /home/AMMOD_data/camera_traps/BayerWald/Vielkadaver-Projekt/VIELAAS_Spring_Session01-VIELAAS_Beaver_01/Lapse/2021_05_21_22h_706.jpg...\n",
+      "Opening /home/AMMOD_data/camera_traps/BayerWald/Vielkadaver-Projekt/VIELAAS_Spring_Session01-VIELAAS_Beaver_01/Motion/Beaver_01_00130.jpg...\n",
+      "Opening /home/AMMOD_data/camera_traps/BayerWald/Vielkadaver-Projekt/VIELAAS_Spring_Session01-VIELAAS_Beaver_01/Lapse/2021_05_21_23h_707.jpg...\n"
+     ]
+    }
+   ],
+   "source": [
+    "previous_img.open()\n",
+    "img.open()\n",
+    "next_img.open()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "interpreter": {
+   "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
+  },
+  "kernelspec": {
+   "display_name": "Python 3.6.9 64-bit",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.6.9"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}

+ 65 - 1
py/Session.py

@@ -1,5 +1,6 @@
-from datetime import datetime
+from datetime import datetime, timedelta
 import pickle
+import random
 import subprocess
 from warnings import warn
 import os
@@ -126,3 +127,66 @@ class Session:
             full_path = os.path.join(self.folder, "Lapse", img_name)
             print(f"#{i+1} {full_path}")
             subprocess.call(("xdg-open", full_path))
+
+    def get_motion_image_from_filename(self, filename: str) -> "MotionImage":
+        if filename in self.motion_dates:
+            return MotionImage(self, filename)
+        else:
+            raise ValueError(f"Unknown motion file name: {filename}")
+    
+    def get_random_motion_image(self) -> "MotionImage":
+        if len(self.motion_dates) == 0:
+            raise ValueError("No motion images in session!")
+        return MotionImage(self, random.choice(list(self.motion_dates.keys())))
+    
+    def get_closest_lapse_images(self, motion_file: str):
+        date: datetime = self.motion_dates[motion_file]
+        previous_date = date.replace(minute=0, second=0)
+        next_date = previous_date + timedelta(hours=1)
+        while not previous_date in self.lapse_map:
+            previous_date -= timedelta(hours=1)
+        while not next_date in self.lapse_map:
+            next_date += timedelta(hours=1)
+        if 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:
+            warn(f"There are multiple lapse images for date {next_date}! Choosing the first one.")
+        return LapseImage(self, self.lapse_map[previous_date][0]), LapseImage(self, self.lapse_map[next_date][0])
+
+class MotionImage:
+    def __init__(self, session: Session, filename: str):
+        self.session = session
+        self.filename = filename
+        if not self.filename in session.motion_dates:
+            raise ValueError(f"File name {filename} not in session!")
+        if not os.path.isfile(self.get_full_path()):
+            raise ValueError(f"File Motion/{filename} in session folder {session.folder} not found!")
+    
+    def get_full_path(self) -> str:
+        return os.path.join(self.session.folder, "Motion", self.filename)
+    
+    def open(self):
+        full_path = self.get_full_path()
+        print(f"Opening {full_path}...")
+        subprocess.call(("xdg-open", full_path))
+
+    def get_closest_lapse_images(self):
+        return self.session.get_closest_lapse_images(self.filename)
+        
+class LapseImage:
+    def __init__(self, session: Session, filename: str):
+        self.session = session
+        self.filename = filename
+        if not self.filename in session.lapse_dates:
+            raise ValueError(f"File name {filename} not in session!")
+        if not os.path.isfile(self.get_full_path()):
+            raise ValueError(f"File Lapse/{filename} in session folder {session.folder} not found!")
+    
+    def get_full_path(self) -> str:
+        return os.path.join(self.session.folder, "Lapse", self.filename)
+    
+    def open(self):
+        full_path = self.get_full_path()
+        print(f"Opening {full_path}...")
+        subprocess.call(("xdg-open", full_path))
+