I followed a tutorial on opencv motion detection. I found the code in several sites, it's more or less the same: in a while loop, after having caught the first frame as base frame, find the difference comparing it to the next others.
I want to renew the first frame every 15 mins (thinking about light conditions during the day) but I cant understand why after taking the "new" first frame the process doesn't work anymore.
# import the necessary packages
from imutils.video import VideoStream
import argparse
import datetime
import imutils
import time
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", help="path to the video file")
ap.add_argument("-a", "--min-area", type=int, default=500, help="minimum area size")
args = vars(ap.parse_args())
# if the video argument is None, then we are reading from webcam
if args.get("video", None) is None:
vs = VideoStream(src=0).start()
time.sleep(2.0)
# otherwise, we are reading from a video file
else:
vs = cv2.VideoCapture(args["video"])
# initialize the first frame in the video stream
firstFrame = None
interval = datetime.datetime.now()
# loop over the frames of the video
while True:
# grab the current frame and initialize the occupied/unoccupied
# text
frame = vs.read()
frame = frame if args.get("video", None) is None else frame[1]
text = "Unoccupied"
# if the frame could not be grabbed, then we have reached the end
# of the video
if frame is None:
break
# resize the frame, convert it to grayscale, and blur it
frame = imutils.resize(frame, width=500)
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)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
# loop over the contours
for c in cnts:
# if the contour is too small, ignore it
if cv2.contourArea(c) < args["min_area"]:
continue
# compute the bounding box for the contour, draw it on the frame,
# and update the text
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = "Occupied"
# draw the text and timestamp on the frame
cv2.putText(frame, "Room Status: {}".format(text), (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"),
(10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)
# 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)
key = cv2.waitKey(1) & 0xFF
# if the `q` key is pressed, break from the lop
if key == ord("q"):
break
# cleanup the camera and close any open windows
if (datetime.datetime.now() - interval) > datetime.timedelta(minutes=15):
firstFrame = None
vs.stop() if args.get("video", None) is None else vs.release()
cv2.destroyAllWindows()
Related
I'm thinking if I can take pictures while the motion detection is using my laptop webcam, so I used the code below from Pyimagesearch website. What I'm trying to do is take a picture when the motion detector detected something using webcam, while the frame is different from the previous one, then take a photo and save it to a file, I tried 'ret, frame = cap.read()' but it didn't work well, I may put it the wrong way, could somebody solve it this for me, please?
The code is here:
# import the necessary packages
from imutils.video import VideoStream
import argparse
import datetime
import imutils #pip install imutils on terminal
import time
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", help="path to the video file") #video file is optional, if video file equals None, then opencv will use webcam
ap.add_argument("-a", "--min-area", type=int, default=500, help="minimum area size") #500 pixels, no need to process large raw images through webcam
args = vars(ap.parse_args())
# if the video argument is None, then we are reading from webcam
if args.get('video', None) is None:
vs = VideoStream(src=0).start()
time.sleep(2.0)
# otherwise, we are reading from a video file
else:
vs = cv2.VideoCapture(args["video"])
# initialize the first frame in the video stream
firstFrame = None
# loop over the frames of the video
while True:
frame = vs.read()
frame = frame if args.get('video', None) is None else frame[1]
text = 'Unoccupied'
if frame is None:
break
frame = imutils.resize(frame, width=500)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
if firstFrame is None:
firstFrame = gray
continue
frameDelta = cv2.absdiff(firstFrame, gray)
thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
for c in cnts:
if cv2.contourArea(c) < args["min_area"]:
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = 'Occupied'
cv2.putText(frame, "Room Status: {}".format(text), (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"),
(10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)
cv2.imshow('Motion Detector', frame)
cv2.imshow('Thresh', thresh)
cv2.imshow('Frame Delta', frameDelta)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
vs.stop()if args.get("video", None) is None else vs.release()
cv2.destroyAllWindows()
If I understand your question correctly, you want to take images if motion is detected. An approach I would suggest, is to do not try and extract every frame but to extract one frame every let's say 1 second. So a 1-minute video will give 60 frames(images) and you won't end up with thousands of images(Webcam frame rate * seconds).
count = 0 # initialize counter (outside while loop)
On motion, take a picture every 1 sec(I would place it inside this if statement:
if cv2.contourArea(c) < args["min_area"]:
vs.set(cv2.CAP_PROP_POS_MSEC,(count*1000)) # wait 1 sec between each capture
cv2.imwrite('Motion_det'+str(count)+'.jpg',frame) # save frame as JPEG file
count+=1
The adjust bellow will save image and video:
# import the necessary packages
from imutils.video import VideoStream
import argparse
import datetime
import imutils #pip install imutils on terminal
import time
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", help="path to the video file") #video file is optional, if video file equals None, then opencv will use webcam
ap.add_argument("-a", "--min-area", type=int, default=500, help="minimum area size") #500 pixels, no need to process large raw images through webcam
args = vars(ap.parse_args())
# if the video argument is None, then we are reading from webcam
if args.get('video', None) is None:
vs = VideoStream(src=0).start()
time.sleep(2.0)
# otherwise, we are reading from a video file
else:
vs = cv2.VideoCapture(args["video"])
# initialize the first frame in the video stream
firstFrame = None
# loop over the frames of the video
sta = 0
while True:
frame = vs.read()
frame = frame if args.get('video', None) is None else frame[1]
text = 'Unoccupied'
if frame is None:
break
frame = imutils.resize(frame, width=500)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
if firstFrame is None:
firstFrame = gray
continue
frameDelta = cv2.absdiff(firstFrame, gray)
thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
record = "No"
for c in cnts:
if cv2.contourArea(c) < args["min_area"]:
record = "No"
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = 'Occupied'
record = "Yes"
cv2.putText(frame, "Room Status: {}".format(text), (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"),
(10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)
cv2.imshow('Motion Detector', frame)
cv2.imshow('Thresh', thresh)
cv2.imshow('Frame Delta', frameDelta)
if record = "Yes":
try:
ts = time.time()
st = datetime.datetime.fromtimestamp(ts).strftime("%Y.%m.%d_%H.%M")
if sta != st:
filename = 'video-' + st + '.mp4'
out = cv2.VideoWriter(filename, fourcc, float(fps), (1280,720))
frame_name = filename.replace('.mp4','.png').format(frame_index)
cv2.imwrite(frame_name,frame)
sta = st
frame_record = cv2.resize(frame,(1280,720),fx=0,fy=0, interpolation = cv2.INTER_CUBIC)
out.write(frame_record)
except Exception as e:
print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno), type(e).__name__, e)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
vs.stop()
vs.release()
cv2.destroyAllWindows()
The code which I have written is able to create the summary of the video by skippig the frames with no motion. But it is taking more than 10 times the duration of the video to save the output video. So anyone can please help me with making some changes in the code. It is not the issue with system configuration. I have tried it even in a i7 GPU system.
import cv2
import imutils
vs = cv2.VideoCapture("example_01.mp4")
fgbg = cv2.createBackgroundSubtractorMOG2()
pathOut = "output.mp4"
frame_array = []
while True:
ret,frame = vs.read()
forig = frame.copy()
height,width,layers = frame.shape
size = (width,height)
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
gray = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
mask = fgbg.apply(gray)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts = cv2.findContours(mask.copy(),
cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cv2.imshow('mask',mask)
for c in cnts:
area = cv2.contourArea(c)
if area > 2000:
frame_array.append(frame)
out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'MPEG'), 20,
size)
for i in range(len(frame_array)):
out.write(frame_array[i])
out.release()
cv2.imshow("Frame", frame)
key = cv2.waitKey(25)
if key == ord("q"):
break
vs.release()
cv2.destroyAllWindows()
I took 18seconds movie and your code on my old computer worked many minutes and it was slowing down so finally I killed it and didn't get output movie.
This code needs ~57 seconds to do the same. If I don't display windows then it needs 39 seconds.
I open out only once. I don't append frame to frame_array but write this one frame directly to file.
import cv2
import imutils
import time
vs = cv2.VideoCapture("Wideo/1-sierpinski-carpet-turtle.mp4")
fgbg = cv2.createBackgroundSubtractorMOG2()
pathOut = "output.mp4"
out = None
start = time.time()
while True:
ret, frame = vs.read()
if frame is None:
break
forig = frame.copy()
height, width, layers = frame.shape
size = (width, height)
if not out:
out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'MPEG'), 20, size)
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
gray = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
mask = fgbg.apply(gray)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cv2.imshow('mask',mask)
for c in cnts:
area = cv2.contourArea(c)
if area > 2000:
out.write(frame)
break # don't check other areas
cv2.imshow("Frame", frame)
key = cv2.waitKey(25)
if key == ord("q"):
break
end = time.time()
print("time:", end-start)
out.release()
vs.release()
cv2.destroyAllWindows()
Your code opens file again and again and write all frames again and again - so it was slowing down on my computer. You could eventually write it only once after loop.
import cv2
import imutils
import time
vs = cv2.VideoCapture("Wideo/1-sierpinski-carpet-turtle.mp4")
fgbg = cv2.createBackgroundSubtractorMOG2()
pathOut = "output.mp4"
frame_array = []
start = time.time()
while True:
ret, frame = vs.read()
if frame is None:
break
forig = frame.copy()
height, width, layers = frame.shape
size = (width, height)
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
gray = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
mask = fgbg.apply(gray)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cv2.imshow('mask',mask)
for c in cnts:
area = cv2.contourArea(c)
if area > 2000:
frame_array.append(frame)
break
cv2.imshow("Frame", frame)
key = cv2.waitKey(25)
if key == ord("q"):
break
# --- after loop ---
out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'MPEG'), 20, size)
for frame in frame_array:
out.write(frame)
out.release()
end = time.time()
print("time:", end-start)
vs.release()
cv2.destroyAllWindows()
I was following this tutorial and I tried to save the video to an avi file, but every time I tried the file was corrupted. I was able to save the frames individually using cv2.imwrite(), but stitching together the individual frames was a lot of work, and would lag the entire program. Here is my code:
from imutils.video import VideoStream
import imutils
import time
import cv2
MINIMUM_AREA = 500
# For Video Recording Purposes
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('vibralert_test001.avi', fourcc, 20, (640, 480))
vs = VideoStream(src=0).start()
print("Setting up feed.")
time.sleep(2)
print("Live")
firstFrame = None
while True:
frame = vs.read()
text = "No Movement Detected"
frame = imutils.resize(frame, width=500)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
if firstFrame is None:
firstFrame = gray
continue
delta = cv2.absdiff(firstFrame, gray)
thresh = cv2.threshold(delta, 25, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
for c in cnts:
if cv2.contourArea(c) < MINIMUM_AREA:
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = "Movement Detected"
cv2.putText(frame, "Room Status: {}".format(text), (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("VibrAlert v0.1", frame)
out.write(frame)
key = cv2.waitKey(1) & 0xFF
if key == 27:
break
vs.stop()
out.release()
cv2.destroyAllWindows()
print('End Feed')
The size of the frame images need to be the same as the frameSize given to the VideoWriter, (640,480). The frame is being resized to have a width of 500, while the videoWriter is expecting a width of 640.
However, changing the resize to frame = imutils.resize(frame, width=640) probably won't work either. imutils.resize will return images with the same aspect ratio as the original image, so the height won't necessarily be 480. I would suggest replacing that line with the opencv.resize:
frame = cv2.resize(frame, (640,480))
I have a problem while running a function in Python 3 with OpenCV 3, I want to calibrate a video with a calibration data .npz and it results in an error message on remapping matrix line.
The calibrated video output is great but it came with an error message, which prevents any further execution. How could I make the script ignore the error and continue?
Any answer will be greatly appreciated.
This is the code:
import cv2, time, sys
import numpy as np
import matplotlib.pyplot as plt
filename = 'vtest3.mp4'
filename_2 = 'vtest3_undistort.mp4'
crop = 0.5
#FIRST FUNCTION (UNDISTORTION)
def undistortion(filename):
print('Loading data files')
npz_calib_file = np.load('calibration_data.npz')
distCoeff = npz_calib_file['distCoeff']
intrinsic_matrix = npz_calib_file['intrinsic_matrix']
npz_calib_file.close()
print('Finished loading files')
print(' ')
print('Starting to undistort the video....')
# Opens the video import and sets parameters
video = cv2.VideoCapture(filename)
# Checks to see if a the video was properly imported
status = video.isOpened()
if status == True:
FPS = video.get(cv2.CAP_PROP_FPS)
width = video.get(cv2.CAP_PROP_FRAME_WIDTH)
height = video.get(cv2.CAP_PROP_FRAME_HEIGHT)
size = (int(width), int(height))
total_frames = video.get(cv2.CAP_PROP_FRAME_COUNT)
frame_lapse = (1 / FPS) * 1000
# Initializes the export video file
codec = cv2.VideoWriter_fourcc(*'DIVX')
video_out = cv2.VideoWriter(str(filename[:-4]) + '_undistort.mp4', codec, FPS, size, 1)
# Initializes the frame counter
current_frame = 0
newMat, ROI = cv2.getOptimalNewCameraMatrix(intrinsic_matrix, distCoeff, size, alpha=crop,
centerPrincipalPoint=1)
mapx, mapy = cv2.initUndistortRectifyMap(intrinsic_matrix, distCoeff, None, newMat, size, m1type=cv2.CV_32FC1)
while current_frame < total_frames:
success, image = video.read()
current_frame = video.get(cv2.CAP_PROP_POS_FRAMES)
dst = cv2.remap(image, mapx, mapy, cv2.INTER_LINEAR)
# dst = cv2.undistort(image, intrinsic_matrix, distCoeff, None)
video_out.write(dst)
video.release()
video_out.release()
else:
print('Error: Could not load video')
sys.exit()
#SECOND FUNCTION
def hauptprogramm(filename_2):
# Create an empty List for x- and y-Positions that will be filled in for-loop
# with the .append function
xposition = [] # Empty list for x-Positions
yposition = [] # Empty list for y-Positions
# Open the Video with die VideoCapture function
# Name the video that is opened cap
cap = cv2.VideoCapture(filename_2)
# set the framenumber to the last frame just to take a picture
cap.set(1, cap.get(cv2.CAP_PROP_FRAME_COUNT)); # Where frame_no is the frame you want
ret, frame = cap.read() # Read the frame
cv2.imwrite('kurve.jpg', frame)
# set the framenumber to 1, which is the first frame of the video
# from here we begin to analyse the video
cap.set(1, 1);
# cv2.imshow('window_name', frame) # show frame on window
# pos_frame = cap.get(cv2.CAP_PROP_POS_FRAMES)
# start an infinite while loop by setting while True
# the loop will go on until we break it
while True:
# read a frame of the video and name it frame0
# read the next frame of the video and name it frame1
# set both frames retangle by writing ret,frame
ret, frame0 = cap.read()
ret, frame1 = cap.read()
ret, frame2 = cap.read()
# the program will lateron compare every pixel from frame0 to frame1 and
# locate the areas where many pixels have changed
# we only are interested in the area where the missile is flying
# the moving of the catapult itself for exemple would cause trouble
# so we paint lines over the areas we are not interested in these lines
# will be painted every loop over frame1
cv2.line(frame1, (0, 0), (0, 511), (255, 0, 0), 200)
cv2.line(frame1, (0, 500), (1000, 500), (255, 0, 0), 350)
cv2.line(frame1, (0, 350), (150, 350), (255, 0, 0), 400)
# the same lines will be painted over frame2
cv2.line(frame2, (0, 0), (0, 511), (255, 0, 0), 200)
cv2.line(frame2, (0, 500), (1000, 500), (255, 0, 0), 350)
cv2.line(frame2, (0, 350), (150, 350), (255, 0, 0), 400)
# for the function that will compare frame1 and frame2 both frames have
# to be in black and white
# the next function will be used to convert frame1 and frame2 to black and
# white and will name them gray1 and gray2
gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
# the absdiff function will compare the gray1 and gray2 images and returns
# an image named diffimage
diffimage = cv2.absdiff(gray1, gray2)
# the result of that function returns a black and white image
# to get clear results the image will be converted to a binary image
# the new image called diffimage only has pixels that are white or black
ret, threshold = cv2.threshold(diffimage, 30, 255, cv2.THRESH_BINARY)
# to reduce the image noise we will make the threshold image blurry by using
# the blur function
threshold = cv2.blur(threshold, (25, 25))
# when converting the blurry image into a threshold image for a secound
# time the small noisy pixels of the image will be gone and the areas where
# a lot of pixels have changed in will be clearer and bigger
ret, threshold = cv2.threshold(threshold, 30, 255, cv2.THRESH_BINARY)
# ========================find the white areas ==================
# now we want to find the white areas in the picture that show
# our flying missile
# !exakte funktion noch nicht verstanden
image, contours, hierarchy = cv2.findContours(threshold.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# !exakte funktion noch nicht verstanden
for cnt in contours:
area = cv2.contourArea(cnt)
# to reduce the chance of tracking background noise that might be left
# even after reducing it with the blur and threshold functions
# we only track the position of if the white area is bigger than x=10
if area > 10:
# we are looking for the bounding rectangle that is around our area
# x and y equal the pixelposition of the top right point of the rectangle
# w and h equal the width and height of the rectangle
x, y, w, h = cv2.boundingRect(cnt)
# we are interested in the center of the rectangle so we add w/2 to x
# and h/2 to y
# because the x- and y-positions have to be integer we round the values
# and declare them as such
xpos = int(round(x + w / 2))
ypos = int(round(y + h / 2))
# to see if everything works fine wile running the program the positions
# can be printed in the console by removing the hashtag
# print("x= ", xpos)
# print("y= ", ypos)
# now the list of x- and y-positions will be extended by every loop
# with these list of positions we can work later on for the
# post-processing of the curve the object is flying
xposition.append(xpos)
yposition.append(ypos)
# not necessary to post-process but a nice visualisation and checking
# if everything works as it is supposed to
# a small circle will be painted on the x- and y-position
# therefore we take the "empty" frame0 that does not have the colored
# lines painted into
cv2.circle(frame0, (xpos, ypos), 5, (0, 255, 0), -1)
# a rectangle will be surrounding the center just to keep track of the
# moving object
cv2.rectangle(frame0, (x, y), (x + w, y + h), (255, 0, 0), 3)
# write the x- and y- position in each frame
cv2.putText(frame0, 'x = ' + str(xpos), (xpos - 20, ypos - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255), 2, cv2.LINE_AA)
cv2.putText(frame0, 'y = ' + str(ypos), (xpos - 20, ypos + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255), 2, cv2.LINE_AA)
# x-Positionen in Konsole mitschreiben
# print(xposition)
# ========================= Open Windows ====================
# the imshow functions open a window and show the selected frame each
# while loop (play the video)
# by removing the hashtag the selected video will open when running the
# program
# 1. Show the original frames and paint the previous visulisation
cv2.imshow('Orginal mit Verfolgung', frame0)
# 2. Show the threshold frames
cv2.imshow('threshold frames', threshold)
# 3. Show the painted lines in frame1 and frame2 (same parameters)
cv2.imshow('mit Balken', frame1)
# if we press the ESC button the loop will break
if cv2.waitKey(10) == 27: # mit ESC verlassen
break
# if we reach the total number of frames the loop will break
if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
# If the number of captured frames is equal to the total number of frames,
# we stop
break
# after we break the loop we release the cap and force all windows to close
cap.release()
cv2.destroyAllWindows()
# does not make sense, just a way to fix a bug in opencv
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(100)
# =================== Spielerei ====================
# cap2 = cv2.VideoCapture("vtest3.m4v")
# while True:
# cap2.set(1,cv2.CAP_PROP_FRAME_COUNT)
# ret, frame = cap.read()
# cv2.imshow('window_name', frame)
#
# if cv2.waitKey(10) == 27: # mit ESC verlassen
# break
#
# cap.release()
# cv2.destroyAllWindows()
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# ========== Plot öffnen und speichern ===================
plt.plot(np.asarray(xposition), np.asarray(yposition), 'g^')
plt.axis('equal')
plt.savefig('positionen.png')
# ============== Image lesen und auswerten ===============
image = cv2.imread('kurve.jpg')
for i in range(0, len(xposition)):
cv2.circle(image, (xposition[i], yposition[i]), 5, (0, 255, 0), -1)
cv2.imwrite('positionen2.png', image)
undistortion(filename)
hauptprogramm(filename_2)
I'm working on my MSc project which is researching automated deletion of low value content in digital file stores. I'm specifically looking at the sort of long shots that often occur in natural history filming whereby a static camera is left rolling in order to capture the rare snow leopard or whatever. These shots may only have some 60s of useful content with perhaps several hours of worthless content either side.
As a first step I have a simple motion detection program from Adrian Rosebrock's tutorial [http://www.pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/#comment-393376]. Next I intend to use FFMPEG to split the video.
What I would like help with is how to get in and out points based on the first and last points that motion is detected in the video.
Here is the code should you wish to see it...
# import the necessary packages
import argparse
import datetime
import imutils
import time
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", help="path to the video file")
ap.add_argument("-a", "--min-area", type=int, default=500, help="minimum area size")
args = vars(ap.parse_args())
# if the video argument is None, then we are reading from webcam
if args.get("video", None) is None:
camera = cv2.VideoCapture(0)
time.sleep(0.25)
# otherwise, we are reading from a video file
else:
camera = cv2.VideoCapture(args["video"])
# initialize the first frame in the video stream
firstFrame = None
# loop over the frames of the video
while True:
# grab the current frame and initialize the occupied/unoccupied
# text
(grabbed, frame) = camera.read()
text = "Unoccupied"
# 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=500)
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)
(_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# loop over the contours
for c in cnts:
# if the contour is too small, ignore it
if cv2.contourArea(c) < args["min_area"]:
continue
# compute the bounding box for the contour, draw it on the frame,
# and update the text
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = "Occupied"
# draw the text and timestamp on the frame
cv2.putText(frame, "Room Status: {}".format(text), (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"),
(10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)
# 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)
key = cv2.waitKey(1) & 0xFF
# if the `q` key is pressed, break from the lop
if key == ord("q"):
break
# cleanup the camera and close any open windows
camera.release()
cv2.destroyAllWindows()