|  | 
|  | 1 | +#!/usr/bin/python3 | 
|  | 2 | + | 
|  | 3 | +# ------------------------------------------------------------------------------ | 
|  | 4 | +# Detect any motion in the frame. | 
|  | 5 | +# ------------------------------------------------------------------------------ | 
|  | 6 | +# automaticdai | 
|  | 7 | +# YF Robotics Labrotary | 
|  | 8 | +# Instagram: yfrobotics | 
|  | 9 | +# Twitter: @yfrobotics | 
|  | 10 | +# Website: https://www.yfrl.org | 
|  | 11 | +# --------------------------------------------#!/usr/bin/python3 | 
|  | 12 | + | 
|  | 13 | +# ------------------------------------------------------------------------------ | 
|  | 14 | +# Detect any motion in the frame. | 
|  | 15 | +# ------------------------------------------------------------------------------ | 
|  | 16 | +# automaticdai | 
|  | 17 | +# YF Robotics Labrotary | 
|  | 18 | +# Instagram: yfrobotics | 
|  | 19 | +# Twitter: @yfrobotics | 
|  | 20 | +# Website: https://www.yfrl.org | 
|  | 21 | +# ------------------------------------------------------------------------------ | 
|  | 22 | + | 
|  | 23 | +import cv2 | 
|  | 24 | +import time | 
|  | 25 | +import numpy as np | 
|  | 26 | + | 
|  | 27 | +from picamera2 import Picamera2 | 
|  | 28 | + | 
|  | 29 | +MOTION_BLUR = True | 
|  | 30 | + | 
|  | 31 | +cnt_frame = 0 | 
|  | 32 | +fps = 0 | 
|  | 33 | + | 
|  | 34 | +# Initialize Picamera2 and configure the camera | 
|  | 35 | +picam2 = Picamera2() | 
|  | 36 | +picam2.configure(picam2.create_preview_configuration(main={"format": 'XRGB8888', "size": (640, 480)})) | 
|  | 37 | +picam2.start() | 
|  | 38 | + | 
|  | 39 | +def mse(image_a, image_b): | 
|  | 40 | +    # the 'Mean Squared Error' between the two images is the | 
|  | 41 | +    # sum of the squared difference between the two images; | 
|  | 42 | +    # NOTE: the two images must have the same dimension | 
|  | 43 | +    err = np.sum((image_a.astype("float") - image_b.astype("float")) ** 2) | 
|  | 44 | +    err /= float(image_a.shape[0] * image_a.shape[1]) | 
|  | 45 | + | 
|  | 46 | +    # return the MSE, the lower the error, the more "similar" | 
|  | 47 | +    # the two images are | 
|  | 48 | +    return err | 
|  | 49 | + | 
|  | 50 | + | 
|  | 51 | +def visualize_fps(image, fps: int): | 
|  | 52 | +    if len(np.shape(image)) < 3: | 
|  | 53 | +        text_color = (255, 255, 255)  # white | 
|  | 54 | +    else: | 
|  | 55 | +        text_color = (0, 255, 0)  # green | 
|  | 56 | +    row_size = 20  # pixels | 
|  | 57 | +    left_margin = 24  # pixels | 
|  | 58 | + | 
|  | 59 | +    font_size = 1 | 
|  | 60 | +    font_thickness = 1 | 
|  | 61 | + | 
|  | 62 | +    # Draw the FPS counter | 
|  | 63 | +    fps_text = 'FPS = {:.1f}'.format(fps) | 
|  | 64 | +    text_location = (left_margin, row_size) | 
|  | 65 | +    cv2.putText(image, fps_text, text_location, cv2.FONT_HERSHEY_PLAIN, | 
|  | 66 | +                font_size, text_color, font_thickness) | 
|  | 67 | + | 
|  | 68 | +    return image | 
|  | 69 | + | 
|  | 70 | + | 
|  | 71 | +if __name__ == "__main__": | 
|  | 72 | +    try: | 
|  | 73 | +		 | 
|  | 74 | +        while True: | 
|  | 75 | +            # ---------------------------------------------------------------------- | 
|  | 76 | +            # record start time | 
|  | 77 | +            start_time = time.time() | 
|  | 78 | +            # ---------------------------------------------------------------------- | 
|  | 79 | +            # Read the frames from a camera | 
|  | 80 | +            frame_raw = picam2.capture_array() | 
|  | 81 | + | 
|  | 82 | +            if MOTION_BLUR: | 
|  | 83 | +                # Denoise the frame | 
|  | 84 | +                frame = cv2.GaussianBlur(frame_raw, (3,3),0) | 
|  | 85 | +            else: | 
|  | 86 | +                frame = frame_raw | 
|  | 87 | + | 
|  | 88 | +            # Convert to gray image | 
|  | 89 | +            frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) | 
|  | 90 | + | 
|  | 91 | +            # Find edges | 
|  | 92 | +            edges = cv2.Canny(frame_gray,100,200) | 
|  | 93 | + | 
|  | 94 | +            # Show the original and processed image | 
|  | 95 | +            cv2.imshow('gray', visualize_fps(frame_gray, fps)) | 
|  | 96 | +            cv2.imshow('edge', visualize_fps(edges, fps)) | 
|  | 97 | + | 
|  | 98 | +            # Calculate MSE | 
|  | 99 | +            if cnt_frame > 0: | 
|  | 100 | +                if mse(frame_gray, frame_gray_p) > 100: | 
|  | 101 | +                    print('Frame{0}: Motion Detected!'.format(cnt_frame)) | 
|  | 102 | + | 
|  | 103 | +            # ---------------------------------------------------------------------- | 
|  | 104 | +            # record end time | 
|  | 105 | +            end_time = time.time() | 
|  | 106 | + | 
|  | 107 | +            # calculate FPS | 
|  | 108 | +            seconds = end_time - start_time | 
|  | 109 | +            fps = 1.0 / seconds | 
|  | 110 | +            print("Estimated fps:{0:0.1f}".format(fps)); | 
|  | 111 | + | 
|  | 112 | +            cnt_frame = cnt_frame + 1 | 
|  | 113 | +            edges_p = edges | 
|  | 114 | +            frame_gray_p = frame_gray | 
|  | 115 | +            # ---------------------------------------------------------------------- | 
|  | 116 | + | 
|  | 117 | +            # if key pressed is 'Esc' then exit the loop | 
|  | 118 | +            if cv2.waitKey(1)== 27: | 
|  | 119 | +                break | 
|  | 120 | +    except Exception as e: | 
|  | 121 | +        print(e) | 
|  | 122 | +    finally: | 
|  | 123 | +        # Clean up and exit the program | 
|  | 124 | +        cv2.destroyAllWindows() | 
|  | 125 | +        picam2.close() | 
0 commit comments