首页 > 解决方案 > 相机预览人脸检测失败

问题描述

在我的 Xamarin.forms android 应用程序中,我使用IFaceDetectionListener Doc来检测自定义相机预览中的人脸。当我尝试打开我的自定义相机页面时,我收到了这样的错误。

Java.Lang.RuntimeException: start face detection failed

我的堆栈跟踪是

JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args)
JniPeerMembers+JniInstanceMethods.InvokeNonvirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
Camera.StartFaceDetection ()
CameraPreviewRenderer+<>c__DisplayClass8_0.<OnElementChanged>b__1 ()
Thread+RunnableImplementor.Run ()
mono.java.lang.RunnableImplementor.run RunnableImplementor.java:30
android.os.Handler.handleCallback Handler.java:883

这个错误发生在我OnElementChanged的 CameraCustomRender 上。

相机自定义渲染

  public class CameraPreviewRenderer : ViewRenderer<App.Views.Clocking.CustomCamera.CameraPreview, App.Droid.CustomRender.Clocking.CameraPreview>, Camera.IFaceDetectionListener, Camera.IPictureCallback, Camera.IShutterCallback
            {
                CameraPreview cameraPreview;
                String Picture_Name = "";
                private CameraFacing camerainfo = CameraFacing.Front;
                int DetectedFaceCount = 0;
        
                [get: Android.Runtime.Register("getMaxNumDetectedFaces", "()I", "GetGetMaxNumDetectedFacesHandler", ApiSince = 14)]
                public virtual int MaxNumDetectedFaces { get; }
        
                public CameraPreviewRenderer(Context context) : base(context)
                {           
                }
        
                [Obsolete]
                protected  override void OnElementChanged(ElementChangedEventArgs<Centraverse.Views.Clocking.CustomCamera.CameraPreview> e)
                {
                    try
                    {
                        base.OnElementChanged(e);
                        if (Control == null)
                        {
                            try
                            {
                                cameraPreview = new CameraPreview(Context);
                                SetNativeControl(cameraPreview);
                            }
                            catch (Exception ex)
                            {
                             
                            }
        
                        }
                        if (e.OldElement != null)
                        {
                        }
                        if (e.NewElement != null)
                        {
                            try
                            {
                                if (Control == null)
                                {
                                    cameraPreview = new CameraPreview(Context);
                                    SetNativeControl(cameraPreview);
                                }
                                Control.Preview = Camera.Open((int)e.NewElement.Camera);
                                Control.CameraID = 1;
        
                                var CameraParaMeters = cameraPreview.camera.GetParameters();
                                if (CameraParaMeters != null)
                                {
                                    if (CameraParaMeters.MaxNumDetectedFaces > 0)
                                    {
                                        Device.BeginInvokeOnMainThread(() =>
                                        {

  >------------------// Getting crashed at here-------------------------------------<
                                            Control.Preview.SetFaceDetectionListener(this);
                                            Control.Preview.StartFaceDetection();
                                        });
                                    }
                                }
                               
                            }
                            catch (Exception ex)
                            {
                              
                            }
                        }
                    }
                    catch(Exception ex)
                    {
                        
                    }      
                }
        
        
        
        
                protected override void Dispose(bool disposing)
                {
                    try
                    {
                        if (disposing)
                        {
                            Control.Preview.Release();
                            MessagingCenter.Unsubscribe<Object>(this, "CaptureClick");
                            MessagingCenter.Unsubscribe<Object>(this, "FlipClick");
                        }
                        Device.BeginInvokeOnMainThread(base.Dispose);
        
                    }
                    catch (Exception ex)
                    {
                        
                    }
        
                }
        
                [Obsolete]
                public void OnFaceDetection(Camera.Face[] faces, Camera camera)
                {
                    try
                    {
                        DetectedFaceCount = faces.Length;
                    }
                    catch (Exception ex)
                    {
                        
                    }
        
                }
        
                private  void takepicture()
                {
                    try
                    {
                        Control.Preview.TakePicture(this, this, this);
                    }
                    catch (Exception ex)
                    {
                       
                    }
                }
        
        
                public  void OnPictureTaken(byte[] data, Camera camera)
                {
                    try
                    {
                       // Managing camera capture        
                    }
                    catch (Exception ex)
                    {        
                    }
                }
        
                public void OnShutter() { }
        
            }

我无法隔离问题。该应用程序因错误提示“启动人脸检测失败”而崩溃。由于我使用的是较旧的相机 API,这会导致此问题吗?请帮我解决这个问题。为方便起见,我在这里有示例项目。示例项目

编辑

我能够捕捉到这样的异常

                                 try
                                    {
                                        Control.Preview.SetFaceDetectionListener(this);
                                        Control.Preview.StartFaceDetection();
                                    }
                                    catch (Java.Lang.RuntimeException ex)
                                    {                                      
                                                                                                                                                               
                                    }

标签: c#xamarinxamarin.formsxamarin.android

解决方案


我测试了您的示例,当我不使用模式页面打开时CameraPage,它会起作用。

您可以尝试更改 which 在您的MainPage.xaml.cs

await Navigation.PushModalAsync(new CameraPage());

await Navigation.PushAsync(new CameraPage()); 

像:

private async void Open_Camera(object sender, EventArgs e)
    {
        try
        {
            var PhotoRequeststatus = await Permissions.RequestAsync<Permissions.Camera>();
            var StorageRequStatus = await Permissions.RequestAsync<Permissions.StorageWrite>();
            if (PhotoRequeststatus != Xamarin.Essentials.PermissionStatus.Granted || StorageRequStatus != Xamarin.Essentials.PermissionStatus.Granted)
            {
                await DisplayAlert("Enable Permission", "Please allow camera permission", "Close");
            }
            else
            {

                await Navigation.PushAsync(new CameraPage()); 
            }
        }

        catch(Exception ex)
        {

        }
    }

推荐阅读