2022-01-12 04:55:58 +03:00
|
|
|
//go:build !nocv
|
|
|
|
// +build !nocv
|
|
|
|
|
2022-01-06 06:25:40 +03:00
|
|
|
/*
|
|
|
|
DESCRIPTION
|
|
|
|
Testing functions for the turbidity sensor using images from
|
|
|
|
previous experiment.
|
|
|
|
|
|
|
|
AUTHORS
|
|
|
|
Russell Stanley <russell@ausocean.org>
|
|
|
|
|
|
|
|
LICENSE
|
2022-01-07 04:10:20 +03:00
|
|
|
Copyright (C) 2021-2022 the Australian Ocean Lab (AusOcean)
|
2022-01-06 06:25:40 +03:00
|
|
|
|
|
|
|
It is free software: you can redistribute it and/or modify them
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
Free Software Foundation, either version 3 of the License, or (at your
|
|
|
|
option) any later version.
|
|
|
|
|
|
|
|
It is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
in gpl.txt. If not, see http://www.gnu.org/licenses.
|
|
|
|
*/
|
|
|
|
|
2022-01-07 04:10:20 +03:00
|
|
|
package turbidity
|
2022-01-06 06:25:40 +03:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2022-02-04 06:16:55 +03:00
|
|
|
"io"
|
2022-01-06 06:25:40 +03:00
|
|
|
"testing"
|
|
|
|
|
2022-05-27 09:12:52 +03:00
|
|
|
"bitbucket.org/ausocean/utils/logging"
|
2022-01-06 06:25:40 +03:00
|
|
|
"gocv.io/x/gocv"
|
2022-01-10 07:41:21 +03:00
|
|
|
"gonum.org/v1/gonum/stat"
|
|
|
|
"gonum.org/v1/plot"
|
|
|
|
"gonum.org/v1/plot/plotutil"
|
2022-02-04 06:16:55 +03:00
|
|
|
"gopkg.in/natefinch/lumberjack.v2"
|
2022-01-06 06:25:40 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2022-04-28 07:13:49 +03:00
|
|
|
nImages = 13 // Number of images to test. (Max 13)
|
2022-04-11 02:53:40 +03:00
|
|
|
nSamples = 10 // Number of samples for each image. (Max 10)
|
2022-01-10 07:41:21 +03:00
|
|
|
increment = 2.5 // Increment of the turbidity level.
|
2022-01-06 06:25:40 +03:00
|
|
|
)
|
|
|
|
|
2022-02-04 06:16:55 +03:00
|
|
|
// Logging configuration.
|
|
|
|
const (
|
|
|
|
logPath = "/var/log/netsender/netsender.log"
|
|
|
|
logMaxSize = 500 // MB
|
|
|
|
logMaxBackup = 10
|
|
|
|
logMaxAge = 28 // days
|
2022-05-27 09:12:52 +03:00
|
|
|
logVerbosity = logging.Info
|
2022-02-04 06:16:55 +03:00
|
|
|
logSuppress = true
|
|
|
|
)
|
|
|
|
|
2022-01-12 04:55:58 +03:00
|
|
|
// TestImages will read a library of test images and calculate the sharpness and contrast scores.
|
|
|
|
// A plot of the results will be generated and stored in the plots directory.
|
2022-01-06 06:25:40 +03:00
|
|
|
func TestImages(t *testing.T) {
|
2022-02-04 06:16:55 +03:00
|
|
|
|
2022-01-07 04:10:20 +03:00
|
|
|
const (
|
2022-04-11 02:53:40 +03:00
|
|
|
k1, k2 = 4, 4
|
2022-01-07 04:10:20 +03:00
|
|
|
filterSize = 3
|
|
|
|
scale, alpha = 1.0, 1.0
|
|
|
|
)
|
|
|
|
|
2022-02-04 06:16:55 +03:00
|
|
|
// Create lumberjack logger.
|
|
|
|
fileLog := &lumberjack.Logger{
|
|
|
|
Filename: logPath,
|
|
|
|
MaxSize: logMaxSize,
|
|
|
|
MaxBackups: logMaxBackup,
|
|
|
|
MaxAge: logMaxAge,
|
|
|
|
}
|
2022-05-27 09:12:52 +03:00
|
|
|
log := logging.New(logVerbosity, io.MultiWriter(fileLog), logSuppress)
|
2022-02-04 06:16:55 +03:00
|
|
|
|
2022-01-06 06:25:40 +03:00
|
|
|
template := gocv.IMRead("images/template.jpg", gocv.IMReadGrayScale)
|
2022-04-28 07:13:49 +03:00
|
|
|
transformMatrix, err := FindTransform("images/default.jpg", "images/template.jpg")
|
2022-04-12 07:02:34 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("could not find transformation: %v", err)
|
|
|
|
}
|
2022-04-28 07:13:49 +03:00
|
|
|
t.Log(formatMat(transformMatrix))
|
2022-01-06 06:25:40 +03:00
|
|
|
|
|
|
|
imgs := make([][]gocv.Mat, nImages)
|
|
|
|
|
|
|
|
// Load test images.
|
|
|
|
for i := range imgs {
|
|
|
|
imgs[i] = make([]gocv.Mat, nSamples)
|
|
|
|
for j := range imgs[i] {
|
2022-04-11 02:53:40 +03:00
|
|
|
imgs[i][j] = gocv.IMRead(fmt.Sprintf("images/t-%v/000%v.jpg", i, j), gocv.IMReadColor)
|
2022-01-06 06:25:40 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-28 07:13:49 +03:00
|
|
|
ts, err := NewTurbiditySensor(template, transformMatrix, k1, k2, filterSize, scale, alpha, log)
|
2022-01-06 06:25:40 +03:00
|
|
|
if err != nil {
|
2022-01-12 04:55:58 +03:00
|
|
|
t.Fatalf("could not create turbidity sensor: %v", err)
|
2022-01-06 06:25:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
results, err := NewResults(nImages)
|
|
|
|
if err != nil {
|
2022-01-12 04:55:58 +03:00
|
|
|
t.Fatalf("could not create results: %v", err)
|
2022-01-06 06:25:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Score each image by calculating the average score from camera burst.
|
|
|
|
for i := range imgs {
|
|
|
|
// Evaluate camera burst.
|
|
|
|
sample_result, err := ts.Evaluate(imgs[i])
|
|
|
|
if err != nil {
|
2022-01-10 02:38:54 +03:00
|
|
|
t.Fatalf("evaluation Failed: %v", err)
|
2022-01-06 06:25:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add the average result from camera burst.
|
2022-01-10 07:41:21 +03:00
|
|
|
results.Update(stat.Mean(sample_result.Sharpness, nil), stat.Mean(sample_result.Contrast, nil), float64(i)*increment, i)
|
2022-01-06 06:25:40 +03:00
|
|
|
}
|
|
|
|
|
2022-04-11 02:53:40 +03:00
|
|
|
err = plotResults(results.Turbidity, normalize(results.Sharpness), normalize(results.Contrast))
|
2022-01-06 06:25:40 +03:00
|
|
|
if err != nil {
|
2022-01-10 02:38:54 +03:00
|
|
|
t.Fatalf("plotting Failed: %v", err)
|
2022-01-06 06:25:40 +03:00
|
|
|
}
|
|
|
|
|
2022-01-07 04:10:20 +03:00
|
|
|
t.Logf("Sharpness: %v", results.Sharpness)
|
2022-01-06 06:25:40 +03:00
|
|
|
t.Logf("Contrast: %v", results.Contrast)
|
|
|
|
}
|
2022-01-10 07:41:21 +03:00
|
|
|
|
2022-01-12 04:55:58 +03:00
|
|
|
// plotResults plots sharpness and contrast scores against the level of almond milk in the container
|
2022-01-10 07:41:21 +03:00
|
|
|
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
|
|
|
|
}
|
2022-04-28 07:13:49 +03:00
|
|
|
|
|
|
|
// formatMat creates a formatted transformation matrix string for use in vidgrind.
|
|
|
|
func formatMat(transformMatrix gocv.Mat) string {
|
|
|
|
var out string
|
|
|
|
for i := 0; i < transformMatrix.Rows(); i++ {
|
|
|
|
for j := 0; j < transformMatrix.Cols(); j++ {
|
|
|
|
out += fmt.Sprintf(" %.10f", transformMatrix.GetDoubleAt(i, j))
|
|
|
|
if i < 2 || j < 2 {
|
|
|
|
out += ","
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|