OCR 识别小工具(4)户口本识别
busyboxs 发布于2020-12 浏览:5346 回复:3
0
收藏

功能介绍

支持对户口本内常住人口登记卡的全部 22 个字段进行结构化识别,包括户号、姓名、与户主关系、性别、出生地、民族、出生日期、身份证号、本市县其他住址、曾用名、籍贯、宗教信仰、身高、血型、文化程度、婚姻状况、兵役状况、服务处所、职业、何时由何地迁往本市、何时由何地迁往本址、登记日期

应用场景

  • 身份信息登记:使用户口本识别技术,对户口本上的姓名、性别、出生地、出生日期、身份证号等信息进行识别,可应用于新生儿建档、户口迁移、个人信贷申请、社会救济金申请等政务办理场景,使政务部门能够快速提取申请人身份信息完成核验和登记,提升办事效率
  • 亲属关系登记:使用户口本识别技术,对户口本上的姓名、与户主关系、身份证号等信息进行识别,可应用于婚姻登记、遗产继承、子女入学登记等需证明亲属关系的民政业务办理场景,使政务部门能够快速提取申请人身份信息及关系完成登记,提升办事效率

接口描述

支持对户口本内常住人口登记卡的全部 22 个字段进行结构化识别,包括户号、姓名、与户主关系、性别、出生地、民族、出生日期、身份证号、本市县其他住址、曾用名、籍贯、宗教信仰、身高、血型、文化程度、婚姻状况、兵役状况、服务处所、职业、何时由何地迁往本市、何时由何地迁往本址、登记日期

请求说明

  • HTTP 方法: POST
  • 请求 URL: https://aip.baidubce.com/rest/2.0/ocr/v1/household_register
  • URL参数: access_token
  • Header 参数: Content-Type = application/x-www-form-urlencoded
  • Body 参数:见下表

返回说明
返回参数如下表:

返回示例如下:

{
    "log_id": 1301870459,
    "words_result": {
        "BirthAddress": {
            "words": "河南洛阳市郊区"
        },
        "Birthday": {
            "words": "2016-07-28"
        },
        "CardNo": {
            "words": "410311201607282825"
        },
        "Name": {
            "words": "孙翌晨"
        },
        "Nation": {
            "words": "汉族"
        },
        "Relationship": {
            "words": "户主"
        },
        "Sex": {
            "words": "男"
        },
    },
    "words_result_num": 7
}

C++ 代码实现调用

这里假设前置准备已经做好了,如果没有,请阅读以下文章;如果有,则直接跳过;

(基础篇 01)在控制台创建对应的应用 https://yangshun.win/blogs/dea770b9/
(基础篇 02)Windows 下使用 Vcpkg 配置百度 AI 图像识别 C++开发环境(VS2017)  https://yangshun.win/blogs/3b103680/
(基础篇 03)C++ 获取 access token  https://yangshun.win/blogs/49f400d2/
(基础篇 04)C++ base64 编解码原理及实现  https://yangshun.win/blogs/3f2fcf2e/
下面的代码中部分函数定义在 util.h 和 util.cpp 中

screenshot/functions/util.h  https://github.com/busyboxs/screenshot/blob/master/functions/util.h
screenshot/functions/util.cpp  https://github.com/busyboxs/screenshot/blob/master/functions/util.cpp
为了方便,首先根据返回参数定义了一个结构体,该结构体包括了返回参数中的参数,如下:

struct HouseholdInfo
{
    uint64_t logID{};
    uint32_t resultNumber{};
    std::map wordsResult{};

    void print()
    {
        std::cout << "log id: " << logID << '\n';
        std::cout << "words result number: " << resultNumber << '\n';

        for (auto& [name, res] : wordsResult)
        {
            std::cout << "\t" << UTF8ToGB(name.c_str()) << ": ";
            res.print();
        }
    }
};

然后定义了一个类来调用接口并获取结果

class Household
{
public:
    Household();
    ~Household();

    Json::Value request(std::string imgBase64, std::map& options);

    void getResult(HouseholdInfo& result);

private:
    Json::Value m_obj;
    std::string m_url;
    // file to save token key
    std::string m_filename;

    inline static std::map resultName
    {
        {"Name", u8"姓名"},
        {"Relationship", u8"户主或与户主关系"},
        {"Sex", u8"性别"},
        {"BirthAddress", u8"出生地"},
        {"Nation", u8"民族"},
        {"Birthday", u8"生日"},
        {"CardNo", u8"身份证号"},
        {"HouseholdNum", u8"户号"},
        {"FormerName", u8"曾用名"},
        {"Hometown", u8"籍贯"},
        {"OtherAddress", u8"本市(县)其他住址"},
        {"Belief", u8"宗教信仰"},
        {"Height", u8"身高"},
        {"BloodType", u8"血型"},
        {"Education", u8"文化程度"},
        {"MaritalStatus", u8"婚姻状况"},
        {"VeteranStatus", u8"兵役状况"},
        {"WorkAddress", u8"服务处所"},
        {"Career", u8"职业"},
        {"WWToCity", u8"何时由何地迁来本市(县)"},
        {"WWHere", u8"何时由何地迁往本址"},
        {"Date", u8"登记日期"}
    };
};

类中的私有成员 m_obj 表示返回结果对应的 json 对象。m_url 表示请求的 url,m_filename 表示用于存储 access token 的文件的文件名。

request 函数输入请求图像的 base64 编码以及请求参数,返回一个 json 对象,json 对象中包含请求的结果。

getResult 将请求的结果进行解析为自定义的结构体数据类型。以便用于后序的打印。

由于请求返回的 json 中各字段是用的英文,所以定义一个静态 Map 将英文映射为中文。

完整代码如下
Household.h 代码如下: screenshot/functions/Household.h https://github.com/busyboxs/screenshot/blob/master/functions/Household.h

#pragma once
#include 
#include 
#include 
#include 
#include 
#include "util.h"
#include "customVariables.h"

struct HouseholdInfo
{
    uint64_t logID{};
    uint32_t resultNumber{};
    std::map wordsResult{};

    void print()
    {
        std::cout << "log id: " << logID << '\n';
        std::cout << "words result number: " << resultNumber << '\n';

        for (auto& [name, res] : wordsResult)
        {
            std::cout << "\t" << UTF8ToGB(name.c_str()) << ": ";
            res.print();
        }
    }
};

class Household
{
public:
    Household();
    ~Household();

    Json::Value request(std::string imgBase64, std::map& options);

    void getResult(HouseholdInfo& result);

private:
    Json::Value m_obj;
    std::string m_url;
    // file to save token key
    std::string m_filename;

    inline static std::map resultName
    {
        {"Name", u8"姓名"},
        {"Relationship", u8"户主或与户主关系"},
        {"Sex", u8"性别"},
        {"BirthAddress", u8"出生地"},
        {"Nation", u8"民族"},
        {"Birthday", u8"生日"},
        {"CardNo", u8"身份证号"},
        {"HouseholdNum", u8"户号"},
        {"FormerName", u8"曾用名"},
        {"Hometown", u8"籍贯"},
        {"OtherAddress", u8"本市(县)其他住址"},
        {"Belief", u8"宗教信仰"},
        {"Height", u8"身高"},
        {"BloodType", u8"血型"},
        {"Education", u8"文化程度"},
        {"MaritalStatus", u8"婚姻状况"},
        {"VeteranStatus", u8"兵役状况"},
        {"WorkAddress", u8"服务处所"},
        {"Career", u8"职业"},
        {"WWToCity", u8"何时由何地迁来本市(县)"},
        {"WWHere", u8"何时由何地迁往本址"},
        {"Date", u8"登记日期"}
    };
};

void HouseholdTest();
HouseholdInfo HouseholdDetect(std::string imgPath);

Household.cpp 代码如下: screenshot/functions/Household.cpp https://github.com/busyboxs/screenshot/blob/master/functions/Household.cpp

#include "Household.h"

Household::Household()
{
    m_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/household_register";
    m_filename = "tokenKey";
}

Household::~Household()
{
}

Json::Value Household::request(std::string imgBase64, std::map& options)
{
    std::string response;
    Json::Value obj;
    std::string token;

    // 1. get HTTP post body
    std::string body;
    mergeHttpPostBody(body, imgBase64, options);

    // 2. get HTTP url with access token
    std::string url = m_url;
    getHttpPostUrl(url, m_filename, token);

    // 3. post request, response store the result
    int status_code = httpPostRequest(url, body, response);
    if (status_code != CURLcode::CURLE_OK) {
        obj["curl_error_code"] = status_code;
        m_obj = obj;
        return obj; // TODO: maybe should exit 
    }

    // 4. make string to json object
    generateJson(response, obj);

    // if access token is invalid or expired, we will get a new one
    if (obj["error_code"].asInt() == 110 || obj["error_code"].asInt() == 111) {
        token = getTokenKey();
        writeFile(m_filename, token);
        return request(imgBase64, options);

    }

    m_obj = obj;

    //checkErrorWithExit(obj);

    return obj;
}

void Household::getResult(HouseholdInfo& result)
{
    if (m_obj.get("error_code", "null"))
    {
        result.wordsResult["error_code"].words = m_obj.get("error_code", "null").asString();
        result.wordsResult["error_msg"].words = m_obj.get("error_msg", "null").asString();
        return;
    }

    result.logID = m_obj["log_id"].asUInt64();
    result.resultNumber = m_obj["words_result_num"].asUInt();
    Json::Value::Members keys = m_obj["words_result"].getMemberNames();

    for (auto it = keys.begin(); it != keys.end(); ++it)
    {
        WordsOnlyPart resultPart;
        getWordsOnlyPart(m_obj["words_result"][*it], resultPart);
        result.wordsResult[resultName[*it].c_str()] = resultPart;
    }
}

void HouseholdTest()
{
    std::string img_file = "./images/household_test.png";
    std::string out;
    readImageFile(img_file.c_str(), out);
    std::string img_base64 = base64_encode(out.c_str(), (int)out.size());

    // set options
    std::map options;

    Json::Value obj;
    Household householdObj;
    HouseholdInfo result;
    obj = householdObj.request(img_base64, options);

    householdObj.getResult(result);
    result.print();
}

HouseholdInfo HouseholdDetect(std::string imgPath)
{
    std::string out;
    readImageFile(imgPath.c_str(), out);
    std::string img_base64 = base64_encode(out.c_str(), (int)out.size());

    // set options
    std::map options;

    Json::Value obj;
    Household householdObj;
    HouseholdInfo result;
    obj = householdObj.request(img_base64, options);

    householdObj.getResult(result);

    return result;
}

运行结果
测试图像

收藏
点赞
0
个赞
共3条回复 最后由用户已被禁言回复于2022-04
#5busyboxs回复于2021-02
#4 hunagprince回复
你好!请问在哪下载工具?

https://github.com/busyboxs/screenshot/releases/tag/1.0

0
#4hunagprince回复于2021-02

你好!请问在哪下载工具?

0
#3doubi渣渣回复于2021-01

666

0
TOP
切换版块