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
|
||||
hfCount++
|
||||
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