commit a2598f591286cd24d8dbcb3920479fe5d7e57676 Author: Bene Date: Thu Mar 2 08:41:42 2023 +0100 Initial commit diff --git a/CAM2maske.png b/CAM2maske.png new file mode 100644 index 0000000..57ecae4 Binary files /dev/null and b/CAM2maske.png differ diff --git a/CAM2maske.xcf b/CAM2maske.xcf new file mode 100644 index 0000000..1149880 Binary files /dev/null and b/CAM2maske.xcf differ diff --git a/CAM2maskeBW.png b/CAM2maskeBW.png new file mode 100644 index 0000000..f566ef3 Binary files /dev/null and b/CAM2maskeBW.png differ diff --git a/CAM2maskeBW640.png b/CAM2maskeBW640.png new file mode 100644 index 0000000..24b6643 Binary files /dev/null and b/CAM2maskeBW640.png differ diff --git a/FrameBuffer.py b/FrameBuffer.py new file mode 100644 index 0000000..0d2cc4b --- /dev/null +++ b/FrameBuffer.py @@ -0,0 +1,41 @@ +import cv2 +import imageio + + +class FrameBuffer(object): + + def __init__(self, size): + self.size = size + self.items = [] + + def is_empty(self): + return len(self.items) == 0 + + def get_size(self): + return len(self.items) + + def push(self, frame): + self.items.append(frame) + if self.get_size() > self.size: + self.items.pop(0) + + def get_frames(self): + return self.items + + def write_gif(self, filename): + with imageio.get_writer(filename, mode='I') as writer: + for frame in self.items: + writer.append_data(frame) + + def dump(self): + self.items = [] + + def write_mp4(self, filename, width, height, fps=25): + print("Schreibe mp4 Datei") + fourcc = cv2.VideoWriter_fourcc(*'mp4v') + out = cv2.VideoWriter(filename, fourcc, fps, frameSize=(width, height)) + + for frame in self.items: + out.write(frame) + + out.release() \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..2be4094 --- /dev/null +++ b/main.py @@ -0,0 +1,126 @@ +from datetime import datetime +from FrameBuffer import FrameBuffer +import cv2 +# import random +# RTSP-Stream-URL einstellen +#1280x720: +#rtsp_url = "rtsp://admin:RlBqOp30cam@192.168.178.121/live/ch0" +#640x360: +rtsp_url = "rtsp://admin:RlBqOp30cam@192.168.178.121/live/ch1" + +# OpenCV-Videoaufzeichnungsobjekt erstellen +cap = cv2.VideoCapture(rtsp_url) +width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) +height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) +print("Width: "+str(width)+" Height: "+str(height)) +fps = cap.get(cv2.CAP_PROP_FPS) +print(f'Framerate: {fps}') +# 2 Sekunden vor Erkennung +MAX_BUFFER = fps*2 +# Codec für die Ausgabe festlegen +fourcc = cv2.VideoWriter_fourcc(*'XVID') +frameBuffer = FrameBuffer(MAX_BUFFER) +# Initialisiere den Hintergrundsubtraktor +# Load the mask from a file +# mask_file = 'CAM2maskeBW.png' +mask_file = 'CAM2maskeBW640.png' +mask_rgb = cv2.imread(mask_file) +mask = cv2.imread(mask_file, cv2.IMREAD_GRAYSCALE) +# Invert the mask (if necessary) and threshold it +# mask = cv2.bitwise_not(mask) +mask = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1] +# Ausgabedatei erstellen und Videoaufzeichnung starten +# output_file = cv2.VideoWriter('output.avi', fourcc, 20.0, (640,480)) +counter = 1 +# print(datetime.datetime.now().time()) +firstFrameWithMotion = 0 +lastFrameWithMotion = 0 +fgbg = cv2.createBackgroundSubtractorMOG2() +bufferedFrames = [] +while(cap.isOpened()): + try: + ret, frame = cap.read() + if ret: + #output_file.write(frame) + #img = cv2.imread(frame) + # Wende die Maske auf das Frame an + masked_frame = cv2.bitwise_and(frame, frame, mask=mask) + + # Subtrahiere das Hintergrund-Modell von dem aktuellen Frame + fgmask = fgbg.apply(masked_frame) + #gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + #fgmask = fgbg.apply(gray) + blur = cv2.GaussianBlur(fgmask, (5,5), 0) + ret,thresh = cv2.threshold(blur,100,255,cv2.THRESH_BINARY) + kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) + opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 3) + contours, hierarchy = cv2.findContours(opening, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + for c in contours: + area = cv2.contourArea(c) + faktor = (width*height*4)/(640*360) + #if area > width*height/3 or area < width*height/20: + # continue + if area < 1600*faktor or area > 40000*faktor: + continue + (x, y, w, h) = cv2.boundingRect(c) + cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) + if firstFrameWithMotion == 0: + firstFrameWithMotion = counter + lastFrameWithMotion = counter + bufferedFrames = frameBuffer.get_frames() + if firstFrameWithMotion > 0: + lastFrameWithMotion = counter + + MAX_PAUSE_OF_MOTION = fps/2 + MIN_DURATION_OF_MOTION = fps*2 + WATCH_BEFORE = fps*2 + if firstFrameWithMotion > 0 and lastFrameWithMotion - firstFrameWithMotion > MIN_DURATION_OF_MOTION and counter - lastFrameWithMotion > MAX_PAUSE_OF_MOTION: + + fourcc = cv2.VideoWriter_fourcc(*'mp4v') + now = datetime.now() + # Format the date and time as a string + dt_string = now.strftime("%Y-%m-%d_%H-%M-%S") + print(dt_string + " Schreibe mp4 Datei") + out = cv2.VideoWriter("output-" + dt_string + ".mp4", fourcc, fps, frameSize=(width, height)) + for frame in bufferedFrames: + out.write(frame) + out.release() + firstFrameWithMotion = 0 + lastFrameWithMotion = 0 + frameBuffer.dump() + bufferedFrames = [] + + if counter > MAX_BUFFER and firstFrameWithMotion == 0: + counter = 1 + + # Apply the mask to the frame + #masked_frame = cv2.multiply(0.2, mask_rgb) + frame + + cv2.imshow('frame',frame) + #cv2.imshow('fgmask',fgmask) + if firstFrameWithMotion == 0: + frameBuffer.push(frame) + else: + bufferedFrames.append(frame) + #if counter % 10 == 0: + # print("Frame"+str(counter)) + counter += 1 + + + #blur_img = cv2.GaussianBlur(frame, (5, 5), 0) + #cv2.imshow('frame',blur_img) + #edges = cv2.Canny(blur_img, 150, 200) + #cv2.imshow("Kantenerkennung", edges) + + if cv2.waitKey(1) & 0xFF == ord('q'): + break + else: + break + except Exception as e: + # Hier kommt der Code, der ausgeführt wird, wenn ein Fehler auftritt + print("Ein Fehler ist aufgetreten:", str(e)) + +# Freigeben der Ressourcen +cap.release() +cv2.destroyAllWindows() \ No newline at end of file