全部产品

本地双录使用文档

创建项目工程

首先打开IDE Android Studio, Android Studio 下载地址请参考这里。

用Android Studio 创建一个项目工程:

11

引入SDK

  1. 在libs目录引入arr文件

2

2. 配置Gradle

3红框处为需要修改的配置

初始化SDK

IdrsSdk.getInstance().init("8D7E82B1-EBD7-40E4-ABC5-F6BF61335936",this,newIdrsSdk.SdkInitCallBack(){
@Override
publicvoid result(finalString message){
                runOnUiThread(newRunnable(){
@Override
publicvoid run(){
Toast.makeText(MainActivity.this, message,Toast.LENGTH_SHORT).show();
}
});
}
});

上方需要填的id是在控制台申请的id,他和你的包名相关联

实现人脸检测

DectetResult[] dectetResult =IdrsSdk.getInstance().startDetectFace(data, width, height, angle, needFlipX);

通过这个方法可以实现人脸检测,其中参数传入

  • data:相机数据

  • width:相机预览宽

  • height:相机预览高

  • angle:旋转角度

  • needFlipX:是否镜像

  • 返回值:会返回图片中人脸的个数和人脸的坐标

根据上方返回值,可以根据返回人脸的坐标绘制人脸框,多次调用不断刷新人脸框的位置,可以实现人脸跟踪

绘制人脸框

可以通过上方的返回值返回的人脸坐标,在加以计算,然后绘制

privatevoid drawFaceRect(Canvas canvas,Paint paint,DectetResult detectResult,int angle,int degree){
float kx =0.0f, ky =0.0f;
// canvas宽高渲染画布的大小,PreviewSize根据info.orientation获取
if((0== angle)||(180== angle)){
            kx =(float) canvas.getWidth()/ cameraView.getPreviewSize().width;
            ky =(float) canvas.getHeight()/ cameraView.getPreviewSize().height;
if((0== degree)||(180== degree)){
// 屏幕竖直方向翻转
}elseif(90== degree ||270== degree){
// 屏幕水平方向翻转
                kx =(float) canvas.getWidth()/ cameraView.getPreviewSize().height;// 960
                ky =(float) canvas.getHeight()/ cameraView.getPreviewSize().width;// 1280
}
}elseif(90== angle ||270== angle){// 一般只有这种情况
            kx =(float) canvas.getWidth()/ cameraView.getPreviewSize().height;// 960
            ky =(float) canvas.getHeight()/ cameraView.getPreviewSize().width;// 1280
if((0== degree)||(180== degree)){
// 屏幕竖直方向翻转
}elseif(90== degree ||270== degree){
// 屏幕水平方向翻转
                kx =(float) canvas.getWidth()/ cameraView.getPreviewSize().width;// 960
                ky =(float) canvas.getHeight()/ cameraView.getPreviewSize().height;// 1280
}
}
// 绘制人脸关键点
float delta =50;
float[] facePoints = detectResult.facePoints;
float left = facePoints[0]* kx;
float y16 = facePoints[16*2+1]* ky;
float y46 = facePoints[46*2+1]* ky;
float top = y46 *2- y16;
float right = facePoints[32*2]* kx;
float bottom = y16;
float actualLeft = left - delta <0?0: left - delta;
float actualTop = top - delta <0?0: top - delta;
float actualRight = right + delta > canvas.getWidth()? canvas.getWidth(): right + delta;
        canvas.drawRect(actualLeft, actualTop, actualRight, bottom, paint);

}

实现人脸对比

publicfloat[] getFeature(DectetResult dectetResult)

首选根据上方的方法获取人脸的特征值,参数传入人脸检测的返回值

publicfloat faceRecognitionSimilarity(float[] features1,float[] features2)

然后根据这个方法,对比俩个人脸特征值的差异,返回分数,一版分数大于0.5就认为是同一个人

实现激活词识别

IdrsSdk.getInstance().startDialogforData(Handler);

上方的方法开启激活词,传入参数Handler同时需要外部传入音频数据去识别

Queue.getInstance().init(1024*1000);
        mAudioRecorder =newAudioRecord(MediaRecorder.AudioSource.CAMCORDER, SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT, WAVE_FRAM_SIZE *4);
        mAudioRecorder.startRecording();
newThread(newRunnable(){
@Override
publicvoid run(){
while(isRecoding){
byte[] bytes =newbyte[640];
int read = mAudioRecorder.read(bytes,0,640);
Queue.getInstance().addAll(bytes);

}
                mAudioRecorder.stop();
}
}).start();

具体做法就是外部开启AudioRecord,拿到音频数据,然后塞入Queue中,然后sdk会不断从Queue中读取音频数据去识别,如果激活词识别成功,会把信息传入到Handler中

if(msg.what ==100){
Gson gson =newGson();
AudioBean audioBean = gson.fromJson((String) msg.obj,AudioBean.class);
Log.d("识别的激活词", audioBean.getWord());
}

实现识别身份证

publicString ocr_run(int width,int height,byte[] data,float[] roi,int rotation,boolean mirror)

上方的方法可以实现识别身份证,其中各个参数含义为

  • width:相机预览宽

  • height:相机预览高

  • data:相机数据

  • roi:识别身份证框的大小

  • rotation:需要旋转的角度

  • mirror:是否镜像

  • 返回值:会返回识别的信息其中重点说下roi参数实际使用中你可能需要提示用户,把身份证放到指定的范围内识别,而roi参数就是根据你指定的范围生成的参数

    privatefloat[] drawIdCardRect(int imageWidth,int imageHeight,String idNumber){
    Canvas canvas =null;
    try{
              canvas = holder.lockCanvas();
    if(canvas ==null){
    returnnull;
    }
              canvas.drawColor(Color.TRANSPARENT,PorterDuff.Mode.CLEAR);
    //计算你指定的范围
    Path path =newPath();
    int left = cameraView.getLeft();
    int right = cameraView.getRight();
    int top = cameraView.getTop();
    int bottom = cameraView.getBottom();
    int middle =(left + right)/2;
    int middle1 =(top + bottom)/2;
    float top1 = middle1 -225;
    float bottom1 = middle1 +225;
    float left1 = middle -300;
    float right1 = middle +300;
              path.moveTo(left1, top1);
              path.rLineTo(50,0);
              path.moveTo(left1, top1);
              path.lineTo(left1, bottom1);
              path.rLineTo(50,0);
              path.moveTo(right1, top1);
              path.rLineTo(-50,0);
              path.moveTo(right1, top1);
              path.lineTo(right1, bottom1);
              path.rLineTo(-50,0);
              canvas.drawPath(path, paint);
              canvas.drawText("请将身份证放到识别框中并静止到识别结果", left1, top1 -50, textidCardPaint);
    if(idNumber !=null){
                  canvas.drawText(idNumber, left1 +50, middle1, textPaint);
    }
    //根据你指定的范围计算roi
    float[] floats =newfloat[4];
              floats[0]= left1 / cameraView.getWidth();
              floats[1]= top1 / cameraView.getHeight();
              floats[2]=(right1 - left1)/ cameraView.getWidth();
              floats[3]=(bottom1 - top1)/ cameraView.getHeight();
    RectF viewRect =newRectF(floats[0], floats[1], floats[0]+ floats[2], floats[1]+ floats[3]);
    RectF frameRect =IdrsSdk.getInstance().viewRectToFrameRect(viewRect, cameraView.getWidth(),
                      cameraView.getHeight(), imageWidth, imageHeight,false,0);
    float[] roi =newfloat[4];
              roi[0]= frameRect.left;
              roi[1]= frameRect.top;
              roi[2]= frameRect.width();
              roi[3]= frameRect.height();
    return roi;
    }catch(Throwable t){
    Log.e("mmm","Draw result error:"+ t);
    }finally{
    if(canvas !=null){
                  holder.unlockCanvasAndPost(canvas);
    }
    }
    returnnull;
    }

实现识别手势

ArrayList<HandDetectionResult> handDetectionResults =IdrsSdk.getInstance().startHandDetection(data, imageWidth, imageHeight, angle, needFlipX);

上方的方法可以实现识别手势,其中参数的含义为

  • data:相机数据

  • imageWidth:相机的预览宽

  • imageHeight:相机的预览高

  • angle:需要旋转的角度

  • needFlipX:是否镜像

  • 返回值:会返回手势的集合和是否识别手势信息

绘制手势框

可以利用上方的返回值来绘制

void drawLines(ArrayList<HandDetectionResult> reports,int angle,int degree){
Canvas canvas =null;
try{
            canvas = holder.lockCanvas();
if(canvas ==null){
return;
}
            canvas.drawColor(Color.TRANSPARENT,PorterDuff.Mode.CLEAR);
for(HandDetectionResult result : reports){
float left = result.left;
float top = result.top;
float right = result.right;
float bottom = result.bottom;
float kx =0.0f, ky =0.0f;
// 这里只写了摄像头正向为90/270度的一般情况,如果有其他情况,自行枚举
// canvas宽高渲染画布的大小,PreviewSize根据info.orientation获取
if((0== angle)||(180== angle)){
                    kx =(float) canvas.getWidth()/ cameraView.getPreviewSize().width;
                    ky =(float) canvas.getHeight()/ cameraView.getPreviewSize().height;
if((0== degree)||(180== degree)){
// 屏幕竖直方向翻转
}elseif(90== degree ||270== degree){
// 屏幕水平方向翻转
                        kx =(float) canvas.getWidth()/ cameraView.getPreviewSize().height;// 960
                        ky =(float) canvas.getHeight()/ cameraView.getPreviewSize().width;// 1280
}
}elseif(90== angle ||270== angle){// 一般只有这种情况
                    kx =(float) canvas.getWidth()/ cameraView.getPreviewSize().height;// 960
                    ky =(float) canvas.getHeight()/ cameraView.getPreviewSize().width;// 1280
if((0== degree)||(180== degree)){
// 屏幕竖直方向翻转
}elseif(90== degree ||270== degree){
// 屏幕水平方向翻转
                        kx =(float) canvas.getWidth()/ cameraView.getPreviewSize().width;// 960
                        ky =(float) canvas.getHeight()/ cameraView.getPreviewSize().height;// 1280
}
}
                canvas.drawLine(left * kx, top * ky,
                        right * kx, top * ky, linePaint);
                canvas.drawLine(right * kx, top * ky,
                        right * kx, bottom * ky, linePaint);
                canvas.drawLine(right * kx, bottom * ky,
                        left * kx, bottom * ky, linePaint);
                canvas.drawLine(left * kx, bottom * ky,
                        left * kx, top * ky, linePaint);
if(result.action.equals("手持手机签字手势")&&!IsSign){
IsSign=true;
                    completeView.setVisibility(View.VISIBLE);
                    completeImageView.setImageResource(R.mipmap.selected);
                    completeTextView.setText("检测到签字动作");
                    mHandler.sendEmptyMessageDelayed(0,3000);
                    mHandler.removeMessages(1);
Log.d("mmm", result.action +"/"+ result.touchphone +"/");
                    canvas.drawText(result.action, left * kx, top * ky -10, lablePaint);
}
                canvas.drawCircle(result.phoneTouchedPointx * kx, result.phoneTouchedPointy * ky,12.0f, numKeyPaint);
}
}catch(Throwable t){
Log.e("mmm","Draw result error:"+ t);
}finally{
if(canvas !=null){
                holder.unlockCanvasAndPost(canvas);
}
}
}

辅助信息上传

拿到上传的地址url

NetworkFactory.getNetwork().ossUpdata(String fileName,NetworkCallBack callBack)

首先调用上方的接口,参数如下

  • fileName:你的meta文件的名字

  • callBack:网络请求结果回调

  • 回调结果:如果成功会返回一个url,这个url用于实现真正的上传上方成功拿到上传的url之后,就可以实现真正的上传了

    NetworkFactory.getNetwork().updataFile((String url,String path,finalNetworkCallBack callBack)

参数如下

  • url:上方返回的url,也是上传的地址

  • path:本地mate文件的路径

  • callBack:网络请求结果回调这个如果调用成功,那么就上传成功了

实现录像

初始化:

Recorder.getInstance().startRecord(Camera.Size sz,String outputFile);

参数如下:

  • Camera.Size sz:就是camera的预览size

  • outputFile:录制的文件位置

  • 当你初始化完成后,需要外部传入视频和音频数据

外部输入视频数据:

@Override
publicvoid onPreviewFrame(byte[] data,Camera camera){
        mRecorder.feedVideoData(data);
}

从相机拿到视频数据,然后送入Recorder中。

外部输入音频数据:

        mAudioRecorder =newAudioRecord(MediaRecorder.AudioSource.CAMCORDER, SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT, WAVE_FRAM_SIZE *4);
        mAudioRecorder.startRecording();
newThread(newRunnable(){
@Override
publicvoid run(){
while(isRecoding){
byte[] bytes =newbyte[640];
int read = mAudioRecorder.read(bytes,0,640);
Recorder.getInstance().feedAudioData(bytes, read);
}
                mAudioRecorder.stop();
}
}).start();

从外部拿到音频数据,然后送入Recorder中。

结束录制

Recorder.getInstance().stopRecord();

调用这个接口会停止录像并生成MP4文件。