@@ -208,35 +208,45 @@ func (d *Detector) Faces(det []pigo.Detection, params pigo.CascadeParams, findLa
208208 results = make (Faces , 0 , len (det ))
209209
210210 for _ , face := range det {
211- // Skip result if quality is too low.
212- if face .Q < QualityThreshold (face .Scale ) {
213- continue
211+ score := face .Q
212+ scale := face .Scale
213+ requiredScore := QualityThreshold (scale )
214+ scaleMin := LandmarkQualityScaleMin
215+ scaleMax := LandmarkQualityScaleMax
216+ fallbackCandidate := false
217+ if ! findLandmarks && score < requiredScore && score >= LandmarkQualityFloor && scale >= scaleMin && scale <= scaleMax && requiredScore - score <= LandmarkQualitySlack {
218+ fallbackCandidate = true
214219 }
215220
216221 faceCoord := NewArea (
217222 "face" ,
218223 face .Row ,
219224 face .Col ,
220- face . Scale ,
225+ scale ,
221226 )
222227
223228 var eyesCoords []Area
224229 var landmarkCoords []Area
230+ var eyesFound bool
231+
232+ needLandmarks := (findLandmarks || fallbackCandidate ) && scale > 50
225233
226- if findLandmarks && face .Scale > 50 {
227- eyesCoords = make ([]Area , 0 , 2 )
234+ if needLandmarks {
235+ if findLandmarks {
236+ eyesCoords = make ([]Area , 0 , 2 )
237+ }
228238
229- scale := float32 (face . Scale )
239+ scaleF := float32 (scale )
230240 leftCandidate := pigo.Puploc {
231- Row : face .Row - int (0.075 * scale ),
232- Col : face .Col - int (0.175 * scale ),
233- Scale : scale * 0.25 ,
241+ Row : face .Row - int (0.075 * scaleF ),
242+ Col : face .Col - int (0.175 * scaleF ),
243+ Scale : scaleF * 0.25 ,
234244 Perturbs : d .perturb ,
235245 }
236246
237247 leftEye := plc .RunDetector (leftCandidate , params .ImageParams , d .landmarkAngle , false )
238248 leftEyeFound := leftEye .Row > 0 && leftEye .Col > 0
239- if leftEyeFound {
249+ if leftEyeFound && findLandmarks {
240250 eyesCoords = append (eyesCoords , NewArea (
241251 "eye_l" ,
242252 leftEye .Row ,
@@ -246,15 +256,15 @@ func (d *Detector) Faces(det []pigo.Detection, params pigo.CascadeParams, findLa
246256 }
247257
248258 rightCandidate := pigo.Puploc {
249- Row : face .Row - int (0.075 * scale ),
250- Col : face .Col + int (0.185 * scale ),
251- Scale : scale * 0.25 ,
259+ Row : face .Row - int (0.075 * scaleF ),
260+ Col : face .Col + int (0.185 * scaleF ),
261+ Scale : scaleF * 0.25 ,
252262 Perturbs : d .perturb ,
253263 }
254264
255265 rightEye := plc .RunDetector (rightCandidate , params .ImageParams , d .landmarkAngle , false )
256266 rightEyeFound := rightEye .Row > 0 && rightEye .Col > 0
257- if rightEyeFound {
267+ if rightEyeFound && findLandmarks {
258268 eyesCoords = append (eyesCoords , NewArea (
259269 "eye_r" ,
260270 rightEye .Row ,
@@ -264,71 +274,83 @@ func (d *Detector) Faces(det []pigo.Detection, params pigo.CascadeParams, findLa
264274 }
265275
266276 if leftEyeFound && rightEyeFound {
267- landmarkCapacity := len (eyeCascades )* 2 + len (mouthCascades ) + 1
268- landmarkCoords = make ([]Area , 0 , landmarkCapacity )
269-
270- for _ , eye := range eyeCascades {
271- for _ , flpc := range flpcs [eye ] {
272- if flpc == nil {
273- continue
274- }
275-
276- flp := flpc .GetLandmarkPoint (leftEye , rightEye , params .ImageParams , d .perturb , false )
277- if flp .Row > 0 && flp .Col > 0 {
278- landmarkCoords = append (landmarkCoords , NewArea (
279- eye ,
280- flp .Row ,
281- flp .Col ,
282- int (flp .Scale ),
283- ))
284- }
285-
286- flp = flpc .GetLandmarkPoint (leftEye , rightEye , params .ImageParams , d .perturb , true )
287- if flp .Row > 0 && flp .Col > 0 {
288- landmarkCoords = append (landmarkCoords , NewArea (
289- eye + "_v" ,
290- flp .Row ,
291- flp .Col ,
292- int (flp .Scale ),
293- ))
277+ eyesFound = true
278+
279+ if findLandmarks {
280+ landmarkCapacity := len (eyeCascades )* 2 + len (mouthCascades ) + 1
281+ landmarkCoords = make ([]Area , 0 , landmarkCapacity )
282+
283+ for _ , eye := range eyeCascades {
284+ for _ , flpc := range flpcs [eye ] {
285+ if flpc == nil {
286+ continue
287+ }
288+
289+ flp := flpc .GetLandmarkPoint (leftEye , rightEye , params .ImageParams , d .perturb , false )
290+ if flp .Row > 0 && flp .Col > 0 {
291+ landmarkCoords = append (landmarkCoords , NewArea (
292+ eye ,
293+ flp .Row ,
294+ flp .Col ,
295+ int (flp .Scale ),
296+ ))
297+ }
298+
299+ flp = flpc .GetLandmarkPoint (leftEye , rightEye , params .ImageParams , d .perturb , true )
300+ if flp .Row > 0 && flp .Col > 0 {
301+ landmarkCoords = append (landmarkCoords , NewArea (
302+ eye + "_v" ,
303+ flp .Row ,
304+ flp .Col ,
305+ int (flp .Scale ),
306+ ))
307+ }
294308 }
295309 }
296- }
297310
298- for _ , mouth := range mouthCascades {
299- for _ , flpc := range flpcs [mouth ] {
300- if flpc == nil {
301- continue
302- }
303-
304- flp := flpc .GetLandmarkPoint (leftEye , rightEye , params .ImageParams , d .perturb , false )
305- if flp .Row > 0 && flp .Col > 0 {
306- landmarkCoords = append (landmarkCoords , NewArea (
307- "mouth_" + mouth ,
308- flp .Row ,
309- flp .Col ,
310- int (flp .Scale ),
311- ))
311+ for _ , mouth := range mouthCascades {
312+ for _ , flpc := range flpcs [mouth ] {
313+ if flpc == nil {
314+ continue
315+ }
316+
317+ flp := flpc .GetLandmarkPoint (leftEye , rightEye , params .ImageParams , d .perturb , false )
318+ if flp .Row > 0 && flp .Col > 0 {
319+ landmarkCoords = append (landmarkCoords , NewArea (
320+ "mouth_" + mouth ,
321+ flp .Row ,
322+ flp .Col ,
323+ int (flp .Scale ),
324+ ))
325+ }
312326 }
313327 }
314- }
315328
316- if cascades := flpcs ["lp84" ]; len (cascades ) > 0 {
317- if flpc := cascades [0 ]; flpc != nil {
318- flp := flpc .GetLandmarkPoint (leftEye , rightEye , params .ImageParams , d .perturb , true )
319- if flp .Row > 0 && flp .Col > 0 {
320- landmarkCoords = append (landmarkCoords , NewArea (
321- "lp84" ,
322- flp .Row ,
323- flp .Col ,
324- int (flp .Scale ),
325- ))
329+ if cascades := flpcs ["lp84" ]; len (cascades ) > 0 {
330+ if flpc := cascades [0 ]; flpc != nil {
331+ flp := flpc .GetLandmarkPoint (leftEye , rightEye , params .ImageParams , d .perturb , true )
332+ if flp .Row > 0 && flp .Col > 0 {
333+ landmarkCoords = append (landmarkCoords , NewArea (
334+ "lp84" ,
335+ flp .Row ,
336+ flp .Col ,
337+ int (flp .Scale ),
338+ ))
339+ }
326340 }
327341 }
328342 }
329343 }
330344 }
331345
346+ if eyesFound && fallbackCandidate && requiredScore > LandmarkQualityFloor {
347+ requiredScore = LandmarkQualityFloor
348+ }
349+
350+ if score < requiredScore {
351+ continue
352+ }
353+
332354 // Create face.
333355 f := Face {
334356 Rows : params .ImageParams .Rows ,
0 commit comments