mirror of https://bitbucket.org/ausocean/av.git
Frame counter resets on a consistent interval.
This commit is contained in:
parent
0b95041d4f
commit
4b28558924
131
filter/mog.go
131
filter/mog.go
|
@ -84,70 +84,71 @@ func (m *MOGFilter) Write(f []byte) (int, error) {
|
||||||
m.hold[hfCount] = f
|
m.hold[hfCount] = f
|
||||||
hfCount++
|
hfCount++
|
||||||
return 0, nil
|
return 0, nil
|
||||||
} else {
|
|
||||||
img, err := gocv.IMDecode(f, gocv.IMReadColor)
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("image can't be decoded: %w", err)
|
|
||||||
}
|
|
||||||
defer img.Close()
|
|
||||||
|
|
||||||
imgDelta := gocv.NewMat()
|
|
||||||
defer imgDelta.Close()
|
|
||||||
|
|
||||||
// Seperate foreground and background.
|
|
||||||
m.bs.Apply(img, &imgDelta)
|
|
||||||
|
|
||||||
// Threshold imgDelta.
|
|
||||||
gocv.Threshold(imgDelta, &imgDelta, 25, 255, gocv.ThresholdBinary)
|
|
||||||
|
|
||||||
// Remove noise.
|
|
||||||
gocv.Erode(imgDelta, &imgDelta, m.knl)
|
|
||||||
gocv.Dilate(imgDelta, &imgDelta, m.knl)
|
|
||||||
|
|
||||||
// Fill small holes.
|
|
||||||
gocv.Dilate(imgDelta, &imgDelta, m.knl)
|
|
||||||
gocv.Erode(imgDelta, &imgDelta, m.knl)
|
|
||||||
|
|
||||||
// Find contours and reject ones with a small area.
|
|
||||||
var contours [][]image.Point
|
|
||||||
allContours := gocv.FindContours(imgDelta, gocv.RetrievalExternal, gocv.ChainApproxSimple)
|
|
||||||
for _, c := range allContours {
|
|
||||||
if gocv.ContourArea(c) > m.area {
|
|
||||||
contours = append(contours, c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw debug information.
|
|
||||||
if m.debug {
|
|
||||||
for _, c := range contours {
|
|
||||||
rect := gocv.BoundingRect(c)
|
|
||||||
gocv.Rectangle(&img, rect, color.RGBA{0, 0, 255, 0}, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(contours) > 0 {
|
|
||||||
gocv.PutText(&img, "Motion", image.Pt(32, 32), gocv.FontHersheyPlain, 2.0, color.RGBA{255, 0, 0, 0}, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.windows[0].IMShow(img)
|
|
||||||
m.windows[1].IMShow(imgDelta)
|
|
||||||
m.windows[0].WaitKey(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't write to destination if there is no motion.
|
|
||||||
if len(contours) == 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write to destination, past 4 frames then current frame.
|
|
||||||
for i, h := range m.hold {
|
|
||||||
_, err := m.dst.Write(h)
|
|
||||||
m.hold[i] = nil
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hfCount = 0
|
|
||||||
return m.dst.Write(f)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hfCount = 0
|
||||||
|
img, err := gocv.IMDecode(f, gocv.IMReadColor)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("image can't be decoded: %w", err)
|
||||||
|
}
|
||||||
|
defer img.Close()
|
||||||
|
|
||||||
|
imgDelta := gocv.NewMat()
|
||||||
|
defer imgDelta.Close()
|
||||||
|
|
||||||
|
// Seperate foreground and background.
|
||||||
|
m.bs.Apply(img, &imgDelta)
|
||||||
|
|
||||||
|
// Threshold imgDelta.
|
||||||
|
gocv.Threshold(imgDelta, &imgDelta, 25, 255, gocv.ThresholdBinary)
|
||||||
|
|
||||||
|
// Remove noise.
|
||||||
|
gocv.Erode(imgDelta, &imgDelta, m.knl)
|
||||||
|
gocv.Dilate(imgDelta, &imgDelta, m.knl)
|
||||||
|
|
||||||
|
// Fill small holes.
|
||||||
|
gocv.Dilate(imgDelta, &imgDelta, m.knl)
|
||||||
|
gocv.Erode(imgDelta, &imgDelta, m.knl)
|
||||||
|
|
||||||
|
// Find contours and reject ones with a small area.
|
||||||
|
var contours [][]image.Point
|
||||||
|
allContours := gocv.FindContours(imgDelta, gocv.RetrievalExternal, gocv.ChainApproxSimple)
|
||||||
|
for _, c := range allContours {
|
||||||
|
if gocv.ContourArea(c) > m.area {
|
||||||
|
contours = append(contours, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw debug information.
|
||||||
|
if m.debug {
|
||||||
|
for _, c := range contours {
|
||||||
|
rect := gocv.BoundingRect(c)
|
||||||
|
gocv.Rectangle(&img, rect, color.RGBA{0, 0, 255, 0}, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(contours) > 0 {
|
||||||
|
gocv.PutText(&img, "Motion", image.Pt(32, 32), gocv.FontHersheyPlain, 2.0, color.RGBA{255, 0, 0, 0}, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.windows[0].IMShow(img)
|
||||||
|
m.windows[1].IMShow(imgDelta)
|
||||||
|
m.windows[0].WaitKey(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't write to destination if there is no motion.
|
||||||
|
if len(contours) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to destination, past 4 frames then current frame.
|
||||||
|
for i, h := range m.hold {
|
||||||
|
_, err := m.dst.Write(h)
|
||||||
|
m.hold[i] = nil
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.dst.Write(f)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue