Java通过百度OCR实现图片文字识别、身份证识别与车牌识别

发布时间 2023-11-17 14:25:26作者: ꧁ʚ星月天空ɞ꧂

百度智能云开通免费服务

1、先注册一个百度智能云账号

2、领取免费资源(每天固定免费多少次的使用次数,如果想用更多,可以花钱开通)
image
选择对应的服务和资源
image
左下角点击0元领取就可以了

返回概览界面
image

服务列表出现,表示免费资源领取成功

3、创建应用

image

image

image

image

创建成功后会在应用列表显示,从这个界面我们可以获取到AppID、API Key和Secret Key,代码中没有这三个是无法使用的

代码实现

导入依赖

    //百度OCR
    implementation 'com.baidu.aip:java-sdk:4.16.16'

我用的是gradle

Maven如下:

    //百度OCR
<dependency>
    <groupId>com.baidu.aip</groupId>
    <artifactId>java-sdk</artifactId>
    <version>4.16.17</version>
</dependency>

Controller

由于不涉及到数据库,我就直接用的controller

package com.example.studydemo.OCR;



import com.baidu.aip.ocr.AipOcr;
import com.example.studydemo.common.ReturnResult;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


@RestController
@RequestMapping("/ocr")
public class OcrController {

    //设置APPID/AK/SK
    private static String APP_ID = "";
    private static String API_KEY ="";
    private static String SECRET_KEY = "";

    @PostMapping("/imageToFont")
    public ReturnResult imageToFont(MultipartFile image) throws IOException {

        // 初始化一个AipOcr
        AipOcr aipOcr = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
        if (isImage(image.getInputStream())){
            image.transferTo(Path.of("./",image.getOriginalFilename()));
            String path = "./" + image.getOriginalFilename();
            System.out.println(path);
            ArrayList<String> re = basicGeneral(aipOcr,path);
            File f = new File(path);
            if (f.exists()){
                f.delete();
            }
            return ReturnResult.buildSuccessResult(re);
        }else {
            return ReturnResult.buildSuccessResult("文件格式必须为图片格式");
        }
    }

    @PostMapping("/checkIdCord")
    public ReturnResult checkIdCord (MultipartFile image) throws IOException {

        // 初始化一个AipOcr
        AipOcr aipOcr = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
        if (isImage(image.getInputStream())){
            image.transferTo(Path.of("./",image.getOriginalFilename()));
            String path = "./" + image.getOriginalFilename();
            System.out.println(path);
            Map<String,Object> re = idCord(aipOcr,path);
            File f = new File(path);
            if (f.exists()){
                f.delete();
            }
            return ReturnResult.buildSuccessResult(re);
        }else {
            return ReturnResult.buildSuccessResult("文件格式必须为图片格式");
        }
    }

    @PostMapping("/checkLicencePlateNumber")
    public ReturnResult checkLicencePlateNumber (MultipartFile image) throws IOException {

        // 初始化一个AipOcr
        AipOcr aipOcr = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
        if (isImage(image.getInputStream())){
            image.transferTo(Path.of("./",image.getOriginalFilename()));
            String path = "./" + image.getOriginalFilename();
            System.out.println(path);
            Map<String,Object> re = licencePlateNumber(aipOcr,path);
            File f = new File(path);
            if (f.exists()){
                f.delete();
            }
            return ReturnResult.buildSuccessResult(re);
        }else {
            return ReturnResult.buildSuccessResult("文件格式必须为图片格式");
        }
    }

    public static boolean isImage(InputStream inputStream) {
        if (inputStream == null) {
            return false;
        }
        Image img;
        try {
            img = ImageIO.read(inputStream);
            return !(img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0);
        } catch (Exception e) {
            return false;
        }
    }

    /*
     * 通用文字识别
     * */
    public static ArrayList<String> basicGeneral(AipOcr aipOcr,String path){
        // 传入可选参数调用接口
        HashMap<String, String> options = new HashMap<String, String>();
        options.put("language_type", "CHN_ENG");//识别语言类型,默认为中英文混合
        options.put("detect_direction", "true");//是否检查图片朝向,默认false不检查
        options.put("detect_language", "true");//是否检查语言,默认false不检查
        options.put("probability", "true");//是否返回识别结果中每一行的置信度

        // 调用接口,返回JSON格式数据
        JSONObject jsonObject = aipOcr.basicGeneral(path, options);
        //获取JSON对象里提取图片文字信息数组
        JSONArray jsonArray = jsonObject.getJSONArray("words_result");
        //循环打印信息
        ArrayList<String> result = new ArrayList<>();
        for(int i = 0;i<jsonArray.length();i++){
            System.out.println(jsonArray.getJSONObject(i).get("words"));
            result.add((String) jsonArray.getJSONObject(i).get("words"));
        }
        return result;
    }


    /*
     * 身份证文字识别
     * */
    public  static Map<String,Object> idCord(AipOcr aipOcr,String path){
        // 传入可选参数调用接口
        HashMap<String, String> options = new HashMap<String, String>();
        options.put("detect_direction", "true");//检查图片朝向。默认false不检测
        options.put("detect_risk", "false");//是否开启身份证类型检测功能(类型为身份证复印件、临时身份证、身份证翻拍、修改过的身份证),默认false不开启
        String idCardSide = "front";//身份证含照片一面
//        String idCardSide = "back";//身份证含国徽一面
        //本地图片识别,返回JSON对象
        JSONObject jsonObject = aipOcr.idcard(path, idCardSide, options);
        //获取到我们需要的信息
        JSONObject result = jsonObject.getJSONObject("words_result");
        Map<String,Object> map = new HashMap<>();
        //获取迭代器,
        Iterator<String> iterator = result.keys();
        while (iterator.hasNext()){
            //获取键和值
            String key = iterator.next();
            String value = result.getJSONObject(key).getString("words");
            //打印识别结果
            System.out.println(key+" : "+value);
            map.put(key,value);
        }
        return map;
    }

    /*
     * 车牌号识别
     * */
    public Map<String,Object> licencePlateNumber(AipOcr aipOcr,String path){
        // 传入可选参数调用接口
        HashMap<String, String> options = new HashMap<String, String>();
        options.put("multi_detect", "false");//是否检测多张图片,默认false
        //本地图片识别,返回JSON对象
        JSONObject jsonObject = aipOcr.plateLicense(path, options);
        System.out.println(jsonObject);
        //获取需要的信息
        JSONObject result = jsonObject.getJSONObject("words_result");
        Map<String,Object> map = new HashMap<>();
        map.put("车牌颜色:",result.getString("color"));
        map.put("车牌号:",result.getString("number"));
        return map;
    }

}

注:上述中AppID、API Key和Secret Key要换成自己百度智能云应用列表中复制的

上述中后面的方法应该放进工具类的,时间有限,就放在一起了

涉及的返回类:

package com.example.studydemo.common;

import lombok.Data;

@Data
public class ReturnResult {

    private int code;

    private String msg;

    private Object data;

    private  ReturnResult(){

    }

    private static ReturnResult buildResult(int code, String msg, Object data){
        ReturnResult result = new ReturnResult();
        result.code = code;
        result.msg = msg;
        result.data = data;
        return result;
    }

    public static ReturnResult buildSuccessResult(String msg, Object data) {
        return buildResult(200, msg, data);
    }

    public static ReturnResult buildSuccessResult(Object data) {
        return buildSuccessResult("success", data);
    }

    public static ReturnResult buildFailureResult(int code, String msg, Object data) {
        return buildResult(code, msg, data);
    }

    public static ReturnResult buildFailureResult(String msg, Object data) {
        return buildFailureResult(500, msg, data);
    }

    public static ReturnResult buildFailureResult(String msg) {
        return buildFailureResult(500, msg, null);
    }
}


如果不想用返回类,直接将Controller中接口的返回值改成自己想要的就行了

参考:https://blog.csdn.net/m0_51527921/article/details/123419775
https://blog.csdn.net/m0_53434091/article/details/127826119