当前位置: 首页 > 科技观察

Android人脸检测介绍

时间:2023-03-18 17:41:12 科技观察

自PlayServices8.1引入Vision开发库后,开发者可以轻松定位视频或图片中的人脸。只要有一张包含人脸信息的图片,就可以收集每张图片上的人脸信息,比如人脸的位置、是否微笑、睁眼或闭眼,以及他们具体的面部特征。此信息对许多应用程序非常有用。例如,相机应用程序可以使用此信息在每个人睁开眼睛微笑时拍照,或者使用它来添加一些有趣的效果,例如将照片添加到照片中的人的头部。独角兽角。但是大家要注意,这个只能用于人脸检测,不能用于人脸识别。我们只能用它来检测人脸信息,不能用它来判断两张照片是不是同一个人。本教程使用人脸检测API对静态图片进行分析,识别图片中的人物,同时绘制叠加图形。所有教程中使用的代码都可以在GitHub上找到。1.项目配置首先,为了将Vision库添加到您的项目中,您需要将PlayServices8.1或更高版本导入到您的项目中。本教程仅导入PlayServicesVision库。打开你项目中的build.gradle文件,添加如下编译依赖节点代码。compile'com.google.android.gms:play-services-vision:8.1.0'当你在项目中包含PlayServices后,你可以关闭项目中的build.gradle文件,然后打开AndroidManifest.xml文件.将以下数据添加到您的清单文件以定义人脸检测的依赖项。让Vision库知道您将在您的应用程序中使用它。完成AndroidManifest.xml配置后,您可以关闭此文件。接下来,您需要创建一个新的类文件FaceOverlayView.java。该类继承自View类,用于执行人脸检测逻辑、显示分析图像以及在图像上绘制信息以说明视点等功能。现在,我们开始添加成员变量并实现构造函数。Bitmap(位图)对象用于存储待分析的位图数据,SparseArray数组用于存储图像中找到的人脸信息。publicclassFaceOverlayViewextendsView{privateBitmapmBitmap;privateSparseArraymFaces;publicFaceOverlayView(Contextcontext){this(context,null);}publicFaceOverlayView(Contextcontext,AttributeSetattrs){this(context,attrs,0);}publicFaceOverlayView(Contextcontext,Attribute){(上下文,attrs,defStyleAttr);}}然后,我们向FaceOverlayView类添加一个setBitmap(Bitmapbitmap)函数。现在我们只使用这个函数来存储位图对象。稍后我们将使用这种方法来分析位图数据。publicvoidsetBitmap(Bitmapbitmap){mBitmap=bitmap;}接下来,我们需要一个位图图像。我已经在GitHub上的示例项目中添加了一个,当然你可以使用任何你喜欢的图像,看看它是否有效。选择图像后,将其放在res/raw目录中。本教程假定图像名为face.jpg。将图像放入res/raw目录后,打开res/layout/activity_main.xml文件。在这个布局文件中引用一个FaceOverlayView对象,使其显示在MainActivity中。定义布局文件后,打开MainActivity,在onCreate()函数中引用一个FaceOverlayView的实例。通过输入流从raw文件夹中读取face.jpg,并将其转换为位图数据。获得位图数据后,您可以通过调用FaceOverlayView的setBitmap方法在自定义视图中设置位图。publicclassMainActivityextendsAppCompatActivity{privateFaceOverlayViewmFaceOverlayView;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mFaceOverlayView=(FaceOverlayView)findViewById(R.id.face_overlay);InputStreamstream=getResources().openRawResource(R.raw.face);Bitmapbitmap=BitmapFactory.decodeStream(stream);mFaceOverlayView.setBitmap(bitmap);}}2.检测人脸现在你的项目已经设置好了,是时候开始检测人脸了。在setBitmap(Bitmapbitmap)方法中定义一个FaceDetector对象。我们可以通过使用FaceDetector中的构造函数来实现这一点。通过FaceDetector.Builder,您可以定义多个参数来控制FaceDetector生成的人脸检测和其他数据的速度。确切的设置取决于您的应用程序的目的。如果打开面部特征搜索,面部检测速度会变得很慢。在大多数编程中,一切都有其优点和缺点。如果您想了解更多有关FaceDetector.Builder的信息,可以在Android开发者网站上找到官方文档。FaceDetectordetector=newFaceDetector.Builder(getContext()).setTrackingEnabled(false).setLandmarkType(FaceDetector.ALL_LANDMARKS).setMode(FaceDetector.FAST_MODE).build();您需要检查FaceDetector是否正常运行。每当用户第一次在设备上使用面部检测时,PlayServices服务需要加载一组小型原生库来处理应用程序的请求。虽然这些工作一般都在应用程序启动前完成,但也有必要做好故障处理工作。如果FaceDetector是可操作的,那么就需要将位图数据转换成Frame对象,通过detect函数传入,进行人脸数据分析。完成数据分析后,您需要释放探测器以防止内存泄漏。***调用invalidate()函数触发视图刷新。if(!detector.isOperational()){//Handlecontingency}else{Frameframe=newFrame.Builder().setBitmap(bitmap).build();mFaces=detector.detect(frame);detector.release();}无效();现在你已经找到了图片中的人脸信息,可以使用了。例如,您可以在每个检测到的人脸周围画一个框。在invalidate()函数调用之后,我们可以在OnDraw(Canvascanvas)函数中添加所有必要的逻辑。我们需要确保位图和人脸数据有效,然后在画布上绘制位图数据,然后沿着每个人脸的方向绘制一个框。因为不同的设备有不同的分辨率,所以需要控制位图的缩放比例以确保图像始终正确显示。@OverrideprotectedvoidonDraw(Canvascanvas){super.onDraw(canvas);if((mBitmap!=null)&&(mFaces!=null)){doublescale=drawBitmap(canvas);drawFaceBox(canvas,scale);}}drawBitmap(Canvascanvas)方法会以自适应大小在画布上绘制图像,并返回正确的缩放值供您使用。privatedoubledrawBitmap(Canvascanvas){doubleviewWidth=canvas.getWidth();doubleviewHeight=canvas.getHeight();doubleimageWidth=mBitmap.getWidth();doubleimageHeight=mBitmap.getHeight();doublescale=Math.min(viewWidth/imageWidth,viewHeight/imageHeight);RectdestBounds=newRect(0,0,(int)(imageWidth*scale),(int)(imageHeight*scale));canvas.drawBitmap(mBitmap,null,destBounds,null);returnscale;}drawFaceBox(Canvascanvas,doublescale)方法会更有趣。检测到的人脸数据以位置信息的形式存储在mFaces中。该方法会根据这些位置数据的宽度和高度,在检测到的人脸位置绘制一个绿色的矩形框。你需要定义自己的绘图对象,然后循环从你的SparseArray中找出位置、高度和宽度信息,然后使用这些信息在画布上绘制一个矩形。privatevoiddrawFaceBox(Canvascanvas,doublescale){//paintshouldbedefinedasamembervariableratherthan//beingcreatedoneachonDrawrequest,butlefttherefor//emphasis.Paintpaint=newPaint();paint.setColor(Color.GREEN);paint.setStyle(Paint.Style.STROKE);keWtrokthStroke();floatleft=0;floattop=0;floatright=0;floatbottom=0;for(inti=0;i36°右眼、右嘴角、右耳、鼻子、右脸颊如果在人脸检测中,您开启了五官检测,那么您可以方便地使用五官信息。只需要调用getLandmarks()函数就可以得到五官列表,直接使用即可。在本教程中,您可以使用一个新函数drawFaceLandmarks(Canvascanvas,doublescale)在人脸检测中检测到的每个面部特征上绘制一个小圆圈。在onDraw(canvascanvas)函数中,替换为drawFaceLandmarksdrawFaceBox。该方法以每个人脸特征点的位置为中心,自适应位图大小,用圆圈将人脸特征点围起来。privatevoiddrawFaceLandmarks(Canvascanvas,doublescale){Paintpaint=newPaint();paint.setColor(Color.GREEN);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(5);for(inti=0;i