创建项目工程
首先打开IDE Android Studio, Android Studio 下载地址请参考这里。
用Android Studio 创建一个项目工程:

引入SDK
在libs目录引入arr文件

2. 配置Gradle
红框处为需要修改的配置
初始化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文件。
在文档使用中是否遇到以下问题
更多建议
匿名提交