|
10 | 10 |
|
11 | 11 | # include("HaarLikeFeature.jl")
|
12 | 12 | include("Utils.jl")
|
| 13 | +include("IntegralImage.jl") |
13 | 14 |
|
14 | 15 | using ProgressMeter: @showprogress
|
| 16 | + |
| 17 | + |
| 18 | +function load_images(image_dir::AbstractString) |
| 19 | + files = filter!(f -> ! occursin(r".*\.DS_Store", f), readdir(image_dir, join=true, sort=false)) |
| 20 | + images = [] |
| 21 | + |
| 22 | + for file in files |
| 23 | + images = push!(images, get_image_matrix(file)) |
| 24 | + end |
| 25 | + |
| 26 | + return images, files |
| 27 | +end |
| 28 | +function get_image_matrix(image_file::AbstractString; scale_up::Bool=true) |
| 29 | + img = load(image_file) |
| 30 | + |
| 31 | + img_arr = convert(Array{Float64}, Gray.(img)) |
| 32 | + |
| 33 | + return img_arr |
| 34 | +end |
| 35 | + |
| 36 | + |
| 37 | + |
15 | 38 | #=
|
16 | 39 | learn(
|
17 | 40 | positive_iis::AbstractArray,
|
@@ -40,21 +63,29 @@ This function selects a set of classifiers. Iteratively takes the best classifie
|
40 | 63 | # Returns `classifiers::Array{HaarLikeObject, 1}`: List of selected features
|
41 | 64 | =#
|
42 | 65 | function learn(
|
43 |
| - positive_iis::AbstractArray, |
44 |
| - negative_iis::AbstractArray, |
| 66 | + # positive_iis::AbstractArray, |
| 67 | + # negative_iis::AbstractArray, |
| 68 | + positive_path::AbstractString, |
| 69 | + negative_path::AbstractString, |
45 | 70 | num_classifiers::Integer=-1,
|
46 | 71 | min_feature_width::Integer=1,
|
47 | 72 | max_feature_width::Integer=-1,
|
48 | 73 | min_feature_height::Integer=1,
|
49 | 74 | max_feature_height::Integer=-1
|
50 |
| -)#::Array{HaarLikeObject,1} |
| 75 | +)::Array{HaarLikeObject,1} |
51 | 76 | # get number of positive and negative images (and create a global variable of the total number of images——global for the @everywhere scope)
|
52 |
| - num_pos = length(positive_iis) |
53 |
| - num_neg = length(negative_iis) |
| 77 | + |
| 78 | + positive_files = filter!(f -> ! occursin(r".*\.DS_Store", f), readdir(positive_path, join=true, sort=false)) |
| 79 | + negative_files = filter!(f -> ! occursin(r".*\.DS_Store", f), readdir(negative_path, join=true, sort=false)) |
| 80 | + |
| 81 | + num_pos = length(positive_files) |
| 82 | + num_neg = length(negative_files) |
54 | 83 | num_imgs = num_pos + num_neg
|
55 | 84 |
|
56 | 85 | # get image height and width
|
57 |
| - img_height, img_width = size(positive_iis[1]) |
| 86 | + temp_image = size(convert(Array{Float64}, Gray.(load(rand(positive_files))))) |
| 87 | + img_height, img_width = temp_image |
| 88 | + temp_image = nothing # unload temporary image |
58 | 89 |
|
59 | 90 | # Maximum feature width and height default to image width and height
|
60 | 91 | if isequal(max_feature_height, -1)
|
@@ -83,37 +114,49 @@ function learn(
|
83 | 114 | weights = vcat(pos_weights, neg_weights)
|
84 | 115 | labels = vcat(ones(num_pos), ones(num_neg) * -1)
|
85 | 116 |
|
86 |
| - # get list of images (global because of @everywhere scope) |
87 |
| - images = vcat(positive_iis, negative_iis) |
88 |
| -
|
89 | 117 | # Create features for all sizes and locations
|
90 | 118 | features = _create_features(img_height, img_width, min_feature_width, max_feature_width, min_feature_height, max_feature_height)
|
91 | 119 | num_features = length(features)
|
92 | 120 | feature_indices = Array(1:num_features)
|
93 | 121 | used = []
|
94 |
| - |
95 | 122 | if isequal(num_classifiers, -1)
|
96 | 123 | num_classifiers = num_features
|
97 | 124 | end
|
98 | 125 |
|
99 |
| - notify_user("Calculating scores for images...") |
100 |
| - |
101 | 126 | # create an empty array (of zeroes) with dimensions (num_imgs, numFeautures)
|
102 | 127 | votes = zeros((num_imgs, num_features)) # necessarily different from `zero.((num_imgs, num_features))`; previously zerosarray
|
103 |
| -
|
104 |
| - n = num_imgs |
105 |
| - processes = num_imgs # i.e., hypotheses |
106 |
| - @showprogress for t in 1:processes # bar(range(num_imgs)): |
107 |
| - votes[t, :] = Array(map(f -> get_vote(f, images[t]), features)) |
108 |
| - end # end show progress in for loop |
| 128 | + num_processed = 0 |
109 | 129 |
|
| 130 | + notify_user("Calculating scores for positive images (e.g., faces)...") |
| 131 | + @showprogress for positive_image in positive_files |
| 132 | + positive_image = convert(Array{Float64}, Gray.(load(positive_image))) |
| 133 | + positive_ii = to_integral_image(positive_image) |
| 134 | + # get list of images |
| 135 | + # images = vcat(positive_iis, negative_iis) |
| 136 | +
|
| 137 | + # n = num_imgs |
| 138 | + # processes = num_imgs # i.e., hypotheses |
| 139 | + votes[num_processed + 1, :] = Array(map(f -> get_vote(f, positive_ii), features)) |
| 140 | + |
| 141 | + num_processed += 1 |
| 142 | + end # end loop through images |
| 143 | + print("\n") # for a new line after the progress bar |
| 144 | + notify_user("Calculating scores for negative images (e.g., non-faces)...") |
| 145 | + @showprogress for negative_image in negative_files |
| 146 | + negative_image = convert(Array{Float64}, Gray.(load(negative_image))) |
| 147 | + negative_ii = to_integral_image(negative_image) |
| 148 | +
|
| 149 | + # n = num_imgs |
| 150 | + # processes = num_imgs # i.e., hypotheses |
| 151 | + votes[num_processed + 1, :] = Array(map(f -> get_vote(f, negative_ii), features)) |
| 152 | + |
| 153 | + num_processed += 1 |
| 154 | + end # end loop through images |
110 | 155 | print("\n") # for a new line after the progress bar
|
111 | 156 |
|
| 157 | + notify_user("Selecting classifiers...") |
112 | 158 | # select classifiers
|
113 | 159 | classifiers = []
|
114 |
| -
|
115 |
| - notify_user("Selecting classifiers...") |
116 |
| - |
117 | 160 | n = num_classifiers
|
118 | 161 | @showprogress for t in 1:num_classifiers
|
119 | 162 | classification_errors = zeros(length(feature_indices)) # previously, zerosarray
|
@@ -154,45 +197,6 @@ function learn(
|
154 | 197 | return classifiers
|
155 | 198 | end
|
156 | 199 |
|
157 |
| -#find / update threshold and coeff for each feature |
158 |
| -# function _feature_job(feature_nr, feature) |
159 |
| -# # if (feature_nr+1) % 1000 == 0: |
160 |
| -# # print('[ %d of %d ]'%(feature_nr+1, n_features)) |
161 |
| -# if feature_nr ∈ used |
162 |
| -# return |
163 |
| -# end |
164 |
| -# |
165 |
| -# # find the scores for the images |
166 |
| -# scores = zeros(n_img) |
167 |
| -# for i, img in enumerate(images): |
168 |
| -# scores[i] = feature.get_score(img) |
169 |
| -# sorted_img_args = np.argsort(scores) |
170 |
| -# Sp = np.zeros(n_img) # sum weights for positive examples below current img |
171 |
| -# Sn = np.zeros(n_img) # sum weights for negative examples below current img |
172 |
| -# Tp = 0 |
173 |
| -# Tn = 0 |
174 |
| -# for img_arg in np.nditer(sorted_img_args): |
175 |
| -# if labels[img_arg] == 0: |
176 |
| -# Tn += w[img_arg] |
177 |
| -# Sn[img_arg] = Tn |
178 |
| -# else: |
179 |
| -# Tp += w[img_arg] |
180 |
| -# Sp[img_arg] = Tp |
181 |
| -# |
182 |
| -# # compute the formula for the threshold |
183 |
| -# nerror = Sp + (Tn - Sn) # error of classifying everything negative below threshold |
184 |
| -# perror = Sn + (Tp - Sp) # error of classifying everything positive below threshold |
185 |
| -# error = np.minimum(perror, nerror) # find minimum |
186 |
| -# best_threshold_img = np.argmin(error) # find the image with the threshold |
187 |
| -# best_local_error = error[best_threshold_img] |
188 |
| -# feature.threshold = scores[best_threshold_img] # use the score we estimated for the image as new threshold |
189 |
| -# # assign new polarity, based on above calculations |
190 |
| -# feature.polarity = 1 if nerror[best_threshold_img] < perror[best_threshold_img] else -1 |
191 |
| -# |
192 |
| -# # store the error to find best feature |
193 |
| -# errors[feature_nr] = best_local_error |
194 |
| -# end |
195 |
| - |
196 | 200 | #=
|
197 | 201 | _create_features(
|
198 | 202 | img_height::Integer,
|
|
0 commit comments