From e7295f8d6b4593c3848f2ad78046964cee1b59b6 Mon Sep 17 00:00:00 2001 From: "Jake W. Ireland" Date: Mon, 28 Sep 2020 21:43:25 +1300 Subject: [PATCH] Added example for serialization to save data (addresses #20) --- examples/Project.toml | 1 + examples/read.jl | 91 +++++++++++++++++++++++++++++++++++++++++++ examples/write.jl | 82 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100755 examples/read.jl create mode 100755 examples/write.jl diff --git a/examples/Project.toml b/examples/Project.toml index 5b257e3cc..21be64b60 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -15,4 +15,5 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" +Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd" diff --git a/examples/read.jl b/examples/read.jl new file mode 100755 index 000000000..fc4f989ee --- /dev/null +++ b/examples/read.jl @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + #= + exec julia --project="$(realpath $(dirname $0))/" "${BASH_SOURCE[0]}" "$@" -e "include(popfirst!(ARGS))" \ + "${BASH_SOURCE[0]}" "$@" + =# + + +#= +Adapted from https://github.com/Simon-Hohberg/Viola-Jones/ +=# + + +println("\033[1;34m===>\033[0;38m\033[1;38m\tLoading required libraries (it will take a moment to precompile if it is your first time doing this)...\033[0;38m") + +include(joinpath(dirname(dirname(@__FILE__)), "src", "FaceDetection.jl")) + +using .FaceDetection +const FD = FaceDetection +using Printf: @printf +using Images: imresize +using Serialization: deserialize + +println("...done") + +function main(; + smart_choose_feats::Bool=false, alt::Bool=false +) + + # we assume that `smart_choose_feats = true` + main_path = dirname(dirname(@__FILE__)) + data_path = joinpath(main_path, "data") + main_image_path = joinpath(main_path, "data", "main") + alt_image_path = joinpath(main_path, "data", "alt") + + if alt + # pos_testing_path = joinpath(alt_image_path, "testing", "pos") + # neg_testing_path = joinpath(homedir(), "Desktop", "Assorted Personal Documents", "Wallpapers copy") + pos_testing_path = joinpath(main_image_path, "testset", "faces")#joinpath(homedir(), "Desktop", "faces")#"$main_image_path/testset/faces/" + neg_testing_path = joinpath(main_image_path, "testset", "non-faces") + else + pos_testing_path = joinpath(main_image_path, "testset", "faces")#joinpath(homedir(), "Desktop", "faces")#"$main_image_path/testset/faces/" + neg_testing_path = joinpath(main_image_path, "testset", "non-faces") + end + + # pos_testing_path = joinpath(data_path, "lizzie-testset", "faces") + # neg_testing_path = joinpath(data_path, "lizzie-testset", "nonfaces") + + if ! isfile(joinpath(dirname(@__FILE__), "data", "haar-like_features")) + error(throw("You do not have a data file. Ensure you run \"write.jl\" to obtain your Haar-like features before running this script/")) + end + + # read classifiers from file + classifiers = deserialize(joinpath(dirname(@__FILE__), "data", "haar-like_features")) + + FD.notify_user("Loading test faces...") + + faces_testing = FD.load_images(pos_testing_path)[1] + # faces_ii_testing = map(FD.to_integral_image, faces_testing) + faces_ii_testing = map(FD.to_integral_image, faces_testing) + println("...done. ", length(faces_testing), " faces loaded.") + + FD.notify_user("Loading test non-faces..") + + non_faces_testing = FD.load_images(neg_testing_path)[1] + non_faces_ii_testing = map(FD.to_integral_image, non_faces_testing) + println("...done. ", length(non_faces_testing), " non-faces loaded.\n") + + FD.notify_user("Testing selected classifiers...") + correct_faces = 0 + correct_non_faces = 0 + + # correct_faces = sum([FD._get_feature_vote(face, classifiers) for face in faces_ii_testing]) + # correct_non_faces = length(non_faces_testing) - sum([FD._get_feature_vote(nonFace, classifiers) for nonFace in non_faces_ii_testing]) + correct_faces = sum(FD.ensemble_vote_all(faces_ii_testing, classifiers)) + correct_non_faces = length(non_faces_testing) - sum(FD.ensemble_vote_all(non_faces_ii_testing, classifiers)) + correct_faces_percent = (float(correct_faces) / length(faces_testing)) * 100 + correct_non_faces_percent = (float(correct_non_faces) / length(non_faces_testing)) * 100 + + faces_frac = string(correct_faces, "/", length(faces_testing)) + faces_percent = string("(", correct_faces_percent, "% of faces were recognised as faces)") + non_faces_frac = string(correct_non_faces, "/", length(non_faces_testing)) + non_faces_percent = string("(", correct_non_faces_percent, "% of non-faces were identified as non-faces)") + + println("...done.\n") + FD.notify_user("Result:\n") + + @printf("%10.9s %10.15s %15s\n", "Faces:", faces_frac, faces_percent) + @printf("%10.9s %10.15s %15s\n\n", "Non-faces:", non_faces_frac, non_faces_percent) +end + +@time main(smart_choose_feats=true, alt=false) diff --git a/examples/write.jl b/examples/write.jl new file mode 100755 index 000000000..95856a07b --- /dev/null +++ b/examples/write.jl @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + #= + exec julia --project="$(realpath $(dirname $0))/" "${BASH_SOURCE[0]}" "$@" -e "include(popfirst!(ARGS))" \ + "${BASH_SOURCE[0]}" "$@" + =# + + +#= +Adapted from https://github.com/Simon-Hohberg/Viola-Jones/ +=# + + +println("\033[1;34m===>\033[0;38m\033[1;38m\tLoading required libraries (it will take a moment to precompile if it is your first time doing this)...\033[0;38m") + +include(joinpath(dirname(dirname(@__FILE__)), "src", "FaceDetection.jl")) + +using .FaceDetection +const FD = FaceDetection +using Printf: @printf +using Images: imresize +using Serialization: serialize + +println("...done") + +function main(; + smart_choose_feats::Bool=false, alt::Bool=false +) + # we assume that `smart_choose_feats = true` + main_path = dirname(dirname(@__FILE__)) + data_path = joinpath(main_path, "data") + main_image_path = joinpath(main_path, "data", "main") + alt_image_path = joinpath(main_path, "data", "alt") + + if alt + pos_training_path = joinpath(alt_image_path, "pos") + neg_training_path = joinpath(alt_image_path, "neg") + else + pos_training_path = joinpath(main_image_path, "trainset", "faces") + neg_training_path = joinpath(main_image_path, "trainset", "non-faces") + end + + # pos_training_path = joinpath(data_path, "lfw-all") + # neg_training_path = joinpath(data_path, "all-non-faces") + + num_classifiers = 10 + + min_size_img = (19, 19) # default for our test dataset + if smart_choose_feats + # For performance reasons restricting feature size + notify_user("Selecting best feature width and height...") + + max_feature_width, max_feature_height, min_feature_height, min_feature_width, min_size_img = determine_feature_size(pos_training_path, neg_training_path) + + println("...done. Maximum feature width selected is $max_feature_width pixels; minimum feature width is $min_feature_width; maximum feature height is $max_feature_height pixels; minimum feature height is $min_feature_height.\n") + else + min_feature_height = 8 + max_feature_height = 10 + min_feature_width = 8 + max_feature_width = 10 + end + + + FD.notify_user("Loading faces...") + + faces_training = FD.load_images(pos_training_path)[1] + faces_ii_training = map(FD.to_integral_image, faces_training) # list(map(...)) + println("...done. ", length(faces_training), " faces loaded.") + + FD.notify_user("Loading non-faces...") + + non_faces_training = FD.load_images(neg_training_path)[1] + non_faces_ii_training = map(FD.to_integral_image, non_faces_training) # list(map(...)) + println("...done. ", length(non_faces_training), " non-faces loaded.\n") + + # classifiers are haar like features + classifiers = FD.learn(faces_ii_training, non_faces_ii_training, num_classifiers, min_feature_height, max_feature_height, min_feature_width, max_feature_width) + + # write classifiers to file + serialize(joinpath(dirname(@__FILE__), "data", "haar-like_features"), classifiers) +end + +@time main(smart_choose_feats=true, alt=false)