From ba3c9369e19680d936e4bcf8f725bc9747cc6673 Mon Sep 17 00:00:00 2001
From: Davide Depau <davide@depau.eu>
Date: Thu, 22 Feb 2024 01:04:15 +0100
Subject: [PATCH] Recycle previous corners on timeout

---
 bot.py | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/bot.py b/bot.py
index 91e9cc7..cb2d7fe 100644
--- a/bot.py
+++ b/bot.py
@@ -12,7 +12,6 @@ import cv2
 import numpy as np
 import telegram
 from aiohttp import BasicAuth
-from cv2 import aruco
 from pytapo import Tapo
 from telegram import Update, Message
 from telegram.ext import Updater
@@ -39,6 +38,8 @@ class Bot:
         self.tapo = Tapo(self.camera_ip, self.camera_user, self.camera_password)
         self.executor = ThreadPoolExecutor(max_workers=len(os.sched_getaffinity(0)))
 
+        self.last_aruco_corners = {}
+
     def _get_presets(self):
         presets = self.tapo.getPresets()
         return {v: k for k, v in presets.items()}
@@ -93,13 +94,21 @@ class Bot:
         # Iterate until we find all 4 aruco markers or timeout
         aruco_corners = {}
         annotated_image = None
-        aruco_dict = aruco.getPredefinedDictionary(aruco.DICT_6X6_250)
-        aruco_params = aruco.DetectorParameters()
+        aruco_dict = a.getPredefinedDictionary(a.DICT_6X6_250)
+        aruco_params = a.DetectorParameters()
 
         t0 = time.time()
         print("Taking image with ArUco markers...")
         while len(aruco_corners) < 4:
             if time.time() - t0 > timeout:
+                a = self.last_aruco_corners.copy()
+                a.update(aruco_corners)
+                aruco_corners = a
+
+                if len(aruco_corners) == 4:
+                    print("Timeout waiting for ArUco markers, using cached corners")
+                    break
+
                 print(
                     "Timeout waiting for ArUco markers, returning only original image"
                 )
@@ -112,7 +121,7 @@ class Bot:
                 continue
 
             # Detect the markers
-            corners, ids, rejected = aruco.detectMarkers(
+            corners, ids, rejected = a.detectMarkers(
                 annotated_image, aruco_dict, parameters=aruco_params
             )
             for corner, i in zip(corners, ids):
@@ -129,7 +138,7 @@ class Bot:
 
         corners = [aruco_corners[i] for i in range(1, 5)]
         ids = np.array([[i] for i in range(1, 5)])
-        aruco.drawDetectedMarkers(annotated_image, corners, ids)
+        a.drawDetectedMarkers(annotated_image, corners, ids)
 
         # Annotate the image with the detected markers and apply the perspective transform to the pretty image
 
@@ -173,6 +182,8 @@ class Bot:
         matrix = cv2.getPerspectiveTransform(expanded_rectangle_points, dst_pts)
         warped = cv2.warpPerspective(pretty_image, matrix, (width, height))
 
+        self.last_aruco_corners = aruco_corners
+
         return [warped, annotated_image]
 
     async def _photo_command(self, chat_id: int, adjust_perspective: bool = True):