diff --git a/core/flploc_test.go b/core/flploc_test.go index 563180b..ad59347 100644 --- a/core/flploc_test.go +++ b/core/flploc_test.go @@ -3,6 +3,7 @@ package pigo_test import ( "io/ioutil" "log" + "runtime" "testing" pigo "github.com/esimov/pigo/core" @@ -159,7 +160,37 @@ func TestFlploc_LandmarkDetectorShouldReturnCorrectDetectionPoints(t *testing.T) } } -func BenchmarkFlploc(b *testing.B) { +func BenchmarkFlplocReadCascadeDir(b *testing.B) { + for i := 0; i < b.N; i++ { + plc.ReadCascadeDir("../cascade/lps/") + } +} + +func BenchmarkFlplocGetLendmarkPoint(b *testing.B) { + pl := pigo.PuplocCascade{} + plc, err := pl.UnpackCascade(puplocCascade) + if err != nil { + b.Fatalf("error reading the cascade file: %s", err) + } + + pixs := pigo.RgbToGrayscale(srcImg) + cParams.Pixels = pixs + + flploc := &pigo.Puploc{Row: 10, Col: 10, Scale: 20, Perturbs: 50} + // For benchmarking we are using common values for left and right eye. + puploc := plc.RunDetector(*flploc, *imgParams, 0.0, false) + + b.ResetTimer() + runtime.GC() + + for i := 0; i < b.N; i++ { + plc.GetLandmarkPoint(puploc, puploc, *imgParams, 63, false) + } +} + +func BenchmarkFlplocDetection(b *testing.B) { + var faces []pigo.Detection + pg := pigo.NewPigo() // Unpack the binary file. This will return the number of cascade trees, // the tree depth, the threshold and the prediction from tree's leaf nodes. @@ -174,19 +205,19 @@ func BenchmarkFlploc(b *testing.B) { b.Fatalf("error reading the cascade file: %s", err) } - var faces []pigo.Detection + pixs := pigo.RgbToGrayscale(srcImg) + cParams.Pixels = pixs b.ResetTimer() + runtime.GC() + + // Run the classifier over the obtained leaf nodes and return the detection results. + // The result contains quadruplets representing the row, column, scale and detection score. + faces = classifier.RunCascade(*cParams, 0.0) + // Calculate the intersection over union (IoU) of two clusters. + faces = classifier.ClusterDetections(faces, 0.1) for i := 0; i < b.N; i++ { - pixs := pigo.RgbToGrayscale(srcImg) - cParams.Pixels = pixs - // Run the classifier over the obtained leaf nodes and return the detection results. - // The result contains quadruplets representing the row, column, scale and detection score. - faces = classifier.RunCascade(*cParams, 0.0) - // Calculate the intersection over union (IoU) of two clusters. - faces = classifier.ClusterDetections(faces, 0.1) - for _, face := range faces { if face.Scale > 50 { // left eye diff --git a/core/pigo_test.go b/core/pigo_test.go index f39b1d3..09e5fc2 100644 --- a/core/pigo_test.go +++ b/core/pigo_test.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "log" "path/filepath" + "runtime" "testing" pigo "github.com/esimov/pigo/core" @@ -68,43 +69,82 @@ func TestPigo_InputImageShouldBeGrayscale(t *testing.T) { } func TestPigo_Detector_ShouldDetectFace(t *testing.T) { - // Unpack the binary file. This will return the number of cascade trees, + // Unpack the facefinder binary cascade file. This will return the number of cascade trees, // the tree depth, the threshold and the prediction from tree's leaf nodes. - classifier, err := p.Unpack(pigoCascade) + p, err := p.Unpack(pigoCascade) if err != nil { t.Fatalf("error reading the cascade file: %s", err) } // Run the classifier over the obtained leaf nodes and return the detection results. // The result contains quadruplets representing the row, column, scale and detection score. - faces := classifier.RunCascade(*cParams, 0.0) + faces := p.RunCascade(*cParams, 0.0) // Calculate the intersection over union (IoU) of two clusters. - faces = classifier.ClusterDetections(faces, 0.1) + faces = p.ClusterDetections(faces, 0.1) if len(faces) == 0 { t.Fatalf("face should've been detected") } } -func BenchmarkPigo(b *testing.B) { +func BenchmarkPigoUnpackCascade(b *testing.B) { pg := pigo.NewPigo() - // Unpack the binary file. This will return the number of cascade trees, - // the tree depth, the threshold and the prediction from tree's leaf nodes. - classifier, err := pg.Unpack(pigoCascade) - if err != nil { - log.Fatalf("Error reading the cascade file: %s", err) - } - - var dets []pigo.Detection - b.ResetTimer() for i := 0; i < b.N; i++ { - pixs := pigo.RgbToGrayscale(srcImg) - cParams.Pixels = pixs + // Unpack the facefinder binary cascade file. + _, err := pg.Unpack(pigoCascade) + if err != nil { + log.Fatalf("error reading the cascade file: %s", err) + } + } +} + +func BenchmarkPigoFaceDetection(b *testing.B) { + var dets []pigo.Detection + + pg := pigo.NewPigo() + p, err := pg.Unpack(pigoCascade) + if err != nil { + log.Fatalf("error reading the cascade file: %s", err) + } + + pixs := pigo.RgbToGrayscale(srcImg) + cParams.Pixels = pixs + + b.ResetTimer() + runtime.GC() + + for i := 0; i < b.N; i++ { // Run the classifier over the obtained leaf nodes and return the detection results. // The result contains quadruplets representing the row, column, scale and detection score. - dets = classifier.RunCascade(*cParams, 0.0) + dets = p.RunCascade(*cParams, 0.0) // Calculate the intersection over union (IoU) of two clusters. - dets = classifier.ClusterDetections(dets, 0.1) + dets = p.ClusterDetections(dets, 0.1) + } + _ = dets +} + +func BenchmarkPigoClusterDetection(b *testing.B) { + var dets []pigo.Detection + + pg := pigo.NewPigo() + p, err := pg.Unpack(pigoCascade) + if err != nil { + log.Fatalf("error reading the cascade file: %s", err) + } + + pixs := pigo.RgbToGrayscale(srcImg) + cParams.Pixels = pixs + + b.ResetTimer() + runtime.GC() + + // Run the classifier over the obtained leaf nodes and return the detection results. + // The result contains quadruplets representing the row, column, scale and detection score. + dets = p.RunCascade(*cParams, 0.0) + + for i := 0; i < b.N; i++ { + // Calculate the intersection over union (IoU) of two clusters. + dets = p.ClusterDetections(dets, 0.1) } _ = dets } diff --git a/core/puploc_test.go b/core/puploc_test.go index 9851f30..dab9f4f 100644 --- a/core/puploc_test.go +++ b/core/puploc_test.go @@ -3,6 +3,7 @@ package pigo_test import ( "io/ioutil" "log" + "runtime" "testing" pigo "github.com/esimov/pigo/core" @@ -36,18 +37,18 @@ func TestPuploc_UnpackCascadeFileShouldNotBeNil(t *testing.T) { func TestPuploc_Detector_ShouldDetectEyes(t *testing.T) { p := pigo.NewPigo() - // Unpack the binary file. This will return the number of cascade trees, + // Unpack the facefinder binary cascade file. This will return the number of cascade trees, // the tree depth, the threshold and the prediction from tree's leaf nodes. - classifier, err := p.Unpack(pigoCascade) + p, err := p.Unpack(pigoCascade) if err != nil { t.Fatalf("error reading the cascade file: %s", err) } // Run the classifier over the obtained leaf nodes and return the detection results. // The result contains quadruplets representing the row, column, scale and detection score. - faces := classifier.RunCascade(*cParams, 0.0) + faces := p.RunCascade(*cParams, 0.0) // Calculate the intersection over union (IoU) of two clusters. - faces = classifier.ClusterDetections(faces, 0.1) + faces = p.ClusterDetections(faces, 0.1) eyes := []pigo.Puploc{} @@ -79,11 +80,50 @@ func TestPuploc_Detector_ShouldDetectEyes(t *testing.T) { } } -func BenchmarkPuploc(b *testing.B) { +func BenchmarkPuplocUnpackCascade(b *testing.B) { pg := pigo.NewPigo() - // Unpack the binary file. This will return the number of cascade trees, - // the tree depth, the threshold and the prediction from tree's leaf nodes. - classifier, err := pg.Unpack(pigoCascade) + + // Unpack the facefinder binary cascade file. + _, err := pg.Unpack(pigoCascade) + if err != nil { + log.Fatalf("error reading the cascade file: %s", err) + } + + b.ResetTimer() + runtime.GC() + + for i := 0; i < b.N; i++ { + pl := pigo.PuplocCascade{} + // Unpack the pupil localization cascade file. + _, err = pl.UnpackCascade(puplocCascade) + if err != nil { + b.Fatalf("error reading the cascade file: %s", err) + } + } +} + +func BenchmarkPuplocDetectorRun(b *testing.B) { + pl := pigo.PuplocCascade{} + + plc, err := pl.UnpackCascade(puplocCascade) + if err != nil { + b.Fatalf("error reading the cascade file: %s", err) + } + + pixs := pigo.RgbToGrayscale(srcImg) + cParams.Pixels = pixs + + puploc := &pigo.Puploc{Row: 10, Col: 10, Scale: 20, Perturbs: 50} + for i := 0; i < b.N; i++ { + plc.RunDetector(*puploc, *imgParams, 0.0, false) + } +} + +func BenchmarkPuplocDetection(b *testing.B) { + var faces []pigo.Detection + + pg := pigo.NewPigo() + p, err := pg.Unpack(pigoCascade) if err != nil { b.Fatalf("error reading the cascade file: %s", err) } @@ -94,19 +134,19 @@ func BenchmarkPuploc(b *testing.B) { b.Fatalf("error reading the cascade file: %s", err) } - var faces []pigo.Detection + pixs := pigo.RgbToGrayscale(srcImg) + cParams.Pixels = pixs b.ResetTimer() + runtime.GC() + + // Run the classifier over the obtained leaf nodes and return the detection results. + // The result contains quadruplets representing the row, column, scale and detection score. + faces = p.RunCascade(*cParams, 0.0) + // Calculate the intersection over union (IoU) of two clusters. + faces = p.ClusterDetections(faces, 0.1) for i := 0; i < b.N; i++ { - pixs := pigo.RgbToGrayscale(srcImg) - cParams.Pixels = pixs - // Run the classifier over the obtained leaf nodes and return the detection results. - // The result contains quadruplets representing the row, column, scale and detection score. - faces = classifier.RunCascade(*cParams, 0.0) - // Calculate the intersection over union (IoU) of two clusters. - faces = classifier.ClusterDetections(faces, 0.1) - for _, face := range faces { if face.Scale > 50 { // left eye