diff --git a/filter/filters_circleci.go b/filter/filters_circleci.go index e9b4b8df..bb49d712 100644 --- a/filter/filters_circleci.go +++ b/filter/filters_circleci.go @@ -37,7 +37,7 @@ func NewMOG(dst io.WriteCloser, area, threshold float64, history int, debug bool } // NewKNN returns a pointer to a new NoOp struct for testing purposes only. -func NewKNN(dst io.WriteCloser, area, threshold float64, history, kernelSize int, debug bool, hf int) *NoOp { +func NewKNN(dst io.WriteCloser, area, threshold float64, history, kernelSize int, debug bool, hf int, downscalingFactor int) *NoOp { return &NoOp{dst: dst} } diff --git a/filter/knn.go b/filter/knn.go index b9b1c3f5..0009ce7d 100644 --- a/filter/knn.go +++ b/filter/knn.go @@ -49,17 +49,18 @@ type KNN struct { hold [][]byte // Will hold all frames up to hf (so only every hf frame is motion detected). hf int // The number of frames to be held. hfCount int // Counter for the hold array. + scale float64 // The factor that frames will be downscaled by for motion detection. } // NewKNN returns a pointer to a new KNN filter struct. -func NewKNN(dst io.WriteCloser, area, threshold float64, history, kernelSize int, debug bool, hf int) *KNN { +func NewKNN(dst io.WriteCloser, area, threshold float64, history, kernelSize int, debug bool, hf int, downscalingFactor int) *KNN { bs := gocv.NewBackgroundSubtractorKNNWithParams(history, threshold, false) k := gocv.GetStructuringElement(gocv.MorphRect, image.Pt(kernelSize, kernelSize)) var windows []*gocv.Window if debug { windows = []*gocv.Window{gocv.NewWindow("KNN: Bounding boxes"), gocv.NewWindow("KNN: Motion")} } - return &KNN{dst, area, &bs, k, debug, windows, make([][]byte, hf-1), hf, 0} + return &KNN{dst, area, &bs, k, debug, windows, make([][]byte, hf-1), hf, 0, 1 / float64(downscalingFactor)} } // Implements io.Closer. @@ -94,6 +95,9 @@ func (m *KNN) Write(f []byte) (int, error) { imgDelta := gocv.NewMat() defer imgDelta.Close() + // Downsize image to speed up calculations. + gocv.Resize(img, &img, image.Point{}, m.scale, m.scale, gocv.InterpolationNearestNeighbor) + // Seperate foreground and background. m.bs.Apply(img, &imgDelta) diff --git a/revid/revid.go b/revid/revid.go index c562799c..faac33a9 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -345,7 +345,7 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64) (io. case config.FilterVariableFPS: r.filters[i] = filter.NewVariableFPS(dst, r.cfg.MinFPS, filter.NewMOG(dst, r.cfg.MOGMinArea, r.cfg.MOGThreshold, int(r.cfg.MOGHistory), r.cfg.ShowWindows, r.cfg.MotionInterval, r.cfg.MotionDownscaling)) case config.FilterKNN: - r.filters[i] = filter.NewKNN(dst, r.cfg.KNNMinArea, r.cfg.KNNThreshold, int(r.cfg.KNNHistory), int(r.cfg.KNNKernel), r.cfg.ShowWindows, r.cfg.MotionInterval) + r.filters[i] = filter.NewKNN(dst, r.cfg.KNNMinArea, r.cfg.KNNThreshold, int(r.cfg.KNNHistory), int(r.cfg.KNNKernel), r.cfg.ShowWindows, r.cfg.MotionInterval, r.cfg.MotionDownscaling) case config.FilterDifference: r.filters[i] = filter.NewDifference(dst, r.cfg.ShowWindows, r.cfg.DiffThreshold) case config.FilterBasic: