android实现人脸识别技术的示例代码

1.前沿

人工智能时代快速来临,其中人脸识别是当前比较热门的技术,在国内也越来越多的运用,例如刷脸打卡,刷脸APP,身份识别,人脸门禁等。当前的人脸识别技术分为WEBAPI和SDK调用两种方式,WEBAPI需要实时联网,SDK调用可以离线使用。

本次使用的虹软提供的人脸识别的SDK,此SDK也可根据不同应用场景设计,针对性强。包括人脸检测、人脸跟踪、人脸识别,即使在离线环境下也可正常运行。

虹软公司是一家具有硅谷背景的图像处理公司,除了人脸技术以外,还有多项图像及视频处理技术。他们的双摄像头处理算法和人脸美化算法囊括了包括OPPO VIVO,SUMAMNG一系列手机厂商。

2.项目的目标

我们需要实现一个人脸识别功能。简单来说,就是机的后置摄像头,识别摄像头中实时拍到的人脸信息,如果人库注册过,则显示识别后的人脸信息,如登记的名字;如果不在,提示未注册。
这个功能具有多个应用场景,比如,火车站或者打卡和门禁系统中。

3.人脸识别的过程

人脸识别包括两个必备的过程,人脸注册和实时识别。
人脸注册是指把人脸的特征信息注册到人脸信息库中。人脸注册的来源可以有很多种,比如

  1. 国家身份证库
  2. 企业自建人脸识别库
  3. 互联网大数据库

人脸特征提取是一个不可逆的过程,你无法从人脸特征信息还原一个人的脸部照片。

在线库在使用时,需要传递照片信息,或者提取图像特征值,

离线的SDK相对安全,但是,在线的SDK通常提供更多的接入和调用方式,这个要结合实际情况来选择。

4.定义并实现人脸库的相关功能

如前面所述,我们希望定义自己 的人脸库,人脸库在程序中使用List存储,在系统中保存为txt文件。

通过查询引擎,可以知道人脸信息是保存在AFR_FSDKFace类中的。这的主要结构为

 public static final int FEATURE_SIZE = 22020;
 byte[] mFeatureData;

如果要进行人脸注册,我们需要定义另外一个类来把人脸信息和姓名关联起来。

class FaceRegist {
    String mName;
    List<AFR_FSDKFace> mFaceList;

    public FaceRegist(String name) {
      mName = name;
      mFaceList = new ArrayList<>();
    }
  }

包含特征信息的长度和内容的byte数组。

我们把这些功能定义在类FaceDB中。FaceDB需要包含引擎定义,初始化,把人脸信息保存在版本库和从版本库中读出人脸信息这些功能

5.初始化引擎

为了程序结构性考虑,我们将人脸识别相关的代码独立出来一个类FaceDB,并定义必要的变量

public static String appid = "bCx99etK9Ns4Saou1EbFdC18xHdY9817EKw****";
public static String ft_key = "CopwZarSihp1VBu5AyGxfuLQdRMPyoGV2C2opc****";
public static String fd_key = "CopwZarSihp1VBu5AyGxfuLXnpccQbWAjd86S8****";
public static String fr_key = "CopwZarSihp1VBu5AyGxfuLexDsi8yyELdgsj4****";

String mDBPath;
List<FaceRegist> mRegister;
AFR_FSDKEngine mFREngine;
AFR_FSDKVersion mFRVersion;

定义有参数的构造函数来初始化引擎

public FaceDB(String path) {
    mDBPath = path;
    mRegister = new ArrayList<>();
    mFRVersion = new AFR_FSDKVersion();
    mUpgrade = false;
    mFREngine = new AFR_FSDKEngine();
    AFR_FSDKError error = mFREngine.AFR_FSDK_InitialEngine(FaceDB.appid, FaceDB.fr_key);
    if (error.getCode() != AFR_FSDKError.MOK) {
      Log.e(TAG, "AFR_FSDK_InitialEngine fail! error code :" + error.getCode());
    } else {
      mFREngine.AFR_FSDK_GetVersion(mFRVersion);
      Log.d(TAG, "AFR_FSDK_GetVersion=" + mFRVersion.toString());
    }
  }

定义析构函数释放引擎占用的系统资源

public void destroy() {
    if (mFREngine != null) {
      mFREngine.AFR_FSDK_UninitialEngine();
    }
  }

6.实现人脸增加和读取功能

通常人脸库会存放在数据库中,本次我们使用List来进行简单的模拟,并将其保存在文本文件中,需要时从文本中读取,保存时写入到文件中。

我们使用addFace方法将待注册的人脸信息添加到人脸库中

public void addFace(String name, AFR_FSDKFace face) {
    try {
      //check if already registered.
      boolean add = true;
      for (FaceRegist frface : mRegister) {
        if (frface.mName.equals(name)) {
          frface.mFaceList.add(face);
          add = false;
          break;
        }
      }
      if (add) { // not registered.
        FaceRegist frface = new FaceRegist(name);
        frface.mFaceList.add(face);
        mRegister.add(frface);
      }

      if (!new File(mDBPath + "/face.txt").exists()) {
        if (!saveInfo()) {
          Log.e(TAG, "save fail!");
        }
      }

      //save name
      FileOutputStream fs = new FileOutputStream(mDBPath + "/face.txt", true);
      ExtOutputStream bos = new ExtOutputStream(fs);
      bos.writeString(name);
      bos.close();
      fs.close();

      //save feature
      fs = new FileOutputStream(mDBPath + "/" + name + ".data", true);
      bos = new ExtOutputStream(fs);
      bos.writeBytes(face.getFeatureData());
      bos.close();
      fs.close();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

使用loadFaces从文件中读取人脸

public boolean loadFaces(){
    if (loadInfo()) {
      try {
        for (FaceRegist face : mRegister) {
          Log.d(TAG, "load name:" + face.mName + "'s face feature data.");
          FileInputStream fs = new FileInputStream(mDBPath + "/" + face.mName + ".data");
          ExtInputStream bos = new ExtInputStream(fs);
          AFR_FSDKFace afr = null;
          do {
            if (afr != null) {
              if (mUpgrade) {
                //upgrade data.
              }
              face.mFaceList.add(afr);
            }
            afr = new AFR_FSDKFace();
          } while (bos.readBytes(afr.getFeatureData()));
          bos.close();
          fs.close();
        }
        return true;
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
    } else {
      if (!saveInfo()) {
        Log.e(TAG, "save fail!");
      }
    }
    return false;
  }

7.实现业务逻辑

7.1实现人脸注册功能

人脸识别的前提条件就是人脸信息要先注册到人脸库中,注册人脸库

第一步当然是获取待注册的照片,我们可以可以使用摄像头,也可以使用照片。我们使用AlertDialog弹出选择框

new AlertDialog.Builder(this)
            .setTitle("请选择注册方式")
            .setIcon(android.R.drawable.ic_dialog_info)
            .setItems(new String[]{"打开图片", "拍摄照片"}, this)
            .show();

在对应的事件处理函数中进行处理

switch (which){
  case 1://摄像头
    Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");
    ContentValues values = new ContentValues(1);
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
    mPath = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT, mPath);
    startActivityForResult(getImageByCamera, REQUEST_CODE_IMAGE_CAMERA);
    break;
  case 0://图片
    Intent getImageByalbum = new Intent(Intent.ACTION_GET_CONTENT);
    getImageByalbum.addCategory(Intent.CATEGORY_OPENABLE);
    getImageByalbum.setType("image/jpeg");
    startActivityForResult(getImageByalbum, REQUEST_CODE_IMAGE_OP);
    break;
  default:;
}

获取一张照片后,后续我们就需要实现人脸检测功能。

if (requestCode == REQUEST_CODE_IMAGE_OP && resultCode == RESULT_OK) {
      mPath = data.getData();
      String file = getPath(mPath);
      //TODO: add image coversion
    }

在上面的代码中,我们获取到了我们需要的图像数据bmp,把图片取出来

我们在Application类用函数 decodeImage中实现这段代码

public static Bitmap decodeImage(String path) {
    Bitmap res;
    try {
      ExifInterface exif = new ExifInterface(path);
      int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

      BitmapFactory.Options op = new BitmapFactory.Options();
      op.inSampleSize = 1;
      op.inJustDecodeBounds = false;
      //op.inMutable = true;
      res = BitmapFactory.decodeFile(path, op);
      //rotate and scale.
      Matrix matrix = new Matrix();

      if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
        matrix.postRotate(90);
      } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
        matrix.postRotate(180);
      } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
        matrix.postRotate(270);
      }

      Bitmap temp = Bitmap.createBitmap(res, 0, 0, res.getWidth(), res.getHeight(), matrix, true);
      Log.d("com.arcsoft", "check target Image:" + temp.getWidth() + "X" + temp.getHeight());

      if (!temp.equals(res)) {
        res.recycle();
      }
      return temp;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

调用AFD_FSDK_StillImageFaceDetection返回检测到的人脸信息

人脸注册 ,首先要先检测出来人脸,对于静态图片,虹软人脸SDK中对应的是FD,提供了一个方法名称,叫AFD_FSDK_StillImageFaceDetection 。

我们来看一下参数列表

注意AFD_FSDKFace对象引擎内部重复使用,如需保存,请clone一份AFD_FSDKFace对象或另外保存

AFD_FSDKFace是人脸识别的结果,定义如下

public class AFD_FSDKFace {
  Rect mRect;
  int mDegree;
  }

mRect定义一个了一个矩形框Rect

在此之前我们需要注意虹软人脸SDK使用的图像格式是NV21的格式,所以我们需要将获取到的图像转化为对应的格式。在Android_extend.jar中提供了对应的转换函数

byte[] data = new byte[mBitmap.getWidth() * mBitmap.getHeight() * 3 / 2];
        ImageConverter convert = new ImageConverter();
        convert.initial(mBitmap.getWidth(), mBitmap.getHeight(), ImageConverter.CP_PAF_NV21);
        if (convert.convert(mBitmap, data)) {
          Log.d(TAG, "convert ok!");
        }
        convert.destroy();

现在我们就可以调用AFD_FSDK_StillImageFaceDetection方法了

8.绘出人脸框

在List<AFD_FSDKFace>中保存了检测到的人脸的位置信息和深度信息。

我们可以将检测到的人脸位置信息在图片上用一个矩形框绘制出来表示检测到的人脸信息。

Canvas canvas = mSurfaceHolder.lockCanvas();
  if (canvas != null) {
   Paint mPaint = new Paint();
   boolean fit_horizontal = canvas.getWidth() / (float)src.width() < canvas.getHeight() / (float)src.height() ? true : false;
   float scale = 1.0f;
   if (fit_horizontal) {
     scale = canvas.getWidth() / (float)src.width();
     dst.left = 0;
     dst.top = (canvas.getHeight() - (int)(src.height() * scale)) / 2;
     dst.right = dst.left + canvas.getWidth();
     dst.bottom = dst.top + (int)(src.height() * scale);
   } else {
     scale = canvas.getHeight() / (float)src.height();
     dst.left = (canvas.getWidth() - (int)(src.width() * scale)) / 2;
     dst.top = 0;
     dst.right = dst.left + (int)(src.width() * scale);
     dst.bottom = dst.top + canvas.getHeight();
   }
   canvas.drawBitmap(mBitmap, src, dst, mPaint);
   canvas.save();
   canvas.scale((float) dst.width() / (float) src.width(), (float) dst.height() / (float) src.height());
   canvas.translate(dst.left / scale, dst.top / scale);
   for (AFD_FSDKFace face : result) {
     mPaint.setColor(Color.RED);
     mPaint.setStrokeWidth(10.0f);
     mPaint.setStyle(Paint.Style.STROKE);
     canvas.drawRect(face.getRect(), mPaint);
   }
   canvas.restore();
   mSurfaceHolder.unlockCanvasAndPost(canvas);
   break;
  }
}

9.将人脸注册到人脸库

检测到了人脸,我们可以输入相应的描述信息,加入到人脸库中。

为了提高识别的准确性,我们可以对一个人多次注册人脸信息。

public void addFace(String name, AFR_FSDKFace face) {
  try {
   //check if already registered.
   boolean add = true;
   for (FaceRegist frface : mRegister) {
     if (frface.mName.equals(name)) {
      frface.mFaceList.add(face);
      add = false;
      break;
     }
   }
   if (add) { // not registered.
     FaceRegist frface = new FaceRegist(name);
     frface.mFaceList.add(face);
     mRegister.add(frface);
   }

   if (!new File(mDBPath + "/face.txt").exists()) {
     if (!saveInfo()) {
      Log.e(TAG, "save fail!");
     }
   }
   //save name
   FileOutputStream fs = new FileOutputStream(mDBPath + "/face.txt", true);
   ExtOutputStream bos = new ExtOutputStream(fs);
   bos.writeString(name);
   bos.close();
   fs.close();
   //save feature
   fs = new FileOutputStream(mDBPath + "/" + name + ".data", true);
   bos = new ExtOutputStream(fs);
   bos.writeBytes(face.getFeatureData());
   bos.close();
   fs.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
}

最后,别忘记了销毁人脸检测引擎

err = engine.AFD_FSDK_UninitialFaceEngine();
Log.d("com.arcsoft", "AFD_FSDK_UninitialFaceEngine =" + err.getCode()); 

10.实现人脸识别

上面的代码准备完毕后,就可以开始我们的人脸识别的功能了。我们使用一个第三方的扩展库,ExtGLSurfaceView的扩展 库CameraGLSurfaceView,用ImageView和TextView显示检测到的人脸和相应的描述信息。

首先是定义layout。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

  <com.guo.android_extend.widget.CameraSurfaceView
    android:id="@+id/surfaceView"
    android:layout_width="1dp"
    android:layout_height="1dp"/>

  <com.guo.android_extend.widget.CameraGLSurfaceView
    android:id="@+id/glsurfaceView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"/>

  <ImageView
    android:id="@+id/imageView"
    android:layout_width="120dp"
    android:layout_height="120dp"
    android:layout_marginLeft="10dp"
    android:layout_marginTop="10dp"/>

  <TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/imageView"
    android:layout_alignRight="@+id/imageView"
    android:layout_below="@+id/imageView"
    android:layout_marginTop="10dp"
    android:text="@string/app_name"
    android:textAlignment="center"/>

  <TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/imageView"
    android:layout_alignRight="@+id/imageView"
    android:layout_below="@+id/textView"
    android:layout_marginTop="10dp"
    android:text="@string/app_name"
    android:textAlignment="center"/>
</RelativeLayout>

因为引擎需要的图像格式是NV21的,所以需要将摄像头中的图像格式预设置为NV21

public Camera setupCamera() {
  // TODO Auto-generated method stub
  mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
  try {
   Camera.Parameters parameters = mCamera.getParameters();
   parameters.setPreviewSize(mWidth, mHeight);
   parameters.setPreviewFormat(ImageFormat.NV21);

   for( Camera.Size size : parameters.getSupportedPreviewSizes()) {
     Log.d(TAG, "SIZE:" + size.width + "x" + size.height);
   }
   for( Integer format : parameters.getSupportedPreviewFormats()) {
     Log.d(TAG, "FORMAT:" + format);
   }

   List<int[]> fps = parameters.getSupportedPreviewFpsRange();
   for(int[] count : fps) {
     Log.d(TAG, "T:");
     for (int data : count) {
      Log.d(TAG, "V=" + data);
     }
   }
   mCamera.setParameters(parameters);
  } catch (Exception e) {
   e.printStackTrace();
  }
  if (mCamera != null) {
   mWidth = mCamera.getParameters().getPreviewSize().width;
   mHeight = mCamera.getParameters().getPreviewSize().height;
  }
  return mCamera;
}

从摄像头识别人脸,需要使用FT库,FT库在人脸跟踪算法上对人脸检测部分进行了优化,是专门为视频处理而优化的库。

11.初始化人脸检测引擎(FT)

和FD一样,我们需要初始化人脸识别FT引擎。

Log.d(TAG, "AFT_FSDK_InitialFaceEngine =" + err.getCode());
err = engine.AFT_FSDK_GetVersion(version);
Log.d(TAG, "AFT_FSDK_GetVersion:" + version.toString() + "," + err.getCode());

在摄像头的预览事件处理函数中,先调用FT的人脸识函数函数,然后再调用FR中的人脸信息特征提取数函数。

AFT_FSDKError err = engine.AFT_FSDK_FaceFeatureDetect(data, width, height, AFT_FSDKEngine.CP_PAF_NV21, result);

AFR_FSDKError error = engine.AFR_FSDK_ExtractFRFeature(mImageNV21, mWidth, mHeight, AFR_FSDKEngine.CP_PAF_NV21,mAFT_FSDKFace.getRect(), mAFT_FSDKFace.getDegree(), result);

这里面的result中保存了人脸特征信息。我们可以将其保存下来或下来并与系统中的其它信息进行对比。

AFR_FSDKMatching score = new AFR_FSDKMatching();
float max = 0.0f;
String name = null;
for (FaceDB.FaceRegist fr : mResgist) {
  for (AFR_FSDKFace face : fr.mFaceList) {
   error = engine.AFR_FSDK_FacePairMatching(result, face, score);
   Log.d(TAG, "Score:" + score.getScore() + ", AFR_FSDK_FacePairMatching=" + error.getCode());
   if (max < score.getScore()) {
     max = score.getScore();
     name = fr.mName;
   }
  }
}

当score的特征信息大于0.6时,我们就可以认为匹配到了人脸。显示人脸匹配信息。

上面的循环中,可以看到,是遍历了真个库进行寻找。我们的目的是为了演示,实际情况下,我们可以在找到一个匹配值比较高的人脸后,就跳出循环。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Android人脸识别Demo竖屏YUV方向调整和图片保存(分享)
  • Android camera实时预览 实时处理,人脸识别示例
(0)

相关推荐

  • Android人脸识别Demo竖屏YUV方向调整和图片保存(分享)

    本博客包含三个常用方法,用于盛开Android版人脸识别Demo中竖屏使用时送入yuv数据,但一直无法识别的情况. 1.首先可以尝试顺时针旋转90°或270°,然后送入识别SDK. 2.旋转方向后依然无法识别时,可以尝试saveImg( ),保存本地检查图片是否符合要求. /** * 视频顺时针旋转90 * 该方法仅仅在竖屏时候使用 * */ public static byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int im

  • Android camera实时预览 实时处理,人脸识别示例

    Android camera实时预览 实时处理,面部认证. 预览操作是网友共享的代码,我在继承SurfaceView 的CameraSurfaceView 中加入了帧监听事件,每次预览监听前五个数据帧,在处理做一个面部识别. 先看目录关系 自定义控件CameraSurfaceView.java 自定义接口方法CameraInterface.java CameraActivity预览界面. CameraSurfaceView.Java package com.centaur.camera.prev

  • android实现人脸识别技术的示例代码

    1.前沿 人工智能时代快速来临,其中人脸识别是当前比较热门的技术,在国内也越来越多的运用,例如刷脸打卡,刷脸APP,身份识别,人脸门禁等.当前的人脸识别技术分为WEBAPI和SDK调用两种方式,WEBAPI需要实时联网,SDK调用可以离线使用. 本次使用的虹软提供的人脸识别的SDK,此SDK也可根据不同应用场景设计,针对性强.包括人脸检测.人脸跟踪.人脸识别,即使在离线环境下也可正常运行. 虹软公司是一家具有硅谷背景的图像处理公司,除了人脸技术以外,还有多项图像及视频处理技术.他们的双摄像头处理

  • 微信小程序实现人脸识别登陆的示例代码

    前言 这是一篇关于一个原创微信小程序开发过程的原创文章.涉及到的核心技术是微信小程序开发方法和百度云人脸识别接口.小程序的主体是一个用于个人密码存储的密码管理器,在登陆注册阶段,需要调用百度云人脸识别接口以及百度云在线人脸库的管理接口.本文主要涉及登陆注册模块的实现,而且不需要PHP后台代码,完全在线调用接口实现,希望后来的你能有所收获! 步骤 步骤 涉及接口(百度云) 拍摄或者相册选择 并 上传比对样本照片到 人脸库 人脸库管理接口(main:人脸注册) 拍摄照片并上传,云服务器在线比对 人脸

  • Android开发人脸识别统计人脸数

    本文实例为大家分享了Android开发人脸识别统计的具体代码,供大家参考,具体内容如下 最近项目需求是统计当前摄像头中的人脸个数,安卓有提供现成的Api,最终实现效果如上图. 分析思路和步奏: 主要使用到的类:SurfaceView.CameraManager.CameraDevice.StateCallback.CameraCaptureSession.StateCallback. 1.通过SurfaceView展示预览区. 2.在SurfaceView创建成功后通过CameraManager

  • Android开发人脸识别登录功能

    近来,很多公司的APP都实现了人脸识别登录的功能.今天呢,银鹏带大家从头到尾做一下这个人脸识别登录. 首先呢,我们需要采用一个拥有人脸识别算法的平台,这边我建议使用虹软的人脸识别,因为我个人用的就是这个,关键有一点好处,就是免费.注册链接:点击进入注册. 注册完毕以后,话不多说,我们进入流程. 第一步:在虹软平台创建应用 直接安装SDK查看激活码 下载虹软识别库地址:点击下载识别库 下载好之后进行依赖添加: implementation 'com.github.tyhjh:PermissionU

  • python3.8动态人脸识别的实现示例

    一.准备依赖库 pip install dlib pip python-opencv 二.代码实现  #coding: utf-8 """ 从视屏中识别人脸,并实时标出面部特征点 """ import dlib #人脸识别的库dlib import cv2 #图像处理的库OpenCv # 使用特征提取器get_frontal_face_detector detector = dlib.get_frontal_face_detector() # 读

  • SpringBoot+Tess4j实现牛逼的OCR识别工具的示例代码

    前言 " 等不到风中你的脸颊 眼泪都美到很融洽 等不到掩饰的雨落下 我的眼泪被你察觉 " 听着循环的歌曲,写着久违的bug.好吧,还是一天.正好一个小伙伴说,要不要做个工具站玩一下.我就随意的找了个工具站,看了下,发现很多都有文字的OCR识别功能.因此,我想起来之前了解的非常流行的开源的OCR大神级别的项目,Tesseract OCR. 简单介绍 官网如下所示 tesseract-ocr.github.io/ 简洁明了,挂在github上的网站. 详细的不再介绍,感兴趣的,可以进入同志

  • 基于Docker+Selenium Grid的测试技术应用示例代码

    Selenium Grid介绍 尽管在未来将会推出的Selenium 4.0版本中对Selenium Grid的一些新特性进行了说明,但是目前来看官方并没有太多详细文档供大家参考,所以本书中仍结合目前被广泛使用的Selenium Grid 版本进行讲解. 正如其官网对Selenium Grid的描述,它是一个智能代理服务器,允许Selenium测试将命令路由到远程Web浏览器实例.其目的是提供一种在多台计算机上并行运行测试的简便方法.使用Selenium Grid,一台服务器充当将JSON格式的

  • uniapp app 人脸识别的实现示例

    由于 小程序端 有camera组件 直接就可以调起摄像头 但是 app端是不支持这个标签的 所以只能用其他的方法 使用 nvue 中 live-pusher 组件 子组件 <template> <div> <div class="livefater"> <div style="width: 300px;height: 300px;border-radius: 150px;overflow: hidden;"> <

  • Android实现用文字生成图片的示例代码

    本文介绍了Android实现用文字生成图片的示例代码,分享给大家,具体如下: 效果图 我们先来看看效果图,可以看到下图由各种颜色的"美"字拼接而成,形成了一张不一样的图片. 原理 生成这种图片的原理很简单,但是当时看开源项目时愣是看不懂,因为没学过Python,但是仔细研究,终于能慢慢的理解该开源项目源码,并把它改写成Android平台的源代码.下面把这个算法的主要内容讲给大家,该算法大致原理如下: 1.根据原图片的大小和字体的大小创建一张空白图片 2.把原图片按字体的大小分成若干块,

  • Android自定义滑动验证条的示例代码

    本文介绍了Android自定义滑动验证条的示例代码,分享给大家,具体如下: *注:不知道为什么,h5的标签在这里没用了,所以我也只能用Markdown的语法来写了 项目地址:https://github.com/994866755/handsomeYe.seekbar.github.io 需求: 在我们的某些应用中需要滑动验证.比如说这个样子的: 刚开始我也很懵逼要怎么去弄,结果我去看了一些人的代码,有人是用自定义viewgroup去做,就是viewgroup包含滑动块和滑动条.但我觉得太麻烦,

随机推荐