百度智能云OCR文字识别的坑

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

这篇的内容其实跟python的关系不是很大,是在使用python做文字识别的时候遇到的一个坑,这里大概记录一下,希望大家在使用百度智能云的OCR文字识别的时候,能够快速的解决这个问题。

业务需求大概是这个样子的,学生在使用仪器做完实验之后,仪器会将实验结果,打印在一张小票上。正常,学生需要将小票上边的数据,逐一输入到系统中,但是,客户觉得这个操作太麻烦了,想用文字识别将小票上边的数据识别出来,自动填入,学生只需要检查一遍识别的是否正确即可。

需求很简单,我这里的后端是使用PHP做的,这也不耽误我使用python做文字识别。最开始的python文字识别的尝试,我这里就不做赘述了,具体,请移步《Python爬虫(八)图形验证码识别——自定义OCR文字识别

但是,之前没有现成的例子,从头写,从头训练模型,代价有点大,后来我们一致决定,使用百度智能云的OCR文字识别来实现这个小功能。具体怎么用,这玩意,有SDK,有官方文档,照着写就行了。这边 通用文字识别(标准版)就可以满足我的需求。其他的模式(高精度,交通场景,卡证等)我就没有深入研究。

这次,客户需求升级,需要读取仪器上边的电子仪表的数据,我这边使用之前接好的通用文字识别(标准版)的接口做测试,对电子屏幕的文字识别率很低。

我这边去百度的产品列表中看了一下,他是有 仪器仪表盘读数识别 这个功能的。价格如下图所示:

微信截图_20220520165007.png

买了一万次的,开始霍霍。

他家的调用还是很简洁的,我这里使用的是laravel5.8框架,调用代码如下图所示:

/**
     * @name: 百度文字识别
     * @author: camellia
     * @date: 2022-03-23
     * @param $filePath string 文件url
     */
    public function baiduOcr($url)
    {
        $client new \AipOcr($this->AppID, $this->API_Key, $this->Secret_Key);
        // 调用仪表文字识别, 图片参数为远程url图片
        $info $client->meter($url);
        // $info = $client->basicAccurate($url);
        // $info = $client->basicGeneralUrl($url);
        return $info;
    }
复制代码

然后,结果,报错了

{
    "code"1,
    "msg""解密成功!",
    "words_result": {
        "log_id"1527573108083997023,
        "error_msg""image format error",
        "error_code"216201
    }
}
复制代码

Words_result是百度云给我返回的结果。错误码是216201,啥意思呢?官方文档是这样告诉我们的:

微信截图_20220520165436.png

我就不明白,我上传的png图片,哪里错了呢?

查文档吧,没有别的办法啊。

官方文档给出的示例代码是这个样子的:

<?php
/**
 * 发起http post请求(REST API), 并获取REST请求的结果
 * @param string $url
 * @param string $param
 * @return - http response body if succeeds, else false.
 */
function request_post($url ''$param '')
{
    if (empty($url) || empty($param)) {
        return false;
    }
 
    $postUrl $url;
    $curlPost $param;
    // 初始化curl
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $postUrl);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    // 要求结果为字符串且输出到屏幕上
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    // post提交方式
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
    // 运行curl
    $data = curl_exec($curl);
    curl_close($curl);
 
    return $data;
}
 
$token '[调用鉴权接口获取的token]';
$url 'https://aip.baidubce.com/rest/2.0/ocr/v1/meter?access_token=' . $token;
$img = file_get_contents('[本地文件路径]');
$img = base64_encode($img);
$bodys array(
    'image' => $img
);
$res = request_post($url$bodys);
 
var_dump($res);
复制代码

这真是官方文档啊,我用你的SDK一共加上返回值就写了三行代码,调试的时候你让我获取token?也就是说我还得去看看token是怎么获取的呗,不出意外,您这token应该还有过期时间吧。天……

然后,我瞄了一眼他实例代码上方对参数的描述:

微信截图_20220520170046.png

注意我红框标注的位置。

我又去他的SDK中看了一下,他的源码:

    /**
     * 仪器仪表盘读数识别
     *
     * @param string $image
     * @param bool $probability
     * @param bool $polyLocation
     * @param array|options $
     * @return bool|mix|mixed|string[]
     */
    public function meter($image$options array())
    {
        $data array();
        $data['image'] = base64_encode($image);
        $data = array_merge($data$options);
        return $this->request($this->meter, $data);
    }
复制代码

对比一下,各位看官是否发现了问题呢?

您的官方文档中显示的参数是image和url两个参数二选一,但是您实际的代码中,只有image赋值,这我给你传图片url不报错才怪了呢……

咱就说,SDK上线之前能不能和文档对一下。这么低级的错误……

行啊,我这里放一下我修改之后的方法:

    /**
     * 仪器仪表盘读数识别
     *
     * @param string $image
     * @param bool $probability
     * @param bool $polyLocation
     * @param array|options $
     * @return bool|mix|mixed|string[]
     */
    public function meter($image$options array())
    {
        $data array();
        // $data['image'] = base64_encode($image);
        $data['url'] = $image;
        $data = array_merge($data$options);
        return $this->request($this->meter, $data);
    }
复制代码

我这里传的是文件的url,所以就不考虑传base64的情况了。改的比较粗暴。各位看官勿喷。

当然,有这个问题的接口,不止这一个,其他的我没有用到,这里就不做修改了。下次有同学遇到类似的问题,记得对照官方文档看一下源码。

有好的建议,请在下方输入你的评论。

欢迎访问个人博客 guanchao.site

欢迎访问我的小程序:打开微信->发现->小程序->搜索“时间里的”

猜你喜欢

转载自juejin.im/post/7101427244177817636