1.从开源名片识别demo NameCardRec中提取出工具代码并打包成jar包

将开源名片识别的demo NameCardRec中有关于拍照名片识别的代码进行提取,将提取出来的代码打包成为picocr.Jar文件,导入到项目中。

2.导入so包

so包支持多个平台,包括armeabi,armeabi- v7a,arm64-v8a,x86,x86_64,mips和mips64;每个目录下面包含 libnamecardrec.so包。本so包为底层的图片文字识别的引擎,armeabi,armeabi- v7a,arm64-v8a三个包下放有该so文件(),如果有些机型无法名片识别,建议armeabi,armeabi- v7a,arm64-v8a,x86,x86_64,mips和mips64包下都放 libnamecardrec.so文件。

3.新建图片识别工具类StaticRecFromCamera类

package com.fang.home.crm.utils;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.List;

import java.util.concurrent.atomic.AtomicBoolean;

import com.fang.home.crm.R;

import com.fang.home.crm.activity.AddContactActivity;

import com.fang.home.crm.net.NetApi;

import com.nostra13.universalimageloader.core.ImageLoader;

import cn.sharp.android.ncr.Constants;

import cn.sharp.android.ncr.MessageId;

import cn.sharp.android.ncr.PrefSettings;

import cn.sharp.android.ncr.ScannerAnimation;

import cn.sharp.android.ncr.image.ImageHelper;

import cn.sharp.android.ncr.ocr.OCRItems;

import cn.sharp.android.ncr.ocr.OCRManager;

import cn.sharp.android.ncr.thread.RecThread;

import cn.sharp.android.ncr.thread.StopWorkThread;

import cn.sharp.android.ncr.view.ScannerView;

import android.app.Activity;

import android.app.AlertDialog;

import android.app.Dialog;

import android.app.ProgressDialog;

import android.content.DialogInterface;

import android.content.Intent;

import android.content.SharedPreferences;

import android.content.DialogInterface.OnKeyListener;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.PixelFormat;

import android.hardware.Camera;

import android.hardware.Camera.Parameters;

import android.hardware.Camera.Size;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.preference.PreferenceManager;

import android.util.Log;

import android.view.Display;

import android.view.KeyEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

import android.view.SurfaceHolder.Callback;

import android.view.View.OnClickListener;

import android.widget.ImageButton;

import android.widget.Toast;

/**

* 拍照识别

* @author peng qi

*

*/

public class StaticRecFromCamera extends Activity implements Callback,

OnClickListener {

private final static String TAG = "StaticRecFromCamera";

private final static int DIALOG_REC_FAILURE = 0; // 失败

private final static int DIALOG_REC_SUCCESS = 1; // 成功

private final static int DIALOG_REC_PROGRESS = 2;

private final static int DIALOG_INTERRUPT_DECODE_IMAGE_OR_REC = 5;

private final static int DIALOG_STOP_REC_PROGRESS = 7;

private final static int ACTIVITY_REC_NAMECARD = 0;

public final static int REC_PROGRESS_STYLE_NORMAL = 0; //正常

public final static int REC_PROGRESS_STYLE_SCANNER = 1;//扫描

private final static SimpleDateFormat dateFormat = new SimpleDateFormat(

"yyyy-MM-dd_HH_mm_ss"); //日期格式

private Camera mCamera;

private SurfaceView surfaceView;

private ImageButton btnSnap;

private ShutterCallback shutterCallback;

private RawPictureCallback rawCallback;

private JpegPictureCallback jpegCallback;

private AutoFocusCallback autoFocusCallback;

private PreviewCallback previewCallback;

private ScannerView scannerView;

private OCRManager ocrManager;

private AtomicBoolean isCapturePic;

private AtomicBoolean isLive;

private ScannerAnimation recAnimation;

private boolean isRec;

private boolean isInterruptDialogShown;

private boolean isRecProgressDialogShown;

private boolean isStoppingRec;

private StopWorkThread stopRecThread;

private SharedPreferences preference;

private boolean autoFocus, saveRecImage;

private int recStyle;

private String imgPath;

/** 上传成功的本地图片路径 */

private String succeedPic;

private String oldSucceedImgPath = "";

private Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

Log.e(TAG, "get message, id:" + msg.what);

switch (msg.what) {

//识别成功

case MessageId.NAMECARD_REC_SUCCESS:

isRec = false;

closeCamera();

if (recThread != null) {

recThread = null;

} else {

Log.e(TAG,

"recSuccess msg received, but recThread is null now");

}

//ocrItems中封装识别出来的文字信息

OCRItems ocrItems = (OCRItems) msg.obj;

Log.d(TAG, "start result show activity");

if (saveRecImage && jpegData != null) {

//获取识别出来的文字信息进行相应的处理

}

break;

//识别失败

case MessageId.NAMECARD_REC_FAILURE:

isRec = false;

if (recStyle == REC_PROGRESS_STYLE_NORMAL) {

tryDismissInterruptDialog();

tryDismissRecProgressDialog();

} else if (recStyle == REC_PROGRESS_STYLE_SCANNER) {

scannerView.clearAnimation();

}

if (recThread != null) {

recThread = null;

Log.e(TAG, "rec failure");

showDialog(DIALOG_REC_FAILURE);

} else {

Log.i(TAG,

"recFailure msg received, but recThread is null now");

}

if (isLive.get()) {

rePreview();

Log.d(TAG,

"screen is still alive, camera start  preview after previous rec interrupt");

btnSnap.setEnabled(true);

}

break;

//识别终止

case MessageId.REC_THREAD_STOPPED:

Log.d(TAG, "rec thread stop msg received");

stopRecThread = null;

removeDialog(DIALOG_STOP_REC_PROGRESS);

if (isLive.get()) {

rePreview();

Log.d(TAG,

"screen is still alive, camera start  preview after previous rec interrupt");

btnSnap.setEnabled(true);

}

isRec = false;

isStoppingRec = false;

break;

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

Window win = getWindow();

//保持界面常亮

win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

setContentView(R.layout.rec_camera_preview);

surfaceView = (SurfaceView) findViewById(R.id.camera_preview);

scannerView = (ScannerView) findViewById(R.id.rec_progress_scannerview);

btnSnap = (ImageButton) findViewById(R.id.btn_snap);

btnSnap.setOnClickListener(this);

SurfaceHolder surfaceHolder = surfaceView.getHolder();

surfaceHolder.addCallback(this);

surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

shutterCallback = new ShutterCallback();

jpegCallback = new JpegPictureCallback();

autoFocusCallback = new AutoFocusCallback();

previewCallback = new PreviewCallback();

isCapturePic = new AtomicBoolean();

isLive = new AtomicBoolean();

isPreviewing = false;

isRec = false;

isStoppingRec = false;

ocrManager = new OCRManager(handler);

preference = PreferenceManager.getDefaultSharedPreferences(this);

autoFocus = saveRecImage = false;

scannerView.setVisibility(View.GONE); //不显示

recAnimation = new ScannerAnimation();

}

@Override

protected void onResume() {

super.onResume();

isLive.set(true);

if (!isStoppingRec && !isRec) {

isCapturePic.set(false);

startPreview();

isRecProgressDialogShown = isInterruptDialogShown = false;

/**

* 默认设置为自动对焦,将特定配置属性值放在

*  layout/pref_settings.xml

*/

autoFocus = preference.getBoolean(PrefSettings.PREF_AUTO_FOCUS,

true);

/**

*默认设置为自动对焦,将特定属性值放在

* layout/pref_settings.xml

*/

saveRecImage = preference.getBoolean(

PrefSettings.PREF_SAVE_REC_IMAGE, true);

}

String recStyleStr = preference.getString(

PrefSettings.PREF_REC_PROGRESS_STYLE, "0");

recStyle = 0;

try {

recStyle = Integer.parseInt(recStyleStr);

} catch (NumberFormatException e) {

}

if (saveRecImage

&& !Environment.getExternalStorageState().equals(

Environment.MEDIA_MOUNTED)) {

Toast.makeText(this, R.string.sdcard_no_write_perm,

Toast.LENGTH_SHORT).show();

Log.e(TAG, "image will not be outputed to sdcard");

}

Log.e(TAG, "onResume结束");

}

@Override

protected void onPause() {

super.onPause();

Log.d(TAG, "on pause");

isLive.set(false);

if (isPreviewing)

stopPreview();

closeCamera();

}

@Override

protected void onDestroy() {

Log.d(TAG, "onDestroy()");

super.onDestroy();

}

@Override

protected Dialog onCreateDialog(int id) {

switch (id) {

case DIALOG_REC_FAILURE:

return new AlertDialog.Builder(this)

.setTitle(R.string.error)

.setMessage(R.string.rec_failure)

.setPositiveButton(R.string.cancel,

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog,

int which) {

if (isLive.get()) {

rePreview();

}

}

}).create();

case DIALOG_REC_PROGRESS:

ProgressDialog recProgressDialog = new ProgressDialog(

StaticRecFromCamera.this);

recProgressDialog.setTitle(R.string.waiting);

recProgressDialog.setMessage(getResources().getString(

R.string.rec_in_progress));

recProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);

recProgressDialog.setCancelable(false);

recProgressDialog

.setOnKeyListener(new DialogInterface.OnKeyListener() {

@Override

public boolean onKey(DialogInterface dialog,

int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK) {

Log.d(TAG, "back key pressed while recognizing");

tryDismissRecProgressDialog();

showDialog(DIALOG_INTERRUPT_DECODE_IMAGE_OR_REC);

isInterruptDialogShown = true;

return true;

}

return false;

}

});

isRecProgressDialogShown = true;

return recProgressDialog;

case DIALOG_INTERRUPT_DECODE_IMAGE_OR_REC:

return new AlertDialog.Builder(this)

.setTitle(R.string.warning)

.setMessage(R.string.interrupt_rec_confirm)

.setPositiveButton(R.string.yes,

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog,

int which) {

/**

*

*移除从jpeg中解码bitmap的线程

* dismissDecodeImageProgressDialog();

*/

if (recStyle == REC_PROGRESS_STYLE_NORMAL)

tryDismissRecProgressDialog();

if (isRec) {

if (recThread != null) {

showDialog(DIALOG_STOP_REC_PROGRESS);

recThread.forceStop();

stopRecThread = new StopWorkThread(

recThread,

handler,

MessageId.REC_THREAD_STOPPED);

stopRecThread.start();

recThread = null;

isStoppingRec = true;

Log.i(TAG,

"rec process stopped by user");

} else {

Log.i(TAG, "recThread==null");

}

}

isInterruptDialogShown = false;

Log.d(TAG, "snap button enabled again");

}

})

.setNegativeButton(R.string.no,

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog,

int which) {

isInterruptDialogShown = false;

if (isRec) {

switch (recStyle) {

case REC_PROGRESS_STYLE_NORMAL:

showDialog(DIALOG_REC_PROGRESS);

isRecProgressDialogShown = true;

break;

case REC_PROGRESS_STYLE_SCANNER:

scannerView

.startAnimation(recAnimation);

break;

}

}

}

}).setCancelable(false).create();

case DIALOG_STOP_REC_PROGRESS:

return ProgressDialog.show(StaticRecFromCamera.this, "",

getResources().getString(R.string.stopping_rec));

default:

return super.onCreateDialog(id);

}

}

private void tryDismissRecProgressDialog() {

if (isRecProgressDialogShown) {

removeDialog(DIALOG_REC_PROGRESS);

isRecProgressDialogShown = false;

}

}

private void tryDismissInterruptDialog() {

if (isInterruptDialogShown) {

removeDialog(DIALOG_INTERRUPT_DECODE_IMAGE_OR_REC);

isInterruptDialogShown = false;

}

}

public void surfaceCreated(SurfaceHolder holder) {

// The Surface has been created, acquire the camera and tell it

//视图已被创建,获取系统camera并通知它

Log.v(TAG, "surface created");

}

public void surfaceDestroyed(SurfaceHolder holder) {

//释放camera资源

closeCamera();

}

private int previewHeight = 0, previewWidth = 0;

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

Log.e(TAG, "surface changed");

if (holder.isCreating()) {

Log.e(TAG, "is createing surface holder");

if (!ensureCameraDevice())

return;

if (mCamera != null) {

Camera.Parameters parameters = mCamera.getParameters();

WindowManager windowManager = getWindowManager();

Display display = windowManager.getDefaultDisplay();

int screenWidth = screenWidth = display.getWidth();

int screenHeight = screenHeight = display.getHeight();

parameters.setPictureSize(screenWidth,screenHeight);

parameters.setPictureFormat(PixelFormat.JPEG);

parameters.setPreviewFormat(PixelFormat.YCbCr_420_SP);

mCamera.setPreviewCallback(previewCallback);

mCamera.setParameters(parameters);

}

try {

mCamera.setPreviewDisplay(holder);

} catch (IOException e) {

Log.e(TAG, e.getMessage());

closeCamera();

}

}

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

switch (requestCode) {

case ACTIVITY_REC_NAMECARD:

Log.e(TAG, "rec-result-display activity finished, result code:"

+ requestCode);

finish();

break;

default:

super.onActivityResult(requestCode, resultCode, data);

}

}

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK) {

if (isRec && recStyle == REC_PROGRESS_STYLE_SCANNER) {

scannerView.clearAnimation();

showDialog(DIALOG_INTERRUPT_DECODE_IMAGE_OR_REC);

isInterruptDialogShown = true;

}

//可以实现跳转到特定界面

finish();

return true;

}

return super.onKeyDown(keyCode, event);

}

//点击事件

public void onClick(View v) {

if (v == btnSnap) {

// capture image from camera

Log.e(TAG, "take picture button clicked");

if (mCamera != null) {

Log.e(TAG, "start auto focus");

isCapturePic.set(true);

isPreviewing = false;

v.setEnabled(false);

v.setVisibility(View.INVISIBLE);

mCamera.autoFocus(autoFocusCallback);

} else {

Log.e(TAG, "camera==null");

}

}

}

private class ShutterCallback implements Camera.ShutterCallback {

@Override

public void onShutter() {

// TODO Auto-generated method stub

}

}

private class RawPictureCallback implements Camera.PictureCallback {

@Override

public void onPictureTaken(byte[] data, Camera camera) {

if (data == null) {

Log.i(TAG, "======raw picture callback,data==null");

} else {

Log.i(TAG, "======raw picture callback, data length:"

+ data.length);

}

}

}

//拍照

private class JpegPictureCallback implements Camera.PictureCallback {

public void onPictureTaken(byte[] data, Camera camera) {

if (!isLive.get()) {

Log.i(TAG, "JpegCallback, but activity has paused");

return;

}

Log.d(TAG, "onPictureTaken callback");

isCapturePic.set(false);

if (data == null) {

Log.e(TAG, "do not get any data from camera, data==null");

} else {

Log.v(TAG, "data length:" + data.length);

isPreviewing = false;

switch (recStyle) {

case REC_PROGRESS_STYLE_NORMAL:

showDialog(DIALOG_REC_PROGRESS);

isRecProgressDialogShown = true;

break;

case REC_PROGRESS_STYLE_SCANNER:

scannerView.setVisibility(View.VISIBLE);

Bitmap previewImage = ImageHelper.fromYUV420P(previewData,

previewWidth, previewHeight);

if (previewImage != null) {

scannerView.setBitmap(previewImage);

recAnimation.setBitmap(previewImage);

scannerView.invalidate();

scannerView.startAnimation(recAnimation);

Log.d(TAG, "animation started");

}

break;

}

//启动新线程将图片保存到本地

recThread = new RecThread(data, handler, ocrManager);

recThread.start();

isRec = true;

if (saveRecImage) {

jpegData = data;

}

}

}

}

private byte[] jpegData;

//自动聚焦

private class AutoFocusCallback implements Camera.AutoFocusCallback {

public void onAutoFocus(boolean success, Camera camera) {

if (isCapturePic.get() && isLive.get()) {

if (success) {

isCapturePic.set(false);

Log.v(TAG, "camera focus successfully");

mCamera.takePicture(shutterCallback, rawCallback,

jpegCallback);

} else {

mCamera.autoFocus(this);

Log.i(TAG, "camera cannot focus, retry");

}

}

}

}

private RecThread recThread;

/**

* 存储图片

* @author peng qi

*

*/

/** 图片本地保存 */

class upLoadImageAsyncTask extends AsyncTask<Void, Void, String> {

boolean isCancel = false;

String photo_path = "";

private byte[] jpeg;

public upLoadImageAsyncTask(byte[] jpeg) {

this.jpeg = jpeg;

}

@Override

protected void onPreExecute() {

super.onPreExecute();

isCancel = false;

}

@Override

protected String doInBackground(Void... params) {

if (jpeg != null) {

if (Environment.getExternalStorageState().equals(

Environment.MEDIA_MOUNTED)) {

Bitmap bitmap = BitmapFactory.decodeByteArray(jpeg, 0,

jpeg.length);

if (bitmap == null) {

Log.e(TAG, "cannot decode bitmap");

return "本地保存失败";

}

File file=AlbumAndComera.getTempPath();

imgPath=file.getAbsolutePath();

boolean error = false;

try {

file.createNewFile();

} catch (IOException e1) {

error = true;

}

if (!error) {

OutputStream os;

try {

os = new BufferedOutputStream(new FileOutputStream(

file));

bitmap.compress(Bitmap.CompressFormat.JPEG, 80, os);

Log.d(TAG, "bitmap compress successfully");

} catch (FileNotFoundException e) {

}

} else {

Log.e(TAG, "error when creating image file, filename:"

+ imgPath);

}

} else {

Log.e(TAG, "sdcard not ready");

}

}

return "本地图片保存成功";

}

@Override

protected void onPostExecute(String result) {

super.onPostExecute(result);

// 处理相机上传失败

if (result.equals("本地保存失败")) {

Utils.toast(StaticRecFromCamera.this, "图片本地保存失败");

return;

}

if (!isCancel) {

UtilsLog.i(TAG, "最后显示路径:" + imgPath.trim());

String url = imgPath.trim();

oldSucceedImgPath = url;

noticeRefresh(new File(oldSucceedImgPath));

tryDismissInterruptDialog();

tryDismissRecProgressDialog();

//此处可以实现页面跳转

}

}

//通知系统媒体库刷新媒体库数据

private void noticeRefresh(File tempFile) {

Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);

Uri uri = Uri.fromFile(tempFile);

intent.setData(uri);

StaticRecFromCamera.this.sendBroadcast(intent);

}

private boolean isPreviewing;

//判断相机资源状态

private boolean ensureCameraDevice() {

if (mCamera == null) {

mCamera = Camera.open();

}

return mCamera != null;

}

//开始相机预览

private void startPreview() {

if (!ensureCameraDevice()) {

Log.e(TAG, "cannot open camera device");

return;

}

if (!isPreviewing) {

mCamera.startPreview();

isPreviewing = true;

Log.e(TAG, "camera started");

} else {

Log.e(TAG, "camera has started previewing");

}

}

//名片识别失败后,重新启动相机预览

private void rePreview() {

if (mCamera != null) {

if (!isPreviewing) {

if (recStyle == REC_PROGRESS_STYLE_SCANNER) {

scannerView.setVisibility(View.GONE);

}

mCamera.startPreview();

isPreviewing = true;

btnSnap.setVisibility(View.VISIBLE);

} else {

Log.i(TAG, "camera has started previewing");

}

} else {

Log.e(TAG, "cannot repreview, mCamera==null");

}

}

//停止相机预览

private void stopPreview() {

if (mCamera != null) {

mCamera.stopPreview();

isPreviewing = false;

Log.e(TAG, "camera stopped");

}

}

//关闭相机

private void closeCamera() {

if (mCamera != null) {

mCamera.release();

isPreviewing = false;

mCamera = null;

Log.e(TAG, "camera released");

}

}

private class PreviewCallback implements Camera.PreviewCallback {

public void onPreviewFrame(byte[] data, Camera camera) {

Log.v(TAG, "preview callback");

if (mCamera != null && isPreviewing) {

previewData = data;

if (autoFocus)

mCamera.autoFocus(autoFocusCallback);

}

}

}

private byte[] previewData;

@Override

public void onLowMemory() {

super.onLowMemory();

Log.i(TAG, "on low memory");

}

}

4.配置AndroidManifest.xml

添加权限:在<manifest>标签下:

<!-- 必选 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.CAMERA" />

<uses-permission android:name="android.permission.READ_CONTACTS" />

<uses-permission android:name="android.permission.WRITE_CONTACTS" />

5.将res文件夹下相应文件复制到项目中;

需要的同学可以联系我,我可以把提取出来的picocr.Jar和so文件以及res文件夹发给你。
6.

名片识别jar文件和so文件下载地址

Android名片识别相关推荐

  1. android 名片识别 简书,名片扫描识别API

    关键词:名片识别 移动端名片识别 云端名片识别 服务器端名片识别 名片识别SDK 名片识别api 一.名片识别背景 随着计算机技术的迅猛发展,电子化的名片变得越来越流行, 交换变得越来越方便.利用手机 ...

  2. android 名片识别 简书,nodejs实现名片识别

    一.说明: 百度云提供了名片识别的api,每天可以免费调用500次:https://cloud.baidu.com/product/ocr/cards 因此,需要先上百度云注册一个开发者应用 二.名片 ...

  3. android 名片识别软件,手机名片识别工具Android名片全能王评测

    人与人之间的关系是需要交流来建立的,所以难免的在职场上,官场上等各种场上会碰到这样那样的朋友,当然也会结实到新的朋友,当然也会收到很多名片!难道还要手动来一个一个存到手机的通讯录中吗?不.我们不要!接 ...

  4. android 名片识别 简书,python 腾讯API 名片识别 通用图片转文字

    记录名片识别和图片转文字. 腾讯AI开放平台提供的名片OCR很强大, 而且可以免费使用, 所以本文使用的是腾讯AI开放平台. 腾讯AI开放平台API调用需要注意签名方法, 请查看之前文章传送门 名片O ...

  5. android 名片识别 简书,iOS 自己实现 名片识别 三 图片处理

    主题: 图片处理 声明:下面这些图片仅供学习使用 0.png 1.剪切图片 根据矩形特征剪切图片 // @property (nonatomic , strong) CIImage *img; //@ ...

  6. android 名片识别 简书,iOS 自己实现 名片识别 四 图片转文字以及归类

    本页主题: 图片转文字以及归类 先看效果展示 原图: 原图 处理后: result OCR识别效果: 量 U ::; 愧睡酣苒 `:| . - @ 唧涮区 总 代埋 í 倪礼波经理 展厅: 西部家具城 ...

  7. android 名片识别 简书,简书,也有了我的名片

    0.1,0.09,写一篇文章,获赠简书钻数少得可怜,尽管少了点,我是在一丁点.一丁点积累到了现在,写了十四.五万的文字,总数还不足40:不过看着简书钻数值排行榜的名次,上升了不少,这也给了自己创作一点 ...

  8. Android名片扫描识别系统SDK

    Android名片扫描识别系统SDK 一.Android名片扫描识别系统应用背景 这些年,随着移动互联的发展,APP应用成爆发式的增长,在很多APP中都涉及到对名片信息的录入,如移动CRM.移动端OA ...

  9. Android图像识别扫名片识别技术SDK

    Android图像识别扫名片识别技术SDK 一.Android图像识别扫名片识别技术应用背景 这些年,随着移动互联的发展,APP应用成爆发式的增长,在很多APP中都涉及到对名片信息的录入,如移动CRM ...

最新文章

  1. 31万奖金算法赛事来了!
  2. GPU — Overview
  3. 给正在为就业苦恼的应届生
  4. Service Mesh 是新瓶装旧酒吗?
  5. CVPR2020 | 参数量减半,北大开源全新高效空域转换模块,还原图像逼真细节
  6. debian 安装php gd2,如何在Debian Linux中为PHP安装Ioncube
  7. 作者:潘永花,阿里数据经济研究中心秘书长,阿里研究院高级专家。
  8. java 从键盘中读取字符流 自定义异常
  9. 冬季打针后忌用手按摩
  10. 雨林木风工具箱 3.5
  11. 视频倒立解决方法/USB 视频设备ID:USB\VID_13D3PID_5130MI_00\621DA5E0900000
  12. vue下载二进制流图片
  13. contour 函数详解
  14. 2021支付宝集五福活动开启啦,集卡攻略来啦
  15. 企业数据中心“云化”转型解决方案
  16. 香农编码C程序及演示结果
  17. ESP8266之AP模式
  18. atom安装插件被墙问题
  19. JS常用工具函数-中文按拼音排序
  20. 计算机网络安全课题研究,网络安全研究的课题题目参考

热门文章

  1. Opencv中视频播放与进度控制
  2. XCO-JS 1.0.1使用教程
  3. 生物冰箱智能锁有哪些功能
  4. qt 绘制五角星图形
  5. SHERlocked93 的 2019 年终总结
  6. 酒桌上应对(from:http://www.haozai.com/bbs/dispbbs.asp?boardID=6ID=106page=1)
  7. 零基础转行大数据怎么学习?大数据学习路线
  8. Xshell 6链接Liunx链接不上:
  9. C语言实现计算数的整数次幂
  10. 数据集成-5-批数据集成