2016年3月20日 星期日

OpenCV3: 檢測移動物件


今日嘗試了用 OpenCV3 檢測移動物件,同時把影像、變化、二值化、灰階層錄影到影片檔。程序比以較長但不算複雜。
##------------------------------------------------------------------------------
##  Motion detection with OpenCV 3.1
##------------------------------------------------------------------------------
##  Language: Python 3.5
##  Platform: Mac OS X
##  Written by Pacess HO
##  Copyright 2016 Pacess Studio.  All rights reserved
##------------------------------------------------------------------------------
 
##  Import packages
import imutils
import numpy
import time
import cv2

##  Reading from webcam
camera = cv2.VideoCapture(0)
time.sleep(0.25)

##  Initialize the first frame in the video stream
firstFrame = None

fourcc = cv2.VideoWriter_fourcc(*"MJPG")
writer = None
zeros = None
width = 512
height = 288

##------------------------------------------------------------------------------
##  Forever loop until user quit the application
while True:

   ##  Grab the current frame and initialize the occupied/unoccupied text
   (grabbed, frame) = camera.read()

   ##  If the frame could not be grabbed, then we have reached the end of the video
   if not grabbed:
      break

   ##  Resize the frame, convert it to grayscale, and blur it
   frame = imutils.resize(frame, width)
   gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
   gray = cv2.GaussianBlur(gray, (21, 21), 0)

   ##  If the first frame is None, initialize it
   if firstFrame is None:
      firstFrame = gray
      continue

   ##------------------------------------------------------------------------------
   ##  Compute the absolute difference between the current frame and first frame
   frameDelta = cv2.absdiff(firstFrame, gray)
   thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]

   ##  Dilate the thresholded image to fill in holes, then find contours on thresholded image
   thresh = cv2.dilate(thresh, None, iterations=2)
   (_, contourArray, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

   ##------------------------------------------------------------------------------
   ##  Loop over the contours
   for contour in contourArray:

      ##  If the contour is too small, ignore it
      if cv2.contourArea(contour) < 500:
         continue

      ##  Compute the bounding box for the contour, draw it on the frame, and update the text
      (x, y, w, h) = cv2.boundingRect(contour)
      cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)

   ##------------------------------------------------------------------------------
   ##  Show the frame and record if the user presses a key
   cv2.imshow("Security Feed", frame)
   cv2.imshow("Thresh", thresh)
   cv2.imshow("Frame Delta", frameDelta)

   ##------------------------------------------------------------------------------
   ##  Write images to video file
   if writer is None:

      ##  Initialzie the video writer and construct the zeros array
      writer = cv2.VideoWriter("output.avi", fourcc, 20, (width*2, height*2), True)
      zeros = numpy.zeros((height, width), dtype="uint8")

   ##  Convert single channel to RGB channel
   FRAMEDELTA = cv2.merge([frameDelta, frameDelta, frameDelta])
   THRESH = cv2.merge([thresh, thresh, thresh])
   GRAY = cv2.merge([gray, gray, gray])

   ##  Construct the final output frame
   output = numpy.zeros((height*2, width*2, 3), dtype="uint8")
   output[0:height, 0:width] = GRAY
   output[0:height, width:width*2] = FRAMEDELTA
   output[height:height*2, 0:width] = THRESH
   output[height:height*2, width:width*2] = frame
 
   ##  Write the output frame to file
   writer.write(output)

   ##------------------------------------------------------------------------------
   ##  If the `q` key is pressed then exit
   key = cv2.waitKey(1) & 0xFF
   if key == ord("q"):
      break

##------------------------------------------------------------------------------
##  Cleanup the camera and close any open windows
writer.release()
camera.release()
cv2.destroyAllWindows()

沒有留言: