Merged in motion-filter-variables (pull request #325)

Motion filter variables

Approved-by: Saxon Milton <saxon.milton@gmail.com>
This commit is contained in:
Scott Barnard 2020-01-09 02:13:27 +00:00 committed by Saxon Milton
commit f5b8ea10fc
4 changed files with 142 additions and 24 deletions

2
go.mod
View File

@ -3,7 +3,7 @@ module bitbucket.org/ausocean/av
go 1.13 go 1.13
require ( require (
bitbucket.org/ausocean/iot v1.2.10 bitbucket.org/ausocean/iot v1.2.11
bitbucket.org/ausocean/utils v1.2.12 bitbucket.org/ausocean/utils v1.2.12
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7
github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480 github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480

4
go.sum
View File

@ -2,8 +2,12 @@ bitbucket.org/ausocean/iot v1.2.9 h1:3tzgiekH+Z0yXhkwnqBzxxe8qQJ2O7YTkz4s0T6stgw
bitbucket.org/ausocean/iot v1.2.9/go.mod h1:Q5FwaOKnCty3dVeVtki6DLwYa5vhNpOaeu1lwLyPCg8= bitbucket.org/ausocean/iot v1.2.9/go.mod h1:Q5FwaOKnCty3dVeVtki6DLwYa5vhNpOaeu1lwLyPCg8=
bitbucket.org/ausocean/iot v1.2.10 h1:TTu+ykH5gQA8wU/pN0aS55ySQ/XcGxV4s4LKx3Wye5k= bitbucket.org/ausocean/iot v1.2.10 h1:TTu+ykH5gQA8wU/pN0aS55ySQ/XcGxV4s4LKx3Wye5k=
bitbucket.org/ausocean/iot v1.2.10/go.mod h1:Q5FwaOKnCty3dVeVtki6DLwYa5vhNpOaeu1lwLyPCg8= bitbucket.org/ausocean/iot v1.2.10/go.mod h1:Q5FwaOKnCty3dVeVtki6DLwYa5vhNpOaeu1lwLyPCg8=
bitbucket.org/ausocean/iot v1.2.11 h1:MwYQK1F2ESA5jPVSCB0lBUN8HBiNDHGkh/OMGJKw8Oc=
bitbucket.org/ausocean/iot v1.2.11/go.mod h1:Q5FwaOKnCty3dVeVtki6DLwYa5vhNpOaeu1lwLyPCg8=
bitbucket.org/ausocean/utils v1.2.11 h1:zA0FOaPjN960ryp8PKCkV5y50uWBYrIxCVnXjwbvPqg= bitbucket.org/ausocean/utils v1.2.11 h1:zA0FOaPjN960ryp8PKCkV5y50uWBYrIxCVnXjwbvPqg=
bitbucket.org/ausocean/utils v1.2.11/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= bitbucket.org/ausocean/utils v1.2.11/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8=
bitbucket.org/ausocean/utils v1.2.12 h1:VnskjWTDM475TnQRhBQE0cNp9D6Y6OELrd4UkD2VVIQ=
bitbucket.org/ausocean/utils v1.2.12/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 h1:LdOc9B9Bj6LEsKiXShkLA3/kpxXb6LJpH+ekU2krbzw= github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 h1:LdOc9B9Bj6LEsKiXShkLA3/kpxXb6LJpH+ekU2krbzw=

View File

@ -95,9 +95,23 @@ const (
defaultRTMPRBSize = 100 defaultRTMPRBSize = 100
defaultRTMPRBElementSize = 300000 defaultRTMPRBElementSize = 300000
defaultRTMPRBWriteTimeout = 5 defaultRTMPRBWriteTimeout = 5
// Motion filter parameter defaults.
defaultMinFPS = 1.0
// KNN filter parameter defaults.
defaultKNNMinArea = 25.0
defaultKNNThreshold = 300
defaultKNNHistory = 300
defaultKNNKernel = 9
// MOG filter parameter defaults.
defaultMOGMinArea = 25.0
defaultMOGThreshold = 20.0
defaultMOGHistory = 500
) )
// quality represents video quality. // Quality represents video quality.
type Quality int type Quality int
// The different video qualities that can be used for variable bitrate when // The different video qualities that can be used for variable bitrate when
@ -277,6 +291,20 @@ type Config struct {
MTSRBSize int // The number of elements in the MTS sender ringbuffer. MTSRBSize int // The number of elements in the MTS sender ringbuffer.
MTSRBElementSize int // The element size in bytes of the MTS sender RingBuffer. MTSRBElementSize int // The element size in bytes of the MTS sender RingBuffer.
MTSRBWriteTimeout int // The ringbuffer write timeout in seconds. MTSRBWriteTimeout int // The ringbuffer write timeout in seconds.
// Motion filter parameters.
MinFPS float64 // The reduced framerate of the video when there is no motion.
// KNN filter parameters.
KNNMinArea float64 // Used to ignore small areas of motion detection.
KNNThreshold float64 // Intensity value from the KNN motion detection algorithm that is considered motion.
KNNHistory uint // Length of KNN filter's history
KNNKernel uint // Size of kernel used for filling holes and removing noise.
// MOG filter parameters.
MOGMinArea float64 // Used to ignore small areas of motion detection.
MOGThreshold float64 // Intensity value from the KNN motion detection algorithm that is considered motion.
MOGHistory uint // Length of MOG filter's history
} }
// TypeData contains information about all of the variables that // TypeData contains information about all of the variables that
@ -298,13 +326,21 @@ var TypeData = map[string]string{
"Input": "enum:raspivid,rtsp,v4l,file", "Input": "enum:raspivid,rtsp,v4l,file",
"InputCodec": "enum:H264,MJPEG", "InputCodec": "enum:H264,MJPEG",
"InputPath": "string", "InputPath": "string",
"KNNHistory": "uint",
"KNNKernel": "float",
"KNNMinArea": "float",
"KNNThreshold": "float",
"logging": "enum:Debug,Info,Warning,Error,Fatal", "logging": "enum:Debug,Info,Warning,Error,Fatal",
"MinFPS": "float",
"MinFrames": "uint", "MinFrames": "uint",
"MOGHistory": "uint",
"MOGMinArea": "float",
"MOGThreshold": "float",
"MTSRBElementSize": "int", "MTSRBElementSize": "int",
"MTSRBSize": "int", "MTSRBSize": "int",
"MTSRBWriteTimeout": "int", "MTSRBWriteTimeout": "int",
"OutputPath": "string",
"Output": "enum:File,Http,Rtmp,Rtp", "Output": "enum:File,Http,Rtmp,Rtp",
"OutputPath": "string",
"Outputs": "enums:File,Http,Rtmp,Rtp", "Outputs": "enums:File,Http,Rtmp,Rtp",
"Quantization": "uint", "Quantization": "uint",
"Rotation": "uint", "Rotation": "uint",
@ -453,6 +489,46 @@ func (c *Config) Validate() error {
c.PSITime = defaultPSITime c.PSITime = defaultPSITime
} }
if c.MinFPS <= 0 {
c.Logger.Log(logger.Info, pkg+"MinFPS bad or unset, defaulting", "MinFPS", defaultMinFPS)
c.MinFPS = defaultMinFPS
}
if c.KNNMinArea <= 0 {
c.Logger.Log(logger.Info, pkg+"KNNMinArea bad or unset, defaulting", "KNNMinArea", defaultKNNMinArea)
c.KNNMinArea = defaultKNNMinArea
}
if c.KNNThreshold <= 0 {
c.Logger.Log(logger.Info, pkg+"KNNThreshold bad or unset, defaulting", "KNNThreshold", defaultKNNThreshold)
c.KNNThreshold = defaultKNNThreshold
}
if c.KNNHistory == 0 {
c.Logger.Log(logger.Info, pkg+"KNNHistory bad or unset, defaulting", "KNNHistory", defaultKNNHistory)
c.KNNHistory = defaultKNNHistory
}
if c.KNNKernel <= 0 {
c.Logger.Log(logger.Info, pkg+"KNNKernel bad or unset, defaulting", "KNNKernel", defaultKNNKernel)
c.KNNKernel = defaultKNNKernel
}
if c.MOGMinArea <= 0 {
c.Logger.Log(logger.Info, pkg+"MOGMinArea bad or unset, defaulting", "MOGMinArea", defaultMOGMinArea)
c.MOGMinArea = defaultMOGMinArea
}
if c.MOGThreshold <= 0 {
c.Logger.Log(logger.Info, pkg+"MOGThreshold bad or unset, defaulting", "MOGThreshold", defaultMOGThreshold)
c.MOGThreshold = defaultMOGThreshold
}
if c.MOGHistory == 0 {
c.Logger.Log(logger.Info, pkg+"MOGHistory bad or unset, defaulting", "MOGHistory", defaultMOGHistory)
c.MOGHistory = defaultMOGHistory
}
if c.ShowWindows { if c.ShowWindows {
os, err := osName() os, err := osName()
if err != nil { if err != nil {

View File

@ -76,24 +76,6 @@ const (
rtmpConnectionTimeout = 10 rtmpConnectionTimeout = 10
) )
// Motion filter parameters.
const minFPS = 1.0
// KNN specific parameters.
const (
knnMinArea = 25.0
knnThreshold = 300
knnHistory = 300
knnKernel = 9
)
// MOG specific parameters.
const (
mogMinArea = 25.0
mogThreshold = 20.0
mogHistory = 500
)
const pkg = "revid: " const pkg = "revid: "
type Logger interface { type Logger interface {
@ -360,11 +342,11 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64) (io.
case config.FilterNoOp: case config.FilterNoOp:
r.filters[i] = filter.NewNoOp(dst) r.filters[i] = filter.NewNoOp(dst)
case config.FilterMOG: case config.FilterMOG:
r.filters[i] = filter.NewMOGFilter(dst, mogMinArea, mogThreshold, mogHistory, r.cfg.ShowWindows) r.filters[i] = filter.NewMOGFilter(dst, r.cfg.MOGMinArea, r.cfg.MOGThreshold, int(r.cfg.MOGHistory), r.cfg.ShowWindows)
case config.FilterVariableFPS: case config.FilterVariableFPS:
r.filters[i] = filter.NewVariableFPSFilter(dst, minFPS, filter.NewMOGFilter(dst, mogMinArea, mogThreshold, mogHistory, r.cfg.ShowWindows)) r.filters[i] = filter.NewVariableFPSFilter(dst, r.cfg.MinFPS, filter.NewMOGFilter(dst, r.cfg.MOGMinArea, r.cfg.MOGThreshold, int(r.cfg.MOGHistory), r.cfg.ShowWindows))
case config.FilterKNN: case config.FilterKNN:
r.filters[i] = filter.NewKNNFilter(dst, knnMinArea, knnThreshold, knnHistory, knnKernel, r.cfg.ShowWindows) r.filters[i] = filter.NewKNNFilter(dst, r.cfg.KNNMinArea, r.cfg.KNNThreshold, int(r.cfg.KNNHistory), int(r.cfg.KNNKernel), r.cfg.ShowWindows)
default: default:
panic("Undefined Filter") panic("Undefined Filter")
} }
@ -803,6 +785,62 @@ func (r *Revid) Update(vars map[string]string) error {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid ShowWindows var", "value", value) r.cfg.Logger.Log(logger.Warning, pkg+"invalid ShowWindows var", "value", value)
break break
} }
case "MinFPS":
v, err := strconv.ParseFloat(value, 64)
if err != nil {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid MinFPS var", "value", value)
break
}
r.cfg.MinFPS = v
case "KNNMinArea":
v, err := strconv.ParseFloat(value, 64)
if err != nil {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid KNNMinArea var", "value", value)
break
}
r.cfg.KNNMinArea = v
case "KNNThreshold":
v, err := strconv.ParseFloat(value, 64)
if err != nil {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid KNNThreshold var", "value", value)
break
}
r.cfg.KNNThreshold = v
case "KNNKernel":
v, err := strconv.Atoi(value)
if err != nil {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid KNNKernel var", "value", value)
break
}
r.cfg.KNNKernel = uint(v)
case "MOGMinArea":
v, err := strconv.ParseFloat(value, 64)
if err != nil {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid MOGMinArea var", "value", value)
break
}
r.cfg.MOGMinArea = v
case "MOGThreshold":
v, err := strconv.ParseFloat(value, 64)
if err != nil {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid MOGThreshold var", "value", value)
break
}
r.cfg.MOGThreshold = v
case "KNNHistory":
v, err := strconv.Atoi(value)
if err != nil || v <= 0 {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid KNNHistory var", "value", value)
break
}
r.cfg.KNNHistory = uint(v)
case "MOGHistory":
v, err := strconv.Atoi(value)
if err != nil || v <= 0 {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid MOGHistory var", "value", value)
break
}
r.cfg.MOGHistory = uint(v)
} }
} }
r.cfg.Logger.Log(logger.Info, pkg+"revid config changed", "config", fmt.Sprintf("%+v", r.cfg)) r.cfg.Logger.Log(logger.Info, pkg+"revid config changed", "config", fmt.Sprintf("%+v", r.cfg))