diff --git a/.gitignore b/.gitignore index dca4d788c..0fbf54b56 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,10 @@ # miscellaneous local things misc/ figs/ +*.xml +*.m +*.mat +tmp/ # Files generated by invoking Julia with --code-coverage *.jl.cov diff --git a/Project.toml b/Project.toml index 65842f4ad..965510350 100644 --- a/Project.toml +++ b/Project.toml @@ -12,6 +12,7 @@ ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" ImageView = "86fae568-95e7-573e-a6b2-d8a6b900c9ef" Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0" IntegralArrays = "1d092043-8f09-5a30-832f-7509e371ab51" +LightXML = "9c8b4983-aa76-5018-a973-4c85ecc9e179" Netpbm = "f09324ee-3d7c-5217-9330-fc30815ba969" ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" diff --git a/README.md b/README.md index 6a76e0093..114cb8513 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ In an over-simplified manner, the Viola-Jones algorithm has some four stages: - Stacking trains a learning algorithm to combine the predictions of several other learning algorithms. Despite this method being developed at the start of the century, it is blazingly fast compared to some machine learning algorithms, and still widely used. 4. Finally, this algorithm uses [Cascading Classifiers](https://en.wikipedia.org/wiki/Cascading_classifiers) to identify faces. (See page 12 of the original paper for the specific cascade). - + For a better explanation, read [the paper from 2001](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.10.6807), or see [the Wikipedia page](https://en.wikipedia.org/wiki/Viola%E2%80%93Jones_object_detection_framework) on this algorithm. ## Quick Start @@ -90,6 +90,7 @@ Thank you to: - [**Michael Jones**](https://www.merl.com/people/mjones) for (along with [Tirta Susilo](https://people.wgtn.ac.nz/tirta.susilo)) suggesting the method for a *facelike-ness* measure; - [**Mahdi Rezaei**](https://environment.leeds.ac.uk/staff/9408/dr-mahdi-rezaei) for helping me understand the full process of Viola-Jones' object detection; - [**Ying Bi**](https://ecs.wgtn.ac.nz/Main/GradYingBi) for always being happy to answer questions (which mainly turned out to be a lack of programming knowledge rather than conceptual; also with help from [**Bing Xue**](https://homepages.ecs.vuw.ac.nz/~xuebing/index.html)); + - [**Rainer Lienhart**](https://www.uni-augsburg.de/en/fakultaet/fai/informatik/prof/mmc/team/lienhart_eng/) for helping me to understand how OpenCV Haar data is serialised; - **Mr. H. Lockwood** and **Mr. D. Peck** are Comp. Sci. students who have answered a few questions of mine; - Finally, the people in the Julia slack channel, for dealing with many (probably stupid) questions. Just a few who come to mind: Micket, David Sanders, Eric Forgy, Jakob Nissen, and Roel. diff --git a/src/HaarLikeFeature.jl b/src/HaarLikeFeature.jl index 9ef8d8eaa..8ba3230d5 100755 --- a/src/HaarLikeFeature.jl +++ b/src/HaarLikeFeature.jl @@ -12,7 +12,7 @@ abstract type AbstractHaarFeature end mutable struct HaarLikeObject{I <: Integer, F <: AbstractFloat} Struct representing a Haar-like feature. - + feature_type::Tuple{I, I} position::Tuple{I, I} top_left::Tuple{I, I} @@ -31,7 +31,7 @@ mutable struct HaarLikeObject{I <: Integer, F <: AbstractFloat} <: AbstractHaarF bottom_right::Tuple{I, I} width::I height::I - threshold::I + threshold::I # TODO: this should be a float! polarity::I weight::F end # end structure @@ -65,14 +65,14 @@ function HaarLikeObject( top_left = position bottom_right = (first(position) + width, last(position) + height) weight = float(one(p₁)) #to make a float of the same size - + HaarLikeObject(feature_type, position, top_left, bottom_right, width, height, threshold, polarity, weight) end """ get_score(feature::HaarLikeObject, int_img::AbstractArray) -> Tuple{Number, Number} - + Get score for given integral image array. This is the feature cascade. # Arguments @@ -90,7 +90,7 @@ function get_score(feature::HaarLikeObject{I, F}, int_img::IntegralArray{T, N}) _3f = F(3) _half = F(0.5) _one_third = F(1.0 / 3.0) - + if feature.feature_type == FEATURE_TYPES.two_vertical _first = sum_region(int_img, feature.top_left, (first(feature.top_left) + feature.width, round(I, last(feature.top_left) + feature.height / 2))) second = sum_region(int_img, (first(feature.top_left), round(I, last(feature.top_left) + feature.height / 2)), feature.bottom_right) @@ -120,7 +120,7 @@ function get_score(feature::HaarLikeObject{I, F}, int_img::IntegralArray{T, N}) fourth = sum_region(int_img, (round(I, first(feature.top_left) + feature.width / 2), round(I, last(feature.top_left) + feature.height / 2)), feature.bottom_right) score = _first - second - third + fourth end - + return score end diff --git a/src/Read.jl b/src/Read.jl new file mode 100644 index 000000000..e55c944b4 --- /dev/null +++ b/src/Read.jl @@ -0,0 +1,13 @@ +using LightXML + +# Based on: +# https://github.com/BehindTheSciences/Face-Recognition-using-Matlab-and-Sift/blob/fef02a5f9e9fa643cb98d5db7a537be01a214927/ConvertHaarcasadeXMLOpenCV.m +# And: +# https://github.com/aldebaro/ufpa-face-detection/blob/d643708b9c338f4bf2c69f02d948c52f774bbb44/ufd_convertXML.m +# +# Adapted by Jake W. Ireland (November, 2022) +# Originally written by D.Kroon, University of Twente (November, 2010) +# With additional resource from Bruno Ricardo Scherer (February, 2016) +function read_opencv_xml(datafile::AbstractString) + +end