improved corner detection in transform function, fixed some comments

This commit is contained in:
Russell Stanley 2022-01-06 14:41:35 +10:30
parent 2ec62db850
commit 77c803e4bd
3 changed files with 29 additions and 25 deletions

View File

@ -29,14 +29,14 @@ package main
import "fmt"
// Struct to hold the results of the turbidity sensor.
// Results holds the results of the turbidity sensor.
type Results struct {
Turbidity []float64
Saturation []float64
Contrast []float64
}
// Results constructor
// NewResults constructs the results object.
func NewResults(n int) (*Results, error) {
if n <= 0 {
@ -51,7 +51,7 @@ func NewResults(n int) (*Results, error) {
return r, nil
}
// Update results to add new values at specified index.
// Update adds new values to slice at specified index.
func (r *Results) Update(newSat, newCont, newTurb float64, index int) {
r.Saturation[index] = newSat
r.Contrast[index] = newCont

View File

@ -40,24 +40,37 @@ import (
// TurbiditySensor is a software based turbidity sensor that uses CV to determine saturation and constrast level
// of a chessboard-like target submerged in water that can be correlated to turbidity/visibility values.
type TurbiditySensor struct {
template, standard gocv.Mat
template, templateCorners gocv.Mat
standard, standardCorners gocv.Mat
k1, k2, sobelFilterSize int
scale, alpha float64
}
// Turbidity sensor constructor.
// NewTurbiditySensor constructor for a turbidity sensor.
func NewTurbiditySensor(template, standard gocv.Mat, k1, k2, sobelFilterSize int, scale, alpha float64) (*TurbiditySensor, error) {
ts := new(TurbiditySensor)
templateCorners := gocv.NewMat()
standardCorners := gocv.NewMat()
// Validate template image is not empty and has valid corners.
if template.Empty() {
return nil, errors.New("template image is empty.")
}
if !gocv.FindChessboardCorners(template, image.Pt(3, 3), &templateCorners, gocv.CalibCBNormalizeImage) {
return nil, errors.New("could not find corners in template image")
}
ts.template = template
ts.templateCorners = templateCorners
// Validate standard image is not empty and has valid corners.
if standard.Empty() {
return nil, errors.New("standard image is empty.")
}
if !gocv.FindChessboardCorners(standard, image.Pt(3, 3), &standardCorners, gocv.CalibCBNormalizeImage) {
return nil, errors.New("could not find corners in standard image")
}
ts.standard = standard
ts.standardCorners = standardCorners
ts.k1, ts.k2, ts.sobelFilterSize = k1, k2, sobelFilterSize
ts.alpha, ts.scale = alpha, scale
@ -127,6 +140,7 @@ func (ts TurbiditySensor) EvaluateImage(img, edge gocv.Mat) (float64, float64, e
return sharpness, contrast, nil
}
// minMax returns the max and min pixel values of an image block.
func (ts TurbiditySensor) minMax(img gocv.Mat, xStart, yStart, xEnd, yEnd int) (float64, float64) {
max := -math.MaxFloat64
min := math.MaxFloat64
@ -147,7 +161,7 @@ func (ts TurbiditySensor) minMax(img gocv.Mat, xStart, yStart, xEnd, yEnd int) (
return max, min
}
// Evaluate a block within an image and return the value to be added to the sharpness result.
// evaluateBlockEME will evaluate an image block and return the value to be added to the sharpness result.
func (ts TurbiditySensor) evaluateBlockEME(img gocv.Mat, xStart, yStart, xEnd, yEnd int) float64 {
max, min := ts.minMax(img, xStart, yStart, xEnd, yEnd)
@ -158,7 +172,7 @@ func (ts TurbiditySensor) evaluateBlockEME(img gocv.Mat, xStart, yStart, xEnd, y
return 0.0
}
// Evaluate a block within an image and return the value to be added to the contrast result.
// evaluateBlockAMEE will evaluate an image block and return the value to be added to the contrast result.
func (ts TurbiditySensor) evaluateBlockAMEE(img gocv.Mat, xStart, yStart, xEnd, yEnd int) float64 {
max, min := ts.minMax(img, xStart, yStart, xEnd, yEnd)
@ -174,29 +188,19 @@ func (ts TurbiditySensor) evaluateBlockAMEE(img gocv.Mat, xStart, yStart, xEnd,
func (ts TurbiditySensor) transform(img gocv.Mat) (gocv.Mat, error) {
out := gocv.NewMat()
mask := gocv.NewMat()
corners_img := gocv.NewMat()
corners_template := gocv.NewMat()
imgCorners := gocv.NewMat()
// Check image is valid.
if img.Empty() {
return out, errors.New("image is empty, cannot transform")
}
// Find corners in image.
if !gocv.FindChessboardCorners(img, image.Pt(3, 3), &corners_img, gocv.CalibCBNormalizeImage) {
// Apply default if transformation fails.
if !gocv.FindChessboardCorners(ts.standard, image.Pt(3, 3), &corners_img, gocv.CalibCBNormalizeImage) {
return out, errors.New("Could not find corners in default image")
}
}
// Find corners in template.
if !gocv.FindChessboardCorners(ts.template, image.Pt(3, 3), &corners_template, gocv.CalibCBNormalizeImage) {
return out, errors.New("Could not find corners in template")
// Check image for corners, if non can be found corners will be set to default value.
if !gocv.FindChessboardCorners(img, image.Pt(3, 3), &imgCorners, gocv.CalibCBFastCheck) {
imgCorners = ts.standardCorners
}
// Find and apply transformation.
H := gocv.FindHomography(corners_img, &corners_template, gocv.HomograpyMethodRANSAC, 3.0, &mask, 2000, 0.995)
H := gocv.FindHomography(imgCorners, &ts.templateCorners, gocv.HomograpyMethodRANSAC, 3.0, &mask, 2000, 0.995)
gocv.WarpPerspective(img, &out, H, image.Pt(ts.template.Rows(), ts.template.Cols()))
return out, nil

View File

@ -59,7 +59,7 @@ func TestImages(t *testing.T) {
t.Fatal(err)
}
// Create results
// Create results.
results, err := NewResults(nImages)
if err != nil {
t.Fatal(err)