5
\$\begingroup\$

I've been tinkering with Python and OpenCV for a while now, and thought I'd start an actual project. This is my first time making something that I'd actually consider using, and my first time posting to Code Review SE. I'm curious to know your thoughts and opinions on the cleanliness of my code, the efficiency of the program, and the project in general!

The basic function of the program is to find and track objects. I am thinking of hooking this up to a webcam and stepper motor and testing this as a tracking security camera. The program first creates a background image, and then loops until it finds a difference between what it sees currently, and the background image. The difference of these images is taken, then made into its own frame (frame_delta). If this delta is large enough, it is treated as a contour. If there are multiple contours, the largest one is chosen. Once a contour is found, an MIL tracker is created, and set to the size of the contour. This process is repeated every 30 frames to prevent the object from being lost due to tracker inaccuracy. Here's the code!:

# OpenCV for tracking/display
import cv2
import time
# When program is started
if __name__ == '__main__':
 # Are we finding motion or tracking
 status = 'motion'
 # How long have we been tracking
 idle_time = 0
 # Background for motion detection
 back = None
 # An MIL tracker for when we find motion
 tracker = cv2.TrackerMIL_create()
 # Webcam footage (or video)
 video = cv2.VideoCapture(0)
 # LOOP
 while True:
 # Check first frame
 ok, frame = video.read()
 # Grayscale footage
 gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
 # Blur footage to prevent artifacts
 gray = cv2.GaussianBlur(gray,(21,21),0)
 # Check for background
 if back is None:
 # Set background to current frame
 back = gray
 if status == 'motion':
 # Difference between current frame and background
 frame_delta = cv2.absdiff(back,gray)
 # Create a threshold to exclude minute movements
 thresh = cv2.threshold(frame_delta,25,255,cv2.THRESH_BINARY)[1]
 #Dialate threshold to further reduce error
 thresh = cv2.dilate(thresh,None,iterations=2)
 # Check for contours in our threshold
 _,cnts,hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
 # Check each contour
 if len(cnts) != 0:
 # If the contour is big enough
 # Set largest contour to first contour
 largest = 0
 # For each contour
 for i in range(len(cnts)):
 # If this contour is larger than the largest
 if i != 0 & int(cv2.contourArea(cnts[i])) > int(cv2.contourArea(cnts[largest])):
 # This contour is the largest
 largest = i
 if cv2.contourArea(cnts[largest]) > 1000:
 # Create a bounding box for our contour
 (x,y,w,h) = cv2.boundingRect(cnts[0])
 # Convert from float to int, and scale up our boudning box
 (x,y,w,h) = (int(x),int(y),int(w),int(h))
 # Initialize tracker
 bbox = (x,y,w,h)
 ok = tracker.init(frame, bbox)
 # Switch from finding motion to tracking
 status = 'tracking'
 # If we are tracking
 if status == 'tracking':
 # Update our tracker
 ok, bbox = tracker.update(frame)
 # Create a visible rectangle for our viewing pleasure
 if ok:
 p1 = (int(bbox[0]), int(bbox[1]))
 p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
 cv2.rectangle(frame,p1,p2,(0,0,255),10)
 # Show our webcam
 cv2.imshow("Camera",frame)
 # If we have been tracking for more than a few seconds
 if idle_time >= 30:
 # Reset to motion
 status = 'motion'
 # Reset timer
 idle_time = 0
 # Reset background, frame, and tracker
 back = None
 tracker = None
 ok = None
 # Recreate tracker
 tracker = cv2.TrackerMIL_create()
 # Incriment timer
 idle_time += 1
 # Check if we've quit
 if cv2.waitKey(1) & 0xFF == ord("q") or cv2.getWindowProperty('Camera',0) == -1:
 break
#QUIT
video.release()
cv2.destroyAllWindows()
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Oct 17, 2017 at 14:42
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

seems cool to me, but i'm not a great expert.

one thing i would improve is the # for each contour using built-in python max() function as in:

largest = max(map(lambda x: int(cv2.contourArea(x)), cnts))
answered Oct 17, 2017 at 17:00
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.