face_detection_impl_mac.mm 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/shape_detection/face_detection_impl_mac.h"
  5. #include "base/mac/scoped_cftyperef.h"
  6. #include "services/shape_detection/detection_utils_mac.h"
  7. namespace shape_detection {
  8. FaceDetectionImplMac::FaceDetectionImplMac(
  9. shape_detection::mojom::FaceDetectorOptionsPtr options) {
  10. NSString* const accuracy =
  11. options->fast_mode ? CIDetectorAccuracyLow : CIDetectorAccuracyHigh;
  12. // The CIDetectorMaxFeatureCount option introduced in Mac OS SDK 10.12 can
  13. // only be used with Rectangle Detectors.
  14. NSDictionary* const detector_options = @{CIDetectorAccuracy : accuracy};
  15. detector_.reset([[CIDetector detectorOfType:CIDetectorTypeFace
  16. context:nil
  17. options:detector_options] retain]);
  18. }
  19. FaceDetectionImplMac::~FaceDetectionImplMac() {}
  20. void FaceDetectionImplMac::Detect(const SkBitmap& bitmap,
  21. DetectCallback callback) {
  22. base::scoped_nsobject<CIImage> ci_image = CreateCIImageFromSkBitmap(bitmap);
  23. if (!ci_image) {
  24. std::move(callback).Run({});
  25. return;
  26. }
  27. NSArray* const features = [detector_ featuresInImage:ci_image];
  28. const int height = bitmap.height();
  29. std::vector<mojom::FaceDetectionResultPtr> results;
  30. for (CIFaceFeature* const f in features) {
  31. auto face = shape_detection::mojom::FaceDetectionResult::New();
  32. face->bounding_box = ConvertCGToGfxCoordinates(f.bounds, height);
  33. if (f.hasLeftEyePosition) {
  34. auto landmark = shape_detection::mojom::Landmark::New();
  35. landmark->type = shape_detection::mojom::LandmarkType::EYE;
  36. landmark->locations.emplace_back(f.leftEyePosition.x,
  37. height - f.leftEyePosition.y);
  38. face->landmarks.push_back(std::move(landmark));
  39. }
  40. if (f.hasRightEyePosition) {
  41. auto landmark = shape_detection::mojom::Landmark::New();
  42. landmark->type = shape_detection::mojom::LandmarkType::EYE;
  43. landmark->locations.emplace_back(f.rightEyePosition.x,
  44. height - f.rightEyePosition.y);
  45. face->landmarks.push_back(std::move(landmark));
  46. }
  47. if (f.hasMouthPosition) {
  48. auto landmark = shape_detection::mojom::Landmark::New();
  49. landmark->type = shape_detection::mojom::LandmarkType::MOUTH;
  50. landmark->locations.emplace_back(f.mouthPosition.x,
  51. height - f.mouthPosition.y);
  52. face->landmarks.push_back(std::move(landmark));
  53. }
  54. results.push_back(std::move(face));
  55. }
  56. std::move(callback).Run(std::move(results));
  57. }
  58. } // namespace shape_detection