From 02f6e8e0d91b6eea7ed0077074512dadd78dfd3f Mon Sep 17 00:00:00 2001 From: "Jake W. Ireland" Date: Thu, 27 Aug 2020 00:21:58 +1200 Subject: [PATCH] added beginnings of testing package (touches on good practices regarding #8) --- Manifest.toml | 63 ++++++++++++++++++++++++++++++++++++------ Project.toml | 1 + src/Adaboost.jl | 28 ++++++++++++++++--- src/FDA.jl | 12 +++++++- src/HaarLikeFeature.jl | 3 +- test/runtests.jl | 10 +++++++ 6 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 test/runtests.jl diff --git a/Manifest.toml b/Manifest.toml index f2dd1716b..e7ba0c59f 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -24,6 +24,12 @@ git-tree-sha1 = "fd04049c7dd78cfef0b06cdc1f0f181467655712" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" version = "1.1.0" +[[ArnoldiMethod]] +deps = ["DelimitedFiles", "LinearAlgebra", "Random", "SparseArrays", "StaticArrays", "Test"] +git-tree-sha1 = "2b6845cea546604fb4dca4e31414a6a59d39ddcd" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.0.4" + [[Arpack]] deps = ["Arpack_jll", "Libdl", "LinearAlgebra"] git-tree-sha1 = "2ff92b71ba1747c5fdd541f8fc87736d82f40ec9" @@ -104,6 +110,12 @@ git-tree-sha1 = "e58b3c2d5de62371be393f4019c27e02e7140d19" uuid = "059b0e18-018a-5deb-a5b2-c624ee85784b" version = "0.2.0" +[[Clustering]] +deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "SparseArrays", "Statistics", "StatsBase"] +git-tree-sha1 = "b11c8d607af357776a046889a7c32567d05f1319" +uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5" +version = "0.14.1" + [[CodeTracking]] deps = ["InteractiveUtils", "UUIDs"] git-tree-sha1 = "9c173f62af93cce8af2bd3527d160b6ddd6eaf81" @@ -400,6 +412,12 @@ git-tree-sha1 = "3af30042a8fe85612a6a106cb20ca2fa1eb67bd6" uuid = "2996bd0c-7a13-11e9-2da2-2f5ce47296a9" version = "0.1.4" +[[ImageSegmentation]] +deps = ["Clustering", "DataStructures", "Distances", "ImageFiltering", "Images", "LightGraphs", "LinearAlgebra", "RegionTrees", "SimpleWeightedGraphs", "StaticArrays", "Statistics"] +git-tree-sha1 = "3837584c12ac9170f2431c3423c2df430c386214" +uuid = "80713f31-8817-5129-9cf8-209ff8fb23e1" +version = "1.4.5" + [[ImageShow]] deps = ["Base64", "FileIO", "ImageCore", "Requires"] git-tree-sha1 = "c9df184bc7c2e665f971079174aabb7d18f1845f" @@ -423,6 +441,11 @@ git-tree-sha1 = "c2a145a145dc03a7620af1444e0264ef907bd44f" uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" version = "0.5.1" +[[Inflate]] +git-tree-sha1 = "f5fc07d4e706b84f72d54eedcc1c13d92fb0871c" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.2" + [[IntelOpenMP_jll]] deps = ["Libdl", "Pkg"] git-tree-sha1 = "fb8e1c7a5594ba56f9011310790e03b5384998d6" @@ -463,9 +486,9 @@ version = "0.21.0" [[JpegTurbo_jll]] deps = ["Libdl", "Pkg"] -git-tree-sha1 = "b007cedc10bb017cdae3af0062fe4dd29b483c70" +git-tree-sha1 = "a53414ab7217ae6cc34e41c453339e17a873d169" uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "2.0.1+0" +version = "2.0.1+1" [[Juno]] deps = ["Base64", "Logging", "Media", "Profile"] @@ -492,6 +515,12 @@ git-tree-sha1 = "1fe8c3608dfe7bdec81d018de1cc66e959016e8c" uuid = "89763e89-9b03-5906-acba-b20f662cd828" version = "4.1.0+0" +[[LightGraphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "6f85a35d2377cb2db1bc448ed0d6340d2bb1ea64" +uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" +version = "1.3.3" + [[LinearAlgebra]] deps = ["Libdl"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -552,6 +581,12 @@ git-tree-sha1 = "928b8ca9b2791081dc71a51c55347c27c618760f" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" version = "0.3.3" +[[NearestNeighbors]] +deps = ["Distances", "StaticArrays"] +git-tree-sha1 = "8bc6180f328f3c0ea2663935db880d34c57d6eae" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.4" + [[Netpbm]] deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore"] git-tree-sha1 = "81d9a952ffd2c9146659c8427f36d98202ff4f88" @@ -571,9 +606,9 @@ version = "1.0.4" [[OpenBLAS_jll]] deps = ["CompilerSupportLibraries_jll", "Libdl", "Pkg"] -git-tree-sha1 = "1887096f6897306a4662f7c5af936da7d5d1a062" +git-tree-sha1 = "0c922fd9634e358622e333fc58de61f05a048492" uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.9+4" +version = "0.3.9+5" [[OpenSpecFun_jll]] deps = ["CompilerSupportLibraries_jll", "Libdl", "Pkg"] @@ -670,6 +705,12 @@ git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" uuid = "189a3867-3050-52da-a836-e630ba90ab69" version = "0.2.0" +[[RegionTrees]] +deps = ["IterTools", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "c103368232a786cc6f73480842bc471eb24c8fed" +uuid = "dee08c22-ab7f-5625-9660-a9af2021b33f" +version = "0.3.1" + [[Requires]] deps = ["UUIDs"] git-tree-sha1 = "d37400976e98018ee840e0ca4f9d20baa231dc6b" @@ -710,6 +751,12 @@ git-tree-sha1 = "2ee666b24ab8be6a922f9d6c11a86e1a703a7dda" uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" version = "0.9.2" +[[SimpleWeightedGraphs]] +deps = ["LightGraphs", "LinearAlgebra", "Markdown", "SparseArrays", "Test"] +git-tree-sha1 = "f3f7396c2d5e9d4752357894889a87340262f904" +uuid = "47aef6b3-ad0c-573a-a1e2-d07658019622" +version = "1.1.1" + [[Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" @@ -821,9 +868,9 @@ version = "0.9.2" [[Zlib_jll]] deps = ["Libdl", "Pkg"] -git-tree-sha1 = "a2e0d558f6031002e380a90613b199e37a8565bf" +git-tree-sha1 = "d5bba6485811931e4b8958e2d7ca3738273ac468" uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.11+10" +version = "1.2.11+15" [[Zstd_jll]] deps = ["Libdl", "Pkg"] @@ -845,6 +892,6 @@ version = "0.2.0" [[libpng_jll]] deps = ["Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "594cb058723c13941cf463fd09e5859499594f50" +git-tree-sha1 = "30518225ee32d63d034756bb5d02d782bffaf0e5" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.37+3" +version = "1.6.37+4" diff --git a/Project.toml b/Project.toml index df55ce564..e356da9c8 100644 --- a/Project.toml +++ b/Project.toml @@ -5,6 +5,7 @@ Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" ImageFeatures = "92ff4b2b-8094-53d3-b29d-97f740f06cef" ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +ImageSegmentation = "80713f31-8817-5129-9cf8-209ff8fb23e1" ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0" Netpbm = "f09324ee-3d7c-5217-9330-fc30815ba969" diff --git a/src/Adaboost.jl b/src/Adaboost.jl index b20b378c5..f1586c051 100755 --- a/src/Adaboost.jl +++ b/src/Adaboost.jl @@ -9,7 +9,7 @@ using Distributed # for parallel processing (namely, @everywhere) include("HaarLikeFeature.jl") - +import Base.print_matrix # TODO: select optimal threshold for each feature # TODO: attentional cascading @@ -49,6 +49,7 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi # Initialise weights $w_{1,i} = \frac{1}{2m}, \frac{1}{2l}$, for $y_i=0,1$ for negative and positive examples respectively posWeights = deepfloat(ones(numPos)) / (2 * numPos) negWeights = deepfloat(ones(numNeg)) / (2 * numNeg) + # println(negWeights) #= Consider the original code, ``` @@ -65,19 +66,23 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi # Concatenate positive and negative weights into one `weights` array weights = vcat(posWeights, negWeights) # println(weights) + # print_matrix(stdout, weights) # weights = vcat(posWeights, negWeights) # weights = hcat((posWeights, negWeights)) # weights = vcat([posWeights, negWeights]) # labels = vcat((ones(numPos), ones(numNeg) * -1)) labels = vcat(ones(numPos), ones(numNeg) * -1) + # println(labels) # labels = vcat([ones(numPos), ones(numNeg) * -1]) # get list of images (global because of @everywhere scope) # global images = positiveIIs + negativeIIs global images = vcat(positiveIIs, negativeIIs) + # println(images) # Create features for all sizes and locations global features = _create_features(imgHeight, imgWidth, minFeatureWidth, maxFeatureWidth, minFeatureHeight, maxFeatureHeight) + # [println(f.weight) for f in features] numFeatures = length(features) # feature_indexes = list(range(num_features)) featureIndices = Array(1:numFeatures) @@ -116,8 +121,11 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi n = numClassifiers p = Progress(n, 1) # minimum update interval: 1 second - for t in processes + for t in numClassifiers + # for t in processes # println(typeof(length(featureIndices))) + # print_matrix(stdout, weights) + println(weights) classificationErrors = zeros(length(featureIndices)) # normalize the weights $w_{t,i}\gets \frac{w_{t,i}}{\sum_{j=1}^n w_{t,j}}$ @@ -127,7 +135,11 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi # weights *= 1. / sum(weights) # weights = weights/sum(weights) # weights *= 1. / sum(weights) + # println(weights) + # print_matrix(stdout, weights) weights = deepdiv(deepfloat(weights), deepsum(weights)) + # println(weights) + # print_matrix(stdout, weights) # For each feature j, train a classifier $h_j$ which is restricted to using a single feature. The error is evaluated with respect to $w_j,\varepsilon_j = \sum_i w_i\left|h_j\left(x_i\right)-y_i\right|$ for j in 1:length(featureIndices) @@ -137,6 +149,8 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi # error = sum(imgIDX -> (labels[imgIDX] ≠ votes[imgIDX, fIDX]) ? weights[imgIDX] : 0, 1:numImgs) # error = sum(map(lambda img_idx: weights[img_idx] if labels[img_idx] != votes[img_idx, f_idx] else 0, range(num_imgs))) ε = deepsum(map(imgIDX -> labels[imgIDX] ≠ votes[imgIDX, fIDX] ? weights[imgIDX] : 0, 1:numImgs)) + # println(weights) + # map(imgIDX -> labels[imgIDX] ≠ votes[imgIDX, fIDX] ? println(weights[imgIDX]) : println(0), 1:numImgs) # lambda img_idx: weights[img_idx] if labels[img_idx] != votes[img_idx, f_idx] else 0 # imgIDX -> (labels[imgIDX] ≠ votes[imgIDX, fIDX]) ? weights[imgIDX] : 0 @@ -152,9 +166,10 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi # println(weights) # set feature weight bestFeature = features[bestFeatureIDX] - featureWeight = 0.5 * log((1 - bestError) / bestError) + featureWeight = 0.5 * log((1 - bestError) / bestError) # β # featureWeight = (1 - bestError) / bestError # β # println(typeof(featureWeight)) + # [println(f.weight) for f in features] bestFeature.weight = featureWeight # classifiers = vcat(classifiers, bestFeature) @@ -181,6 +196,7 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi # remove feature (a feature can't be selected twice) # feature_indexes.remove(best_feature_idx) featureIndices = filter!(e -> e ∉ bestFeatureIDX, featureIndices) # note: without unicode operators, `e ∉ [a, b]` is `!(e in [a, b])` + # println(bestFeature) next!(p) end @@ -217,6 +233,7 @@ function _create_features(imgHeight::Int64, imgWidth::Int64, minFeatureWidth::In # features = Array() features = [] + # for feature in FeatureTypes # from HaarLikeFeature.jl # # FeatureTypes are just tuples # println(typeof(feature), " " , feature) @@ -233,8 +250,11 @@ function _create_features(imgHeight::Int64, imgWidth::Int64, minFeatureWidth::In for y in 1:(imgHeight - featureHeight) # println("top left: ", typeof((x, y)), " ", (x, y)) features = push!(features, HaarLikeFeature(feature, (x, y), featureWidth, featureHeight, 0, 1)) + # features = (features..., HaarLikeFeature(feature, (x, y), featureWidth, featureHeight, 0, 1)) # using splatting to add to a tuple. see Utils.partial() features = push!(features, HaarLikeFeature(feature, (x, y), featureWidth, featureHeight, 0, -1)) + # [println(f.weight) for f in features] + # println(HaarLikeFeature(feature, (x, y), featureWidth, featureHeight, 0, 1).weight) # features = (features..., HaarLikeFeature(feature, (x, y), featureWidth, featureHeight, 0, -1)) # feature.append(HaarLikeFeature...) end # end for y @@ -244,7 +264,7 @@ function _create_features(imgHeight::Int64, imgWidth::Int64, minFeatureWidth::In end # end for feature in feature types # println("...finished processing; ", length(features), " features created.") - + # [println(f.weight) for f in features] return features end diff --git a/src/FDA.jl b/src/FDA.jl index 8823316c5..48db71121 100755 --- a/src/FDA.jl +++ b/src/FDA.jl @@ -41,6 +41,7 @@ function main(alt::Bool=false) maxFeatureWidth = 10 + ### TRAINING PROCESS println("Loading faces...") facesTraining = loadImages(posTrainingPath) @@ -96,7 +97,16 @@ function main(alt::Bool=false) # recon.save("/Users/jakeireland/Desktop/reconstruction.png") # println(reconstructedImage) - save("/Users/jakeireland/Desktop/reconstruction.png", colorview(Gray, reconstructedImage)) + # save("/Users/jakeireland/Desktop/reconstruction.png", colorview(Gray, map(clamp01nan, reconstructedImage))) + # save("/Users/jakeireland/Desktop/reconstruction.png", reconstructedImage) + # readblob(reconstructedImage, "/Users/jakeireland/Desktop/reconstruction.png") + + # save("/Users/jakeireland/Desktop/reconstruction.png", reconstructedImage) + save("/Users/jakeireland/Desktop/reconstruction.png", Gray.(map(clamp01nan, reconstructedImage))) + # save("/Users/jakeireland/Desktop/reconstruction.png", Gray.(reconstructedImage ./ 255)) + # println(channelview(reconstructedImage)) + # colorview(Gray, reconstructedImage) + end diff --git a/src/HaarLikeFeature.jl b/src/HaarLikeFeature.jl index 1b445d15c..abb4f05ae 100755 --- a/src/HaarLikeFeature.jl +++ b/src/HaarLikeFeature.jl @@ -44,8 +44,9 @@ mutable struct HaarLikeFeature <: HaarFeatureType#struct HaarLikeFeature{T} <: H topLeft = position bottomRight = (position[1] + width, position[2] + height) weight = 1 + # println(weight) - new(featureType, position, topLeft, bottomRight, width, height, threshold, polarity) + new(featureType, position, topLeft, bottomRight, width, height, threshold, polarity, weight) end # end constructor end # end structure diff --git a/test/runtests.jl b/test/runtests.jl new file mode 100644 index 000000000..901207861 --- /dev/null +++ b/test/runtests.jl @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + #= + exec julia --project="~/FaceDetection.jl/" "${BASH_SOURCE[0]}" "$@" -e "include(popfirst!(ARGS))" \ + "${BASH_SOURCE[0]}" "$@" + =# + +using Test +using FaceDetection + +# @test ... == ... \ No newline at end of file