diff --git a/turbidity/main.go b/turbidity/main.go index f43f375f..fedc49b3 100644 --- a/turbidity/main.go +++ b/turbidity/main.go @@ -34,14 +34,13 @@ func main() { } // Create turbidity sensor. - ts := TurbiditySensor{template: template, standard: standard, k1: 90, k2: 90, scale: 5.0, alpha: 1.0} + ts := TurbiditySensor{template: template, standard: standard, k1: 8, k2: 8, sobelFilterSize: 3, scale: 1.0, alpha: 1.0} var finalRes Results finalRes.new(nImages) // 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 { @@ -49,7 +48,7 @@ func main() { } // Add the average result from camera burst. - finalRes.update(average(sample_result.saturation), average(sample_result.contrast), float64(i*10), i) + finalRes.update(average(sample_result.saturation), average(sample_result.contrast), float64(i)*2.5, i) } // Plot the final results. @@ -106,12 +105,12 @@ func plotResults(x, saturation, contrast []float64) error { err := plotToFile( "Results", - "Turbidity (Almond Milk) (ml)", + "Almond Milk (ml)", "Score", func(p *plot.Plot) error { return plotutil.AddLinePoints(p, - "AMEE", plotterXY(x, contrast), - "EME", plotterXY(x, saturation), + "Contrast", plotterXY(x, contrast), + "Saturation", plotterXY(x, saturation), ) }, ) diff --git a/turbidity/turbidity.go b/turbidity/turbidity.go index e7708aad..c065eef6 100644 --- a/turbidity/turbidity.go +++ b/turbidity/turbidity.go @@ -11,9 +11,9 @@ import ( // Turbidity Sensor. type TurbiditySensor struct { - template, standard gocv.Mat - k1, k2 int //block size - alpha, scale float64 + template, standard gocv.Mat + k1, k2, sobelFilterSize int + alpha, scale float64 } // Given a slice of test images, return the sharpness and contrast scores. @@ -31,46 +31,43 @@ func (ts TurbiditySensor) Evaluate(imgs []gocv.Mat) (Results, error) { } // Apply sobel filter. - edge := ts.Sobel(marker, ts.scale) - - gocv.IMWrite("marker.jpg", marker) - gocv.IMWrite("edge.jpg", edge) + edge := ts.Sobel(marker) // Evaluate image. - out, err := ts.EvaluateImage(marker, edge, ts.k1, ts.k2, ts.alpha) + scores, err := ts.EvaluateImage(marker, edge) if err != nil { return result, err } - result.update(out[0], out[1], float64(i*10), i) + result.update(scores[0], scores[1], float64(i*10), i) } return result, nil } // Evaluate image sharpness and contrast using blocks of size k1 by k2. Return a slice of the respective scores. -func (ts TurbiditySensor) EvaluateImage(img, edge gocv.Mat, k1, k2 int, alpha float64) ([]float64, error) { +func (ts TurbiditySensor) EvaluateImage(img, edge gocv.Mat) ([]float64, error) { result := make([]float64, 2) // [0.0, 0.0] - if img.Rows()%k1 != 0 || img.Cols()%k2 != 0 { - return nil, fmt.Errorf("Dimensions not compatible (%v, %v)", k1, k2) + if img.Rows()%ts.k1 != 0 || img.Cols()%ts.k2 != 0 { + return nil, fmt.Errorf("Dimensions not compatible (%v, %v)", ts.k1, ts.k2) } - lStep := int(img.Rows() / k1) - kStep := int(img.Cols() / k2) + lStep := int(img.Rows() / ts.k1) + kStep := int(img.Cols() / ts.k2) for l := 0; l < img.Rows(); l = l + lStep { for k := 0; k < img.Cols(); k = k + kStep { // Enhancement Measure Estimation (EME), provides a measure of the sharpness. - err := ts.EvaluateBlock(edge, l, k, l+lStep, k+kStep, result, "EME", alpha) + err := ts.EvaluateBlock(edge, l, k, l+lStep, k+kStep, result, "EME", ts.alpha) if err != nil { return nil, err } // AMEE, provides a measure of the contrast. - err = ts.EvaluateBlock(img, l, k, l+lStep, k+kStep, result, "AMEE", alpha) + err = ts.EvaluateBlock(img, l, k, l+lStep, k+kStep, result, "AMEE", ts.alpha) if err != nil { return nil, err } @@ -78,22 +75,22 @@ func (ts TurbiditySensor) EvaluateImage(img, edge gocv.Mat, k1, k2 int, alpha fl } // EME. - result[0] = 2.0 / (float64(k1) * float64(k2)) * result[0] + result[0] = 2.0 / (float64(ts.k1) * float64(ts.k2)) * result[0] // AMEE. - result[1] = -1.0 / (float64(k1) * float64(k2)) * result[1] + result[1] = -1.0 / (float64(ts.k1) * float64(ts.k2)) * result[1] return result, nil } // Evaluate a block within an image and add to to the result slice. -func (ts TurbiditySensor) EvaluateBlock(img gocv.Mat, l1, k1, l2, k2 int, result []float64, operation string, alpha float64) error { +func (ts TurbiditySensor) EvaluateBlock(img gocv.Mat, xStart, yStart, xEnd, yEnd int, result []float64, operation string, alpha float64) error { max := -math.MaxFloat64 min := math.MaxFloat64 - for i := l1; i < l2; i++ { - for j := k1; j < k2; j++ { + for i := xStart; i < xEnd; i++ { + for j := yStart; j < yEnd; j++ { value := float64(img.GetUCharAt(i, j)) @@ -150,15 +147,15 @@ func (ts TurbiditySensor) Transform(img gocv.Mat) (gocv.Mat, error) { } // Apply sobel filter to an image with a given scale and return the result. -func (ts TurbiditySensor) Sobel(img gocv.Mat, scale float64) gocv.Mat { +func (ts TurbiditySensor) Sobel(img gocv.Mat) gocv.Mat { dx := gocv.NewMat() dy := gocv.NewMat() sobel := gocv.NewMat() // Apply filter. - gocv.Sobel(img, &dx, gocv.MatTypeCV64F, 0, 1, 3, scale, 0.0, gocv.BorderConstant) - gocv.Sobel(img, &dy, gocv.MatTypeCV64F, 1, 0, 3, scale, 0.0, gocv.BorderConstant) + gocv.Sobel(img, &dx, gocv.MatTypeCV64F, 0, 1, ts.sobelFilterSize, ts.scale, 0.0, gocv.BorderConstant) + gocv.Sobel(img, &dy, gocv.MatTypeCV64F, 1, 0, ts.sobelFilterSize, ts.scale, 0.0, gocv.BorderConstant) // Convert to unsigned. gocv.ConvertScaleAbs(dx, &dx, 1.0, 0.0)