Skip to content

Commit

Permalink
Fix webcam motion detection with live streams. #961
Browse files Browse the repository at this point in the history
  • Loading branch information
theyosh committed Nov 12, 2024
1 parent 76bbd54 commit c3d921e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 22 deletions.
9 changes: 9 additions & 0 deletions hardware/webcam/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,15 @@ def motion_capture(self, motion_frame="last", motion_threshold=25, motion_area=5
# https://www.pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/
# try:
current_image = cv2.imread(str(self.raw_image_path))

if self.live:
# Make a black bar over the title and timestamp bar so it will not trigger a motion
x = int(self.width / 4)
y = 20
w = int(self.width / 2)
h = 46
current_image = cv2.rectangle(current_image, (x, y), (x + w, y + h), (0, 0, 0), -1 )

current_image = cv2.cvtColor(current_image, cv2.COLOR_BGR2GRAY)
current_image = cv2.GaussianBlur(current_image, (21, 21), 0)

Expand Down
47 changes: 25 additions & 22 deletions terrariumEngine.py
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ def __load_existing_webcams(self):
webcamLogger.info(f"Loaded {self.webcams[webcam.id]} in {time.time()-start:.2f} seconds.")

def _update_webcams(self):
def __process_webcam(self, webcam, current_state, relays):
def __process_webcam(self, webcam, light_state, door_state, relays):
start = time.time()
if self.webcams[webcam.id].update(relays) == False:
return
Expand All @@ -1170,28 +1170,20 @@ def __process_webcam(self, webcam, current_state, relays):
# Check archiving/motion settings
if webcam.archive["state"] not in ["disabled", ""]:
# Check light status
if webcam.archive["light"] not in ["ignore", ""] and current_state != webcam.archive["light"]:
if webcam.archive["light"] not in ["ignore", ""] and light_state is not None and light_state != webcam.archive["light"]:
webcamLogger.debug(
f'Webcam {webcam} will not archive based on light state: {current_state} vs {webcam.archive["light"]}'
f'Webcam {webcam} will not archive based on light state: {light_state} vs {webcam.archive["light"]}'
)
webcamLogger.info(f"Updated webcam {webcam} in {time.time()-start:.2f} seconds.")
return

# Check door status
if webcam.archive["door"] not in ["ignore", ""]:
# Default state is that the doors are closed....
current_state = (
"close"
if webcam.enclosure is None or self.enclosures[webcam.enclosure.id].door_closed
else "open"
if webcam.archive["door"] not in ["ignore", ""] and door_state is not None and webcam.archive["door"] != door_state:
webcamLogger.debug(
f'Webcam {webcam} will not archive based on door state: {door_state} vs {webcam.archive["door"]}'
)

if webcam.archive["door"] != current_state:
webcamLogger.debug(
f'Webcam {webcam} will not archive based on door state: {current_state} vs {webcam.archive["door"]}'
)
webcamLogger.info(f"Updated webcam {webcam} in {time.time()-start:.2f} seconds.")
return
webcamLogger.info(f"Updated webcam {webcam} in {time.time()-start:.2f} seconds.")
return

if "motion" == webcam.archive["state"]:
newImage = self.webcams[webcam.id].motion_capture(
Expand Down Expand Up @@ -1226,19 +1218,30 @@ def __process_webcam(self, webcam, current_state, relays):
],
key=lambda item: item.address,
):
# Get the current light state first, as processing new image could take 10 sec. In that period the lights could have been turned on,
# where the picture is taken when the lights are off.
current_state = (
"on" if webcam.enclosure is None or self.enclosures[webcam.enclosure.id].lights_on else "off"
)
light_state = door_state = None

if webcam.enclosure is not None:
# Get the current light state first, as processing new image could take 10 sec. In that period the lights could have been turned on,
# where the picture is taken when the lights are off.
light_state = (
"on" if webcam.enclosure is None or self.enclosures[webcam.enclosure.id].lights_on else "off"
)

# Default state is that the doors are closed....
door_state = (
"close"
if webcam.enclosure is None or self.enclosures[webcam.enclosure.id].door_closed
else "open"
)

# Set the flash relays if selected
relays = (
[]
if webcam.flash is None
else [self.relays[relay.id] for relay in webcam.flash if not relay.manual_mode]
)
# Start update in parallel
pool.submit(__process_webcam, self, webcam, current_state, relays)
pool.submit(__process_webcam, self, webcam, light_state, door_state, relays)

def __load_existing_enclosures(self):
self.enclosures = {}
Expand Down

0 comments on commit c3d921e

Please sign in to comment.