dimanche 28 mai 2017

RedCV: Motion detection with differential images

The Red code is based on the following paper: Collins, R., Lipton, A., Kanade, T., Fijiyoshi, H., Duggins, D., Tsin, Y., Tolliver, D., Enomoto, N., Hasegawa, O., Burt, P., Wixson, L.: A system for video surveillance and monitoring. Tech. rep., Carnegie Mellon University, Pittsburg, PA (2000).

The idea is to use the webcam and analyse motion using differential images.

Differential Images

Differential Images are the result of the subtraction of two images:  Idif (x, y) = I1(x, y) − I2(x, y).

A differential image shows the pixels differences between two images. With those images you can make movement visible.

Based on the quoted paper,  we use a differential image calculated from three consecutive images It−1 (previous image),  It (current image) and It+1 (next image). The advantage of this technic is that the motionless  background is removed from the result, and only motion pixels are visible.


RedCV offers the possibility to subtract two images from each other using rcvAbsDiff. Since logical operations on images are also implemented, we use rcvAnd to achieve the final differential image.

Code

Implemented code is simple to understand and just requires a time event to activate the camera. When the time event occurs, differential image is calculated and updated in the base object. To-image Red function allows to copy the webcam image to a Red image. Thanks Red!

Red [
    Title:   "Test image operators and camera Red VID "
    Author:  "Francois Jouen"
    File:    %motion.red
    Needs:   'View
]

; all we need for computer vision with red
#include %../../libs/redcv.red ; for red functions

iSize: 320x240
prevImg: rcvCreateImage iSize
currImg: rcvCreateImage iSize
nextImg: rcvCreateImage iSize
d1: rcvCreateImage iSize
d2: rcvCreateImage iSize
r1: rcvCreateImage iSize
r2: rcvCreateImage iSize

margins: 10x10
threshold: 32

to-text: function [val][form to integer! 0.5 + 128 * any [val 0]]

view win: layout [
        title "Motion Detection"
        origin margins space margins
        text "Motion " 50 
        motion: field 50 rate 0:0:1 on-time [face/text: to-text rcvCountNonZero r2]
        btnQuit: button "Quit" 60x24 on-click [
            rcvReleaseImage prevImg
            rcvReleaseImage currImg
            rcvReleaseImage nextImg
            rcvReleaseImage d1
            rcvReleaseImage d2
            rcvReleaseImage r1
            rcvReleaseImage r2
            quit]
        return
        cam: camera iSize
        canvas: base 320x240 r2 rate 0:0:1 on-time [
            rcv2gray/average nextImg currImg    ; transforms to grayscale since, we don't need color
            rcvAbsdiff  prevImg currImg d1      ; difference between previous and current image
            rcvAbsdiff  currImg nextImg d2      ; difference between current and next image
            rcvAnd d1 d2 r1                     ; AND differences
            rcv2BWFilter r1 r2 threshold        ; Applies B&W Filter to base/image
            prevImg: currImg                    ; previous image contains now the current image
            currImg: nextImg                    ; current image contains the next image             
            nextImg: to-image cam               ; updates next image
        ]
        return
        text 40 "Select" 
        cam-list: drop-list 180x32 on-create [
                face/data: cam/data
            ]
        onoff: button "Start/Stop" 80x24 on-click [
                either cam/selected [
                    cam/selected: none
                    canvas/rate: none
                    motion/rate: none
                    canvas/image: black
                ][
                    cam/selected: cam-list/selected
                    rcvZeroImage prevImg
                    rcvZeroImage currImg
                    rcvZeroImage nextImg
                    canvas/rate: 0:0:0.04;  max 1/25 fps in ms
                    motion/rate: 0:0:0.04
                    ]
            ]
        text "Filter" 40
        sl1: slider 180 [filter/text: to-text sl1/data threshold: to integer! filter/data ]
        filter: field 40 "32" 
        do [cam-list/selected: 1 motion/rate: canvas/rate: none sl1/data: 0.32 ]
]

Result


Aucun commentaire:

Enregistrer un commentaire