Skip to content

Instantly share code, notes, and snippets.

@SilverBut
Last active November 14, 2021 14:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SilverBut/8205ccc44cc6e7d2cd91d918fecc6b82 to your computer and use it in GitHub Desktop.
Save SilverBut/8205ccc44cc6e7d2cd91d918fecc6b82 to your computer and use it in GitHub Desktop.
could be helpful if you want to get 61w.
#!/usr/bin/env python
# coding: utf-8
# Original camera video resolution
RES_FROM=(2560,1920)
# If set to 4, then sampled down to 1/4 resolution to speed up
RESIZE = 4
# POI is under target resolution.
# First point is top left cornor of ROI, and second one is bottom right cornor
# (0,0) is at top left cornor of the whole graph.
POI = [(724, 832), (1116, 1180)]
POI = [ (1320, 248), (1604, 680)]
# Apply a blur could be better for detection, and reduce false alarms
BLUR = 3
# Sensitive value of the image change. Larger means LESS sensitive.
SENSITIVE = 25
# If area(changed)/area(poi_resized) > FINAL_DETECT, get a compare
FINAL_DETECT = 0.30
# Skip some seconds if a match is found, to prevent continously alert
# This is somehow a stupid hack. A better way is having a sliding window but I'm busy.
SKIP_SEC = 2
# import libraries. could work better if use tuna source.
# > conda install imutils opencv
from imutils.video import VideoStream
import argparse
import datetime
import imutils
import time
import cv2
import numpy as np
from IPython.display import clear_output, Image, display, HTML
import base64
from pathlib import Path
imageCount = 0
def arrayShow(*imageArray):
global imageCount
imageCount += 1
for i in range(len(imageArray)):
ret, png = cv2.imencode('.png', imageArray[i])
if not ret:
continue
cv2.imwrite(f"results/{imageCount}_{i}.png", imageArray[i])
print(f"wrote {imageCount} ({len(imageArray)}) images")
def img_preprocess(frame):
gray = imutils.resize(frame, width=int(frame.shape[1]/4), height=int(frame.shape[0]/4))
gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
blur_factor = 2 * BLUR + 1 # must be odd
gray = cv2.GaussianBlur(gray, (blur_factor, blur_factor), 0)
return gray
def mark_poi(frame):
cv2.rectangle(frame, POI[0], POI[1], (255, 255, 255), 2)
return frame
def cut_to_poi(frame):
return frame[POI[0][1]:POI[1][1], POI[0][0]:POI[1][0]]
def calc_diff(src, dst):
frameDelta = cv2.absdiff(src, dst)
thresh = cv2.threshold(frameDelta, SENSITIVE, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
return (1.0 * np.count_nonzero(thresh)) / (1.0 * thresh.shape[0] * thresh.shape[1])
def judger(vs):
fps = vs.get(cv2.CAP_PROP_FPS)
src = None
frame1 = None
while True:
ret, frame2 = vs.read()
if not ret:
raise ValueError("False ret")
if frame2 is None:
raise ValueError("empty frame")
if frame1 is None:
frame1 = frame2
src = img_preprocess(cut_to_poi(frame1))
continue
dst = img_preprocess(cut_to_poi(frame2))
diff = calc_diff(src, dst)
if (diff > FINAL_DETECT):
arrayShow(src, frame1, dst, frame2)
frame1 = None
# When detected, go forward for 2 seconds to prevent continously trigger
# weird. frame by frame is faster than skipping.
vs.set(cv2.CAP_PROP_POS_FRAMES, int(vs.get(cv2.CAP_PROP_POS_FRAMES) + SKIP_SEC * fps))
print("-----------------")
pathlist = Path("../videos").glob('**/*.mp4')
for path in pathlist:
p = str(path)
if not "/datadir4/" in p and not "/datadir5/" in p:
continue
if "/datadir4/" in p and "/hiv000" in p:
continue
print(f"processing {p}")
try:
vs = cv2.VideoCapture(p)
judger(vs)
finally:
vs.release()
continue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment