Skip to content

Commit

Permalink
Load images one-by-one
Browse files Browse the repository at this point in the history
  • Loading branch information
jakewilliami committed Oct 19, 2020
1 parent 67df2f8 commit e911698
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 83 deletions.
27 changes: 15 additions & 12 deletions examples/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ using Images: imresize
println("...done")

function main(;
smart_choose_feats::Bool=false, alt::Bool=false
smart_choose_feats::Bool=false,
alt::Bool=false
)
include("constants.jl")

Expand All @@ -48,20 +49,22 @@ function main(;
end


FD.notify_user("Loading faces...")
# 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.")

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")
# 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")

# FD.notify_user("Loading training images and obtaining classifiers...")

# 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)
classifiers = FD.learn(pos_training_path, neg_training_path, num_classifiers, min_feature_height, max_feature_height, min_feature_width, max_feature_width)

FD.notify_user("Loading test faces...")

Expand Down
16 changes: 8 additions & 8 deletions examples/main_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"${BASH_SOURCE[0]}" "$@"
=#

# pos_training_path = joinpath(main_image_path, "trainset", "faces")
# neg_training_path = joinpath(main_image_path, "trainset", "non-faces")
# 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")
pos_training_path = joinpath(main_image_path, "trainset", "faces")
neg_training_path = joinpath(main_image_path, "trainset", "non-faces")
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")

pos_training_path = joinpath(data_path, "lfw-all")
neg_training_path = joinpath(data_path, "all-non-faces")
pos_testing_path = joinpath(data_path, "lizzie-testset", "faces")
neg_testing_path = joinpath(data_path, "lizzie-testset", "nonfaces")
# pos_training_path = joinpath(data_path, "lfw-all")
# neg_training_path = joinpath(data_path, "all-non-faces")
# pos_testing_path = joinpath(data_path, "lizzie-testset", "faces")
# neg_testing_path = joinpath(data_path, "lizzie-testset", "nonfaces")
124 changes: 64 additions & 60 deletions src/AdaBoost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,31 @@

# include("HaarLikeFeature.jl")
include("Utils.jl")
include("IntegralImage.jl")

using ProgressMeter: @showprogress


function load_images(image_dir::AbstractString)
files = filter!(f -> ! occursin(r".*\.DS_Store", f), readdir(image_dir, join=true, sort=false))
images = []

for file in files
images = push!(images, get_image_matrix(file))
end

return images, files
end
function get_image_matrix(image_file::AbstractString; scale_up::Bool=true)
img = load(image_file)

img_arr = convert(Array{Float64}, Gray.(img))

return img_arr
end



#=
learn(
positive_iis::AbstractArray,
Expand Down Expand Up @@ -40,21 +63,29 @@ This function selects a set of classifiers. Iteratively takes the best classifie
# Returns `classifiers::Array{HaarLikeObject, 1}`: List of selected features
=#
function learn(
positive_iis::AbstractArray,
negative_iis::AbstractArray,
# positive_iis::AbstractArray,
# negative_iis::AbstractArray,
positive_path::AbstractString,
negative_path::AbstractString,
num_classifiers::Integer=-1,
min_feature_width::Integer=1,
max_feature_width::Integer=-1,
min_feature_height::Integer=1,
max_feature_height::Integer=-1
)#::Array{HaarLikeObject,1}
)::Array{HaarLikeObject,1}
# get number of positive and negative images (and create a global variable of the total number of images——global for the @everywhere scope)
num_pos = length(positive_iis)
num_neg = length(negative_iis)

positive_files = filter!(f -> ! occursin(r".*\.DS_Store", f), readdir(positive_path, join=true, sort=false))
negative_files = filter!(f -> ! occursin(r".*\.DS_Store", f), readdir(negative_path, join=true, sort=false))

num_pos = length(positive_files)
num_neg = length(negative_files)
num_imgs = num_pos + num_neg

# get image height and width
img_height, img_width = size(positive_iis[1])
temp_image = size(convert(Array{Float64}, Gray.(load(rand(positive_files)))))
img_height, img_width = temp_image
temp_image = nothing # unload temporary image

# Maximum feature width and height default to image width and height
if isequal(max_feature_height, -1)
Expand Down Expand Up @@ -83,37 +114,49 @@ function learn(
weights = vcat(pos_weights, neg_weights)
labels = vcat(ones(num_pos), ones(num_neg) * -1)

# get list of images (global because of @everywhere scope)
images = vcat(positive_iis, negative_iis)

# Create features for all sizes and locations
features = _create_features(img_height, img_width, min_feature_width, max_feature_width, min_feature_height, max_feature_height)
num_features = length(features)
feature_indices = Array(1:num_features)
used = []

if isequal(num_classifiers, -1)
num_classifiers = num_features
end

notify_user("Calculating scores for images...")

# create an empty array (of zeroes) with dimensions (num_imgs, numFeautures)
votes = zeros((num_imgs, num_features)) # necessarily different from `zero.((num_imgs, num_features))`; previously zerosarray

n = num_imgs
processes = num_imgs # i.e., hypotheses
@showprogress for t in 1:processes # bar(range(num_imgs)):
votes[t, :] = Array(map(f -> get_vote(f, images[t]), features))
end # end show progress in for loop
num_processed = 0

notify_user("Calculating scores for positive images (e.g., faces)...")
@showprogress for positive_image in positive_files
positive_image = convert(Array{Float64}, Gray.(load(positive_image)))
positive_ii = to_integral_image(positive_image)
# get list of images
# images = vcat(positive_iis, negative_iis)

# n = num_imgs
# processes = num_imgs # i.e., hypotheses
votes[num_processed + 1, :] = Array(map(f -> get_vote(f, positive_ii), features))

num_processed += 1
end # end loop through images
print("\n") # for a new line after the progress bar
notify_user("Calculating scores for negative images (e.g., non-faces)...")
@showprogress for negative_image in negative_files
negative_image = convert(Array{Float64}, Gray.(load(negative_image)))
negative_ii = to_integral_image(negative_image)

# n = num_imgs
# processes = num_imgs # i.e., hypotheses
votes[num_processed + 1, :] = Array(map(f -> get_vote(f, negative_ii), features))

num_processed += 1
end # end loop through images
print("\n") # for a new line after the progress bar

notify_user("Selecting classifiers...")
# select classifiers
classifiers = []

notify_user("Selecting classifiers...")

n = num_classifiers
@showprogress for t in 1:num_classifiers
classification_errors = zeros(length(feature_indices)) # previously, zerosarray
Expand Down Expand Up @@ -154,45 +197,6 @@ function learn(
return classifiers
end

#find / update threshold and coeff for each feature
# function _feature_job(feature_nr, feature)
# # if (feature_nr+1) % 1000 == 0:
# # print('[ %d of %d ]'%(feature_nr+1, n_features))
# if feature_nr ∈ used
# return
# end
#
# # find the scores for the images
# scores = zeros(n_img)
# for i, img in enumerate(images):
# scores[i] = feature.get_score(img)
# sorted_img_args = np.argsort(scores)
# Sp = np.zeros(n_img) # sum weights for positive examples below current img
# Sn = np.zeros(n_img) # sum weights for negative examples below current img
# Tp = 0
# Tn = 0
# for img_arg in np.nditer(sorted_img_args):
# if labels[img_arg] == 0:
# Tn += w[img_arg]
# Sn[img_arg] = Tn
# else:
# Tp += w[img_arg]
# Sp[img_arg] = Tp
#
# # compute the formula for the threshold
# nerror = Sp + (Tn - Sn) # error of classifying everything negative below threshold
# perror = Sn + (Tp - Sp) # error of classifying everything positive below threshold
# error = np.minimum(perror, nerror) # find minimum
# best_threshold_img = np.argmin(error) # find the image with the threshold
# best_local_error = error[best_threshold_img]
# feature.threshold = scores[best_threshold_img] # use the score we estimated for the image as new threshold
# # assign new polarity, based on above calculations
# feature.polarity = 1 if nerror[best_threshold_img] < perror[best_threshold_img] else -1
#
# # store the error to find best feature
# errors[feature_nr] = best_local_error
# end

#=
_create_features(
img_height::Integer,
Expand Down
6 changes: 3 additions & 3 deletions src/Utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ Takes an image and constructs a matrix of greyscale intensity values based on it
function get_image_matrix(image_file::AbstractString; scale_up::Bool=true)
img = load(image_file)

if scale_up
img = imresize(img, (577, 577))
end
# if scale_up
# img = imresize(img, (577, 577))
# end

img_arr = convert(Array{Float64}, Gray.(img))

Expand Down

0 comments on commit e911698

Please sign in to comment.