mirror of https://bitbucket.org/ausocean/av.git
added gonum stat library, moved plotResults to test file
This commit is contained in:
parent
07c8d4774a
commit
fea59f4a07
1
go.mod
1
go.mod
|
@ -14,6 +14,7 @@ require (
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e
|
github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e
|
||||||
gocv.io/x/gocv v0.29.0
|
gocv.io/x/gocv v0.29.0
|
||||||
|
gonum.org/v1/gonum v0.9.3
|
||||||
gonum.org/v1/plot v0.10.0
|
gonum.org/v1/plot v0.10.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
)
|
)
|
||||||
|
|
3
go.sum
3
go.sum
|
@ -58,10 +58,8 @@ github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+
|
||||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||||
github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d h1:dPUSr0RGzXAdsUTMtiyQ/2RBLIIwkv6jGnhxrufitvQ=
|
github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d h1:dPUSr0RGzXAdsUTMtiyQ/2RBLIIwkv6jGnhxrufitvQ=
|
||||||
github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d/go.mod h1:ACKj9jnzOzj1lw2ETilpFGK7L9dtJhAzT7T1OhAGtRQ=
|
github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d/go.mod h1:ACKj9jnzOzj1lw2ETilpFGK7L9dtJhAzT7T1OhAGtRQ=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21 h1:Hc1iKlyxNHp3CV59G2E/qabUkHvEwOIJxDK0CJ7CRjA=
|
github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21 h1:Hc1iKlyxNHp3CV59G2E/qabUkHvEwOIJxDK0CJ7CRjA=
|
||||||
github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21/go.mod h1:LlQmBGkOuV/SKzEDXBPKauvN2UqCgzXO2XjecTGj40s=
|
github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21/go.mod h1:LlQmBGkOuV/SKzEDXBPKauvN2UqCgzXO2XjecTGj40s=
|
||||||
|
@ -149,7 +147,6 @@ gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=
|
||||||
gonum.org/v1/plot v0.10.0 h1:ymLukg4XJlQnYUJCp+coQq5M7BsUJFk6XQE4HPflwdw=
|
gonum.org/v1/plot v0.10.0 h1:ymLukg4XJlQnYUJCp+coQq5M7BsUJFk6XQE4HPflwdw=
|
||||||
gonum.org/v1/plot v0.10.0/go.mod h1:JWIHJ7U20drSQb/aDpTetJzfC1KlAPldJLpkSy88dvQ=
|
gonum.org/v1/plot v0.10.0/go.mod h1:JWIHJ7U20drSQb/aDpTetJzfC1KlAPldJLpkSy88dvQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
|
|
|
@ -30,74 +30,35 @@ import (
|
||||||
|
|
||||||
"gonum.org/v1/plot"
|
"gonum.org/v1/plot"
|
||||||
"gonum.org/v1/plot/plotter"
|
"gonum.org/v1/plot/plotter"
|
||||||
"gonum.org/v1/plot/plotutil"
|
|
||||||
"gonum.org/v1/plot/vg"
|
"gonum.org/v1/plot/vg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// standarDeviation will return the standard deviation of a float slice
|
// normalise normalises the values in the given slice to the range [0,1] inclusive.
|
||||||
func standarDeviation(slice []float64) float64 {
|
func normalize(s []float64) []float64 {
|
||||||
mean := average(slice)
|
|
||||||
variance := 0.0
|
|
||||||
|
|
||||||
for _, i := range slice {
|
|
||||||
variance += math.Pow(i-mean, 2.0)
|
|
||||||
}
|
|
||||||
return math.Sqrt(variance / float64(len(slice)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalize values in a slice between 0 and 1.
|
|
||||||
func normalize(slice []float64) []float64 {
|
|
||||||
max := -math.MaxFloat64
|
max := -math.MaxFloat64
|
||||||
min := math.MaxFloat64
|
min := math.MaxFloat64
|
||||||
out := make([]float64, len(slice))
|
out := make([]float64, len(s))
|
||||||
|
|
||||||
if len(slice) <= 1 {
|
if len(s) <= 1 {
|
||||||
return slice
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the max and min values of the slice.
|
// Find the max and min values of the s.
|
||||||
for i := range slice {
|
for i := range s {
|
||||||
if slice[i] > max {
|
if s[i] > max {
|
||||||
max = slice[i]
|
max = s[i]
|
||||||
}
|
}
|
||||||
if slice[i] < min {
|
if s[i] < min {
|
||||||
min = slice[i]
|
min = s[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range slice {
|
for i := range s {
|
||||||
out[i] = (slice[i] - min) / (max - min)
|
out[i] = (s[i] - min) / (max - min)
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the average of a slice.
|
|
||||||
func average(slice []float64) float64 {
|
|
||||||
var out float64
|
|
||||||
for i := range slice {
|
|
||||||
out += slice[i]
|
|
||||||
}
|
|
||||||
return out / float64(len(slice))
|
|
||||||
}
|
|
||||||
|
|
||||||
func plotResults(x, sharpness, contrast []float64) error {
|
|
||||||
err := plotToFile(
|
|
||||||
"Results",
|
|
||||||
"Almond Milk (ml)",
|
|
||||||
"Score",
|
|
||||||
func(p *plot.Plot) error {
|
|
||||||
return plotutil.AddLinePoints(p,
|
|
||||||
"Contrast", plotterXY(x, contrast),
|
|
||||||
"Sharpness", plotterXY(x, sharpness),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not plot results: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// plotToFile creates a plot with a specified name and x&y titles using the
|
// plotToFile creates a plot with a specified name and x&y titles using the
|
||||||
// provided draw function, and then saves to a PNG file with filename of name.
|
// provided draw function, and then saves to a PNG file with filename of name.
|
||||||
func plotToFile(name, xTitle, yTitle string, draw func(*plot.Plot) error) error {
|
func plotToFile(name, xTitle, yTitle string, draw func(*plot.Plot) error) error {
|
||||||
|
|
|
@ -36,7 +36,7 @@ type Results struct {
|
||||||
Contrast []float64
|
Contrast []float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewResults returns a new Results
|
// NewResults returns a new Results.
|
||||||
func NewResults(n int) (*Results, error) {
|
func NewResults(n int) (*Results, error) {
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
return nil, fmt.Errorf("invalid result size: %v", n)
|
return nil, fmt.Errorf("invalid result size: %v", n)
|
||||||
|
|
|
@ -30,12 +30,15 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"gocv.io/x/gocv"
|
"gocv.io/x/gocv"
|
||||||
|
"gonum.org/v1/gonum/stat"
|
||||||
|
"gonum.org/v1/plot"
|
||||||
|
"gonum.org/v1/plot/plotutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
nImages = 13 // Number of images to test. (Max 13)
|
nImages = 13 // Number of images to test. (Max 13)
|
||||||
nSamples = 10 // Number of samples for each image. (Max 10)
|
nSamples = 10 // Number of samples for each image. (Max 10)
|
||||||
increment = 2.5 // Increment of the turbidity level
|
increment = 2.5 // Increment of the turbidity level.
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestImages(t *testing.T) {
|
func TestImages(t *testing.T) {
|
||||||
|
@ -45,7 +48,6 @@ func TestImages(t *testing.T) {
|
||||||
scale, alpha = 1.0, 1.0
|
scale, alpha = 1.0, 1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
// Load template and standard image.
|
|
||||||
template := gocv.IMRead("images/template.jpg", gocv.IMReadGrayScale)
|
template := gocv.IMRead("images/template.jpg", gocv.IMReadGrayScale)
|
||||||
standard := gocv.IMRead("images/default.jpg", gocv.IMReadGrayScale)
|
standard := gocv.IMRead("images/default.jpg", gocv.IMReadGrayScale)
|
||||||
|
|
||||||
|
@ -59,13 +61,11 @@ func TestImages(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create turbidity sensor.
|
|
||||||
ts, err := NewTurbiditySensor(template, standard, k1, k2, filterSize, scale, alpha)
|
ts, err := NewTurbiditySensor(template, standard, k1, k2, filterSize, scale, alpha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("could not create turbidity sensor: %w", err)
|
t.Fatal("could not create turbidity sensor: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create results.
|
|
||||||
results, err := NewResults(nImages)
|
results, err := NewResults(nImages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("could not create results: %w", err)
|
t.Fatal("could not create results: %w", err)
|
||||||
|
@ -80,10 +80,9 @@ func TestImages(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the average result from camera burst.
|
// Add the average result from camera burst.
|
||||||
results.Update(average(sample_result.Sharpness), average(sample_result.Contrast), float64(i)*increment, i)
|
results.Update(stat.Mean(sample_result.Sharpness, nil), stat.Mean(sample_result.Contrast, nil), float64(i)*increment, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plot the final results.
|
|
||||||
err = plotResults(results.Turbidity, normalize(results.Sharpness), normalize(results.Contrast))
|
err = plotResults(results.Turbidity, normalize(results.Sharpness), normalize(results.Contrast))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("plotting Failed: %v", err)
|
t.Fatalf("plotting Failed: %v", err)
|
||||||
|
@ -92,3 +91,21 @@ func TestImages(t *testing.T) {
|
||||||
t.Logf("Sharpness: %v", results.Sharpness)
|
t.Logf("Sharpness: %v", results.Sharpness)
|
||||||
t.Logf("Contrast: %v", results.Contrast)
|
t.Logf("Contrast: %v", results.Contrast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func plotResults(x, sharpness, contrast []float64) error {
|
||||||
|
err := plotToFile(
|
||||||
|
"Results",
|
||||||
|
"Almond Milk (ml)",
|
||||||
|
"Score",
|
||||||
|
func(p *plot.Plot) error {
|
||||||
|
return plotutil.AddLinePoints(p,
|
||||||
|
"Contrast", plotterXY(x, contrast),
|
||||||
|
"Sharpness", plotterXY(x, sharpness),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Could not plot results: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue