Files
TrafficSpeed/internal/project/frame_analysis.go
Jehiah Czebotar b62fd13263 go modules
2020-04-07 22:00:32 -04:00

95 lines
3.2 KiB
Go

package project
import (
"html/template"
"image"
"log"
"time"
"github.com/jehiah/TrafficSpeed/img/blurimg"
"github.com/jehiah/TrafficSpeed/img/diffimg"
"github.com/jehiah/TrafficSpeed/img/imgutils"
"github.com/jehiah/TrafficSpeed/img/labelimg"
"github.com/nfnt/resize"
)
const analysFrameCount = 60
var analyizeInterval time.Duration = time.Duration(30) * time.Second
type Analyzer struct {
Background *image.RGBA
BWCutoff uint8
BlurRadius int
ContinguousPixels int
MinMass int
}
func (a Analyzer) Positions(src *image.RGBA) []labelimg.Label {
highlight := diffimg.DiffRGBA(src, a.Background, diffimg.SumDifferenceCap)
imgutils.BWClamp(highlight, a.BWCutoff)
highlight = blurimg.Blur(highlight, a.BlurRadius)
detected := labelimg.New(highlight, a.ContinguousPixels, a.MinMass)
return labelimg.Labels(detected)
}
type FrameAnalysis struct {
Timestamp time.Duration `json:"ts"`
Base template.URL `json:"base,omitempty"` // first frame
BaseGif template.URL `json:"base_gif,omitempty"`
Highlight template.URL `json:"highlight,omitempty"` // frame - bg
HighlightGif template.URL `json:"highlight_gif,omitempty"`
Colored template.URL `json:"colored,omitempty"` // detected items in highlight
ColoredGif template.URL `json:"colored_gif,omitempty"`
Positions []labelimg.Label `json:"positions,omitempty"`
images []*image.RGBA
}
func (f FrameAnalysis) NeedsMore() bool {
return len(f.images) < analysFrameCount
}
func (f *FrameAnalysis) Calculate(bg *image.RGBA, blurRadius, contiguousPixels, minMass int, tolerance uint8) {
log.Printf("analysis covering %d frames starting at %s", len(f.images), f.Timestamp)
if len(f.images) == 0 {
return
}
src := f.images[0]
f.Base = dataImg(src, "image/png")
highlight := diffimg.DiffRGBA(src, bg, diffimg.SumDifferenceCap)
f.Highlight = dataImg(highlight, "image/png")
imgutils.BWClamp(highlight, tolerance)
highlight = blurimg.Blur(highlight, blurRadius)
detected := labelimg.New(highlight, contiguousPixels, minMass)
f.Colored = dataImg(detected, "image/png")
f.Positions = labelimg.Labels(detected)
log.Printf("%#v", f.Positions)
// animate 2s of video in 1s (drop 50% of frames)
// ^^ == highlight_gif
log.Printf("animating highlight gif")
var baseGif []image.Image
var highlightGif []image.Image
var coloredGif []image.Image
// bgresize := resize.Thumbnail(550, 200, bg, resize.NearestNeighbor).(*image.RGBA)
for i := 0; i < 60 && i < len(f.images); i += 3 {
im := f.images[i]
baseGif = append(baseGif, resize.Thumbnail(550, 200, im, resize.NearestNeighbor))
detected := diffimg.DiffRGBA(im, bg, diffimg.SumDifferenceCap)
imgutils.BWClamp(detected, tolerance)
detected = blurimg.Blur(detected, blurRadius)
highlightGif = append(highlightGif, resize.Thumbnail(550, 200, detected, resize.NearestNeighbor))
// since operating on a scaled image, we need to scale contiguousPixels and minMass here
colored := labelimg.New(detected, contiguousPixels, minMass)
coloredGif = append(coloredGif, resize.Thumbnail(550, 200, colored, resize.NearestNeighbor))
}
f.BaseGif = dataGif(imgutils.NewGIF(baseGif))
f.HighlightGif = dataGif(imgutils.NewGIF(highlightGif))
f.ColoredGif = dataGif(imgutils.NewGIF(coloredGif))
}