@@ -158,7 +158,8 @@ public static async Task DetectFaceExtract(IFaceClient client, string url, strin
158158 returnFaceAttributes : new List < FaceAttributeType > { FaceAttributeType . Accessories , FaceAttributeType . Age ,
159159 FaceAttributeType . Blur , FaceAttributeType . Emotion , FaceAttributeType . Exposure , FaceAttributeType . FacialHair ,
160160 FaceAttributeType . Gender , FaceAttributeType . Glasses , FaceAttributeType . Hair , FaceAttributeType . HeadPose ,
161- FaceAttributeType . Makeup , FaceAttributeType . Noise , FaceAttributeType . Occlusion , FaceAttributeType . Smile } ,
161+ FaceAttributeType . Makeup , FaceAttributeType . Noise , FaceAttributeType . Occlusion , FaceAttributeType . Smile ,
162+ FaceAttributeType . Smile , FaceAttributeType . QualityForRecognition } ,
162163 // We specify detection model 1 because we are retrieving attributes.
163164 detectionModel : DetectionModel . Detection01 ,
164165 recognitionModel : recognitionModel ) ;
@@ -230,6 +231,9 @@ public static async Task DetectFaceExtract(IFaceClient client, string url, strin
230231 Console . WriteLine ( $ "Occlusion : { string . Format ( "EyeOccluded: {0}" , face . FaceAttributes . Occlusion . EyeOccluded ? "Yes" : "No" ) } " +
231232 $ " { string . Format ( "ForeheadOccluded: {0}" , face . FaceAttributes . Occlusion . ForeheadOccluded ? "Yes" : "No" ) } { string . Format ( "MouthOccluded: {0}" , face . FaceAttributes . Occlusion . MouthOccluded ? "Yes" : "No" ) } ") ;
232233 Console . WriteLine ( $ "Smile : { face . FaceAttributes . Smile } ") ;
234+
235+ // Get quality for recognition attribute
236+ Console . WriteLine ( $ "QualityForRecognition : { face . FaceAttributes . QualityForRecognition } ") ;
233237 Console . WriteLine ( ) ;
234238 }
235239 }
@@ -238,16 +242,27 @@ public static async Task DetectFaceExtract(IFaceClient client, string url, strin
238242
239243 // Detect faces from image url for recognition purpose. This is a helper method for other functions in this quickstart.
240244 // Parameter `returnFaceId` of `DetectWithUrlAsync` must be set to `true` (by default) for recognition purpose.
245+ // Parameter `FaceAttributes` is set to include the QualityForRecognition attribute.
246+ // Recognition model must be set to recognition_03 or recognition_04 as a result.
247+ // Result faces with insufficient quality for recognition are filtered out.
241248 // The field `faceId` in returned `DetectedFace`s will be used in Face - Find Similar, Face - Verify. and Face - Identify.
242249 // It will expire 24 hours after the detection call.
243250 // <snippet_face_detect_recognize>
244251 private static async Task < List < DetectedFace > > DetectFaceRecognize ( IFaceClient faceClient , string url , string recognition_model )
245252 {
246253 // Detect faces from image URL. Since only recognizing, use the recognition model 1.
247254 // We use detection model 3 because we are not retrieving attributes.
248- IList < DetectedFace > detectedFaces = await faceClient . Face . DetectWithUrlAsync ( url , recognitionModel : recognition_model , detectionModel : DetectionModel . Detection03 ) ;
249- Console . WriteLine ( $ "{ detectedFaces . Count } face(s) detected from image `{ Path . GetFileName ( url ) } `") ;
250- return detectedFaces . ToList ( ) ;
255+ IList < DetectedFace > detectedFaces = await faceClient . Face . DetectWithUrlAsync ( url , recognitionModel : recognition_model , detectionModel : DetectionModel . Detection03 , FaceAttributes : new List < FaceAttributeType > { FaceAttributeType . QualityForRecognition } ) ;
256+ List < DetectedFace > sufficientQualityFaces = new List < DetectedFace > ( ) ;
257+ foreach ( DetectedFace detectedFace in detectedFaces ) {
258+ var faceQualityForRecognition = detectedFace . FaceAttributes . QualityForRecognition ;
259+ if ( faceQualityForRecognition . HasValue && ( faceQualityForRecognition . Value >= QualityForRecognition . Medium ) ) {
260+ sufficientQualityFaces . Add ( detectedFace ) ;
261+ }
262+ }
263+ Console . WriteLine ( $ "{ detectedFaces . Count } face(s) with { sufficientQualityFaces . Count } having sufficient quality for recognition detected from image `{ Path . GetFileName ( url ) } `") ;
264+
265+ return sufficientQualityFaces . ToList ( ) ;
251266 }
252267 // </snippet_face_detect_recognize>
253268 /*
@@ -402,6 +417,27 @@ public static async Task IdentifyInPersonGroup(IFaceClient client, string url, s
402417 // Add face to the person group person.
403418 foreach ( var similarImage in personDictionary [ groupedFace ] )
404419 {
420+ Console . WriteLine ( $ "Check whether image is of sufficient quality for recognition") ;
421+ IList < DetectedFace > detectedFaces = await client . Face . DetectWithUrlAsync ( $ "{ url } { similarImage } ",
422+ recognitionModel : recognition_model ,
423+ detectionModel : DetectionModel . Detection03 ,
424+ returnFaceAttributes : new List < FaceAttributeType > { FaceAttributeType . QualityForRecognition } ) ;
425+ bool sufficientQuality = true ;
426+ foreach ( var face in detectedFaces )
427+ {
428+ var faceQualityForRecognition = face . FaceAttributes . QualityForRecognition ;
429+ // Only "high" quality images are recommended for person enrollment
430+ if ( faceQualityForRecognition . HasValue && ( faceQualityForRecognition . Value != QualityForRecognition . High ) ) {
431+ sufficientQuality = false ;
432+ break ;
433+ }
434+ }
435+
436+ if ( ! sufficientQuality ) {
437+ continue ;
438+ }
439+
440+
405441 Console . WriteLine ( $ "Add face to the person group person({ groupedFace } ) from image `{ similarImage } `") ;
406442 PersistedFace face = await client . PersonGroupPerson . AddFaceFromUrlAsync ( personGroupId , person . PersonId ,
407443 $ "{ url } { similarImage } ", similarImage ) ;
0 commit comments