微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Xmarin.forms iOS检查捕获的照片是否包含面部

如何解决Xmarin.forms iOS检查捕获的照片是否包含面部

在我的xamarin.forms应用程序中,我使用“相机”视图和自定义渲染创建了一个自定义相机。一切正常。在拍摄照片后的android中,我可以检查所拍摄的照片是否包含人脸。这可以通过使用Camera.IFaceDetectionListener完成。我的问题是如何在iOS中实现这一目标?我知道有视觉API。但是我不希望有实时面部跟踪。我只是想检查拍摄的照片是否包含脸部。任何帮助表示赞赏。

我的iOS CameraPreview

public class UICameraPreview : UIView,IAVCaptureMetadataOutputObjectsDelegate
    {
        
        AVCaptureVideoPreviewLayer previewLayer;
        public AVCaptureDevice[] videoDevices;
        CameraOptions cameraOptions;
        public AVCaptureStillImageOutput stillImageOutput;
        public AVCaptureDeviceInput captureDeviceInput;
        public AVCaptureDevice device;

        public event EventHandler<EventArgs> Tapped;

        public AVCaptureSession CaptureSession { get; set; }

        public bool IsPreviewing { get; set; }

        public AVCaptureStillImageOutput CaptureOutput { get; set; }

        

        public UICameraPreview(CameraOptions options)
        {
            cameraOptions = options;
            IsPreviewing = false;
            Initialize();
        }

        public override void LayoutSubviews()
        {
            base.LayoutSubviews();

            if (previewLayer != null)
                previewLayer.Frame = Bounds;
        }

        public override void touchesBegan(NSSet touches,UIEvent evt)
        {
            base.touchesBegan(touches,evt);
            OnTapped();
        }

        protected virtual void OnTapped()
        {
            var eventHandler = Tapped;
            if (eventHandler != null)
            {
                eventHandler(this,new EventArgs());
            }
        }


        void Initialize()
        {
            CaptureSession = new AVCaptureSession();
            previewLayer = new AVCaptureVideoPreviewLayer(CaptureSession)
            {
                Frame = Bounds,VideoGravity = AVLayerVideoGravity.ResizeAspectFill
            };

            videoDevices = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video);
            var cameraPosition = (cameraOptions == CameraOptions.Front) ? AVCaptureDevicePosition.Front : AVCaptureDevicePosition.Back;
            device = videoDevices.FirstOrDefault(d => d.Position == cameraPosition);

            if (device == null)
            {
                return;
            }

            NSError error;
            captureDeviceInput = new AVCaptureDeviceInput(device,out error);
            CaptureSession.AddInput(captureDeviceInput);

            var dictionary = new NSMutableDictionary();
            dictionary[AVVideo.CodecKey] = new NSNumber((int)AVVideoCodec.JPEG);
            stillImageOutput = new AVCaptureStillImageOutput()
            {
                OutputSettings = new NSDictionary()
            };
            CaptureSession.AddOutput(stillImageOutput);
            Layer.AddSublayer(previewLayer);
            CaptureSession.StartRunning();
            IsPreviewing = true;
        }

       // Photo Capturing

        public async Task CapturePhoto()
        {
            try
            {
                var videoConnection = stillImageOutput.ConnectionFromMediaType(AVMediaType.Video);
                var sampleBuffer = await stillImageOutput.CaptureStillImageTaskAsync(videoConnection);
                var jpegData = AVCaptureStillImageOutput.JpegStillToNSData(sampleBuffer);
                var photo = new UIImage(jpegData);
                var rotatedPhoto = RotateImage(photo,180f);
                var img = rotatedPhoto;
                
                CALayer layer = new CALayer
                {
                    
                    ContentsScale = 1.0f,Frame = Bounds,Contents = rotatedPhoto.CGImage //Contents = photo.CGImage,};
                CaptureSession.StopRunning();
                photo.SavetoPhotosAlbum((image,error) =>
                {
                    if (!string.IsNullOrEmpty(error?.LocalizedDescription))
                    {
                        Console.Error.WriteLine($"\t\t\tError: {error.LocalizedDescription}");
                    }
                });

            }
            catch (Exception ex)
            {
            }
            //MainPage.UpdateSource(UIImageFromLayer(layer).AsJPEG().Asstream());
            //MainPage.UpdateImage(UIImageFromLayer(layer).AsJPEG().Asstream());
        }

    
    }

我的CameraPrevieWrenderer

public class CameraPrevieWrenderer : VieWrenderer<CameraPreview,UICameraPreview>,IAVCaptureMetadataOutputObjectsDelegate
    {
        UICameraPreview uiCameraPreview;
        AVCaptureSession captureSession;
        AVCaptureDeviceInput captureDeviceInput;
        AVCaptureStillImageOutput stillImageOutput;

        protected override void OnElementChanged(ElementChangedEventArgs<CameraPreview> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                // Unsubscribe
                uiCameraPreview.Tapped -= OnCameraPreviewTapped;
            }
            if (e.NewElement != null)
            {
                if (Control == null)
                {
                    uiCameraPreview = new UICameraPreview(e.NewElement.Camera);
                    SetNativeControl(uiCameraPreview);
                    MessagingCenter.Subscribe<Camera_Popup>(this,"CaptureClick",async (sender) =>
                    {
                        try
                        {
                           // Using messeging center to take photo when clicking button from shared code
                            var data = new AVCaptureMetadataOutputObjectsDelegate();
                            await uiCameraPreview.CapturePhoto();
                            
                        }
                        catch (Exception ex)
                        {
                            return;
                        }

                    });
                }
                MessagingCenter.Subscribe<Camera_Popup>(this,"RetryClick",(sender) =>
                {
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        uiCameraPreview.CaptureSession.StartRunning();
                        uiCameraPreview.IsPreviewing = true;
                    });
                });
                MessagingCenter.Subscribe<Camera_Popup>(this,"FlipClick",(sender) =>
                {
                    try
                    {
                        var devicePosition = uiCameraPreview.captureDeviceInput.Device.Position;
                        if (devicePosition == AVCaptureDevicePosition.Front)
                        {
                            devicePosition = AVCaptureDevicePosition.Back;
                        }
                        else
                        {
                            devicePosition = AVCaptureDevicePosition.Front;
                        }
                        uiCameraPreview.device = uiCameraPreview.videoDevices.FirstOrDefault(d => d.Position == devicePosition);
                        uiCameraPreview.CaptureSession.BeginConfiguration();
                        uiCameraPreview.CaptureSession.RemoveInput(uiCameraPreview.captureDeviceInput);
                        uiCameraPreview.captureDeviceInput = AVCaptureDeviceInput.FromDevice(uiCameraPreview.device);
                        uiCameraPreview.CaptureSession.AddInput(uiCameraPreview.captureDeviceInput);
                        uiCameraPreview.CaptureSession.CommitConfiguration();

                    }
                    catch (Exception ex)
                    {
                        var abc = ex.InnerException.Message;
                    }

                });
                uiCameraPreview.Tapped += OnCameraPreviewTapped;
            }
        }

         void OnCameraPreviewTapped(object sender,EventArgs e)
        {
            if (uiCameraPreview.IsPreviewing)
            {
                uiCameraPreview.CaptureSession.StopRunning();
                uiCameraPreview.IsPreviewing = false;
            }
            else
            {
                uiCameraPreview.CaptureSession.StartRunning();
                uiCameraPreview.IsPreviewing = true;
            }
        }

        protected override void dispose(bool disposing)
        {
            if (disposing)
            {
                Control.CaptureSession.dispose();
                Control.dispose();
            }
            base.dispose(disposing);
        }
    }

解决方法

CoreImage框架具有CIDetector,该框架提供了用于面部,QR码,文本...的图像检测器,您可以在其中传递图像并获得特定的“功能集”。

Xamarin文档中的示例:

var imageFile = "photoFace2.jpg";
var image = new UIImage(imageFile);
var context = new CIContext ();
var detector = CIDetector.CreateFaceDetector (context,true);
var ciImage = CIImage.FromCGImage (image.CGImage);
var features = detector.GetFeatures (ciImage);
Console.WriteLine ("Found " + features.Length + " faces");

re:https://docs.microsoft.com/en-us/dotnet/api/CoreImage.CIDetector?view=xamarin-ios-sdk-12

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。