Skip to content

Commit

Permalink
Updated within-code function documentation for readability
Browse files Browse the repository at this point in the history
  • Loading branch information
jakewilliami committed Aug 25, 2020
1 parent c87f50b commit f1f5b5e
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 99 deletions.
6 changes: 3 additions & 3 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ done


main() {
setupWD
checkPackages
obtainDataset1
# setupWD
# checkPackages
# obtainDataset1
obtainDataset2
}

Expand Down
44 changes: 30 additions & 14 deletions src/Adaboost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,18 @@ include("HaarLikeFeature.jl")


function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassifiers::Int64=-1, minFeatureWidth::Int64=1, maxFeatureWidth::Int64=-1, minFeatureHeight::Int64=1, maxFeatureHeight::Int64=-1)
"""
Selects a set of classifiers. Iteratively takes the best classifiers based
on a weighted error.
:param positive_iis: List of positive integral image examples
:type positive_iis: list[numpy.ndarray]
:param negative_iis: List of negative integral image examples
:type negative_iis: list[numpy.ndarray]
:param num_classifiers: Number of classifiers to select, -1 will use all
classifiers
:type num_classifiers: int
:return: List of selected features
:rtype: list[violajones.HaarLikeFeature.HaarLikeFeature]
"""
#=
The boosting algorithm for learning a query online. $T$ hypotheses are constructed, each using a single feature. The final hypothesis is a weighted linear combination of the $T$ hypotheses, where the weights are inverselt proportional to the training errors.
This function selects a set of classifiers. Iteratively takes the best classifiers based on a weighted error.
parameter `positiveIIs`: List of positive integral image examples [type: Abstracy Array]
parameter `negativeIIs`: List of negative integral image examples [type: Abstract Array]
parameter `numClassifiers`: Number of classifiers to select. -1 will use all
classifiers [type: Integer]
return `classifiers`: List of selected features [type: HaarLikeFeature]
=#

numPos = length(positiveIIs)
numNeg = length(negativeIIs)
global numImgs = numPos + numNeg
Expand Down Expand Up @@ -61,6 +60,7 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi
The series of `deep*` functions——though useful in general——were designed from awkward arrays of tuples of arrays, which came about from a translation error in this case.
=#
weights = vcat(posWeights, negWeights)
# println(weights)
# weights = vcat(posWeights, negWeights)
# weights = hcat((posWeights, negWeights))
# weights = vcat([posWeights, negWeights])
Expand All @@ -86,6 +86,7 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi

# bar = progressbar.ProgressBar()
# @everywhere numImgs begin
# println(votes)
@everywhere begin
n = numImgs
processes = length(numImgs)
Expand All @@ -107,7 +108,7 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi

n = numClassifiers
p = Progress(n, 1) # minimum update interval: 1 second
for i in processes
for _ in processes
# println(typeof(length(featureIndices)))
classificationErrors = zeros(length(featureIndices))

Expand Down Expand Up @@ -139,6 +140,8 @@ function learn(positiveIIs::AbstractArray, negativeIIs::AbstractArray, numClassi
bestError = classificationErrors[minErrorIDX]
bestFeatureIDX = featureIndices[minErrorIDX]

# println(classificationErrors)
# println(weights)
# set feature weight
bestFeature = features[bestFeatureIDX]
featureWeight = 0.5 * log((1 - bestError) / bestError)
Expand Down Expand Up @@ -173,6 +176,19 @@ end


function _create_features(imgHeight::Int64, imgWidth::Int64, minFeatureWidth::Int64, maxFeatureWidth::Int64, minFeatureHeight::Int64, maxFeatureHeight::Int64)
#=
Iteratively creates the Haar-like feautures
parameter `imgHeight`: The height of the image [type: Integer]
parameter `imgWidth`: The width of the image [type: Integer]
parameter `minFeatureWidth`: The minimum width of the feature (used for computation efficiency purposes) [type: Integer]
parameter `maxFeatureWidth`: The maximum width of the feature [type: Integer]
parameter `minFeatureHeight`: The minimum height of the feature [type: Integer]
parameter `maxFeatureHeight`: The maximum height of the feature [type: Integer]
return `features`: an array of Haar-like features found for an image [type: Abstract Array]
=#

println("Creating Haar-like features...")
# features = Array()
features = []
Expand Down
39 changes: 26 additions & 13 deletions src/HaarLikeFeature.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ abstract type HaarFeatureType end

# make structure
struct HaarLikeFeature <: HaarFeatureType#struct HaarLikeFeature{T} <: HaarObject where {T <: HaarFeatureType}
#=
Struct representing a Haar-like feature.
=#

featureType::Tuple{Int64, Int64}
position::Tuple{Int64, Int64}
topLeft::Tuple{Int64, Int64}
Expand All @@ -32,6 +36,8 @@ struct HaarLikeFeature <: HaarFeatureType#struct HaarLikeFeature{T} <: HaarObjec
threshold::Int64
polarity::Int64
weight::Number# number because it can be -Inf due to log(0)
# weight::Int64
# weight::Any

# constructor; equivalent of __init__ method within class # ::CartesianIndex
function HaarLikeFeature(featureType::Tuple{Int64,Int64}, position::Tuple{Int64, Int64}, width::Int64, height::Int64, threshold::Int64, polarity::Int64)
Expand Down Expand Up @@ -108,13 +114,15 @@ end # end structure
# end

function getScore(feature::HaarLikeFeature, intImg::Array)
"""
#=
Get score for given integral image array.
:param int_img: Integral image array
:type int_img: numpy.ndarray
:return: Score for given feature
:rtype: float
"""
parameter `feature`: given Haar-like feature (parameterised replacement of Python's `self`) [type: HaarLikeFeature]
parameter `intImg`: Integral image array [type: Abstract Array]
return `score`: Score for given feature [type: Float]
=#

score = 0

if feature.featureType == FeatureTypes[1] # two vertical
Expand Down Expand Up @@ -187,20 +195,25 @@ end


function getVote(feature::HaarLikeFeature, intImg::AbstractArray)
"""
#=
Get vote of this feature for given integral image.
:param int_img: Integral image array
:type int_img: numpy.ndarray
:return: 1 iff this feature votes positively, otherwise -1
:rtype: int
"""
parameter `feature`: given Haar-like feature (parameterised replacement of Python's `self`) [type: HaarLikeFeature]
parameter `intImg`: Integral image array [type: Abstract Array]
return:
1 ⟺ this feature votes positively
-1 otherwise
[type: Integer]
=#

score = getScore(feature, intImg)


# return feature.weight * (1 if score < feature.polarity * feature.threshold else -1)


return feature.weight * ((score < (feature.polarity * feature.threshold)) ? 1 : -1)
# return 1 * ((score < (feature.polarity * feature.threshold)) ? 1 : -1)
end


Expand Down
32 changes: 21 additions & 11 deletions src/IntegralImage.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,26 @@
"${BASH_SOURCE[0]}" "$@"
=#

"""
Any one pixel in a given image has the value that is the sum of all of the pixels above it and to the left.
#=
Rectangle features can be computed very rapidly using an intermediate representation for the image, which we call the integral image.
The integral image at location $x,y$ contains the sum of the pixels above and to the left of $x,y$ inclusive.
Original Integral
+-------- +------------
| 1 2 3 . | 1 3 6 .
| 4 5 6 . | 5 12 21 .
| . . . . | . . . . .
"""
=#

function toIntegralImage(imgArr::AbstractArray)
"""
#=
Calculates the integral image based on this instance's original image data.
parameter `imgArr`: Image source data [type: Abstract Array]
return `integralImageArr`: Integral image for given image [type: Abstract Array]
https://www.ipol.im/pub/art/2014/57/article_lr.pdf, p. 346
"""
=#

arrRows, arrCols = size(imgArr) # get size only once in case
rowSum = zeros(arrRows, arrCols)
Expand Down Expand Up @@ -62,12 +69,15 @@ end


function sumRegion(integralImageArr::AbstractArray, topLeft::Tuple{Int64,Int64}, bottomRight::Tuple{Int64,Int64})
"""
Calculates the sum in the rectangle specified by the given tuples
topLeft: (x, y) of the rectangle's top left corner
bottomRight: (x, y) of the rectangle's bottom right corner
return The sum of all pixels in the given rectangle
"""
#=
parameter `integralImageArr`: The intermediate Integral Image [type: Abstract Array]
Calculates the sum in the rectangle specified by the given tuples:
parameter `topLeft`: (x,y) of the rectangle's top left corner [type: Tuple]
parameter `bottomRight`: (x,y) of the rectangle's bottom right corner [type: Tuple]
return: The sum of all pixels in the given rectangle defined by the parameters topLeft and bottomRight
=#

# swap tuples
# topLeft = [topLeft[2], topLeft[1]]
topLeft = (topLeft[2], topLeft[1])
Expand Down
Loading

0 comments on commit f1f5b5e

Please sign in to comment.