OCR 是什么?
:OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程;
百度OCR 能做什么?
- 通用文字识别
- 身份证识别
- 银行卡识别
- 网络图片文字识别
- 通用文字识别(含位置信息)
- 通用文字识别(含生僻字)
如何集成使用OCR
目前Android这块没有理想的免费OCR开源框架,项目需要,我们选择了百度的OCR 产品;
这里以AS开发环境,身份证信息识别功能为例,阐述集成使用ORC的过程;
官网相关连接
百度视觉技术 文字识别_API文档
1.下载对应的Android SDK 下载地址 使用说明
2.有兴趣的可以运行下Demo,我这里直接集成其中ocr_ui文件(依赖该Moudle,相关so库也在改Moudle中)
3.(必须)将下载包libs目录中的ocr-sdk.jar文件拷贝到工程libs目录中,并加入工程依赖。
4.(必须)将libs目录下armeabi,arm64-v8a,armeabi-v7a,x86文件夹按需添加到android studio工程src/main/jniLibs
5.确保已经在工程AndroidManifest.xml文件中添加如下权限:
项目代码
Xm 代码
逻辑代码(可直接复制使用)
public class OCRActivity extends AppCompatActivity {
private ProgressDialog dialog;
// 标识
private static boolean hasGotToken = false;
private static final int REQUEST_CODE_CAMERA = 102;
private static final String APIKey = "官网上传包名的APIKey";
private static final String SecretKey = "官网上传包名的SecretKey";
private ImageView iv;
public static void start(Activity activity) {
Intent intent = new Intent(activity, OCRActivity.class);
activity.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ocr);
iv = (ImageView) findViewById(R.id.iv_identityScan);
initOCR();
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (hasGotToken) {
applyCard();
}else {
Log.d("tag", "百度OCR token还未成功获取");
initOCR();
}
}
});
}
public static File getSaveFile(Context context) {
File file = new File(context.getFilesDir(), "pic.jpg");
return file;
}
private void applyCard() {
Intent intent = new Intent(this, CameraActivity.class);
intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH,
getSaveFile(getApplication()).getAbsolutePath());
intent.putExtra(CameraActivity.KEY_NATIVE_TOKEN,
OCR.getInstance().getLicense());
intent.putExtra(CameraActivity.KEY_NATIVE_ENABLE,
true);
intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, CameraActivity.CONTENT_TYPE_ID_CARD_FRONT);
startActivityForResult(intent, REQUEST_CODE_CAMERA);
}
private void initOCR() {
showProgressDialog("正在初始化OCR");
OCR.getInstance().initAccessTokenWithAkSk(new OnResultListener() {
@Override
public void onResult(AccessToken result) {
String token = result.getAccessToken();
hasGotToken = true;
Log.d("tag","初始化成功...");
dismissProgressDialog();
}
@Override
public void onError(OCRError error) {
error.printStackTrace();
Log.d("AK,SK方式获取token失败", error.getMessage());
dismissProgressDialog();
}
}, getApplicationContext(), APIKey,SecretKey);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_CAMERA && resultCode == Activity.RESULT_OK) {
if (data != null) {
showProgressDialog("正在为您初始化身份证数据...");
String contentType = data.getStringExtra(CameraActivity.KEY_CONTENT_TYPE);
String filePath = getSaveFile(getApplicationContext()).getAbsolutePath();
if (!TextUtils.isEmpty(contentType)) {
if (CameraActivity.CONTENT_TYPE_ID_CARD_FRONT.equals(contentType)) {
recIDCard(IDCardParams.ID_CARD_SIDE_FRONT, filePath);
} else if (CameraActivity.CONTENT_TYPE_ID_CARD_BACK.equals(contentType)) {
recIDCard(IDCardParams.ID_CARD_SIDE_BACK, filePath);
}
} else {
dismissProgressDialog();
}
}
}
}
private void recIDCard(String idCardSideFront, String filePath) {
IDCardParams param = new IDCardParams();
param.setImageFile(new File(filePath));
// 设置身份证正反面
param.setIdCardSide(idCardSideFront);
// 设置方向检测
param.setDetectDirection(true);
// 设置图像参数压缩质量0-100, 越大图像质量越好但是请求时间越长。 不设置则默认值为20
param.setImageQuality(20);
OCR.getInstance().recognizeIDCard(param, new OnResultListener() {
@Override
public void onResult(IDCardResult result) {
if (result != null) {
String name = "";
String sex = "";
String nation = "";
String num = "";
String address = "";
String birthday = "";
if (result.getBirthday() != null) {
birthday = result.getBirthday().toString();
String year = birthday.substring(0, 4);
String mouth = birthday.substring(4, 6);
String day = birthday.substring(6, 8);
String time = year + "-" + mouth + "-" + day;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = dateFormat.parse(time);
int age = getAge(date);
} catch (ParseException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
if (result.getName() != null) {
name = result.getName().toString();
}
if (result.getGender() != null) {
sex = result.getGender().toString();
}
if (result.getIdNumber() != null) {
num = result.getIdNumber().toString();
}
Log.d("tag", "姓名:"+name+" 性别:"+sex+" 身份证号:"+num+" 生日:"+birthday);
}
dismissProgressDialog();
}
@Override
public void onError(OCRError error) {
Log.d("tag", error.getMessage());
dismissProgressDialog();
}
});
}
public void dismissProgressDialog() {
if (dialog != null) {
dialog.dismiss();
}
}
public void showProgressDialog(String message) {
if (dialog == null) {
if (!this.isFinishing()) {
dialog = new ProgressDialog(this);
dialog.setMessage(message);
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
dialog.show();
}
} else {
dialog.setMessage(message);
if (!this.isFinishing()) {
dialog.show();
}
}
}
//由出生日期获得年龄
public int getAge(Date birthDay) throws Exception {
Calendar cal = Calendar.getInstance();
if (cal.before(birthDay)) {
throw new IllegalArgumentException(
"The birthDay is before Now.It's unbelievable!");
}
int yearNow = cal.get(Calendar.YEAR);
int monthNow = cal.get(Calendar.MONTH);
int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
cal.setTime(birthDay);
int yearBirth = cal.get(Calendar.YEAR);
int monthBirth = cal.get(Calendar.MONTH);
int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
int age = yearNow - yearBirth;
if (monthNow <= monthBirth) {
if (monthNow == monthBirth) {
if (dayOfMonthNow < dayOfMonthBirth) age--;
} else {
age--;
}
}
return age;
}
}