持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
这篇的内容其实跟python的关系不是很大,是在使用python做文字识别的时候遇到的一个坑,这里大概记录一下,希望大家在使用百度智能云的OCR文字识别的时候,能够快速的解决这个问题。
业务需求大概是这个样子的,学生在使用仪器做完实验之后,仪器会将实验结果,打印在一张小票上。正常,学生需要将小票上边的数据,逐一输入到系统中,但是,客户觉得这个操作太麻烦了,想用文字识别将小票上边的数据识别出来,自动填入,学生只需要检查一遍识别的是否正确即可。
需求很简单,我这里的后端是使用PHP做的,这也不耽误我使用python做文字识别。最开始的python文字识别的尝试,我这里就不做赘述了,具体,请移步《Python爬虫(八)图形验证码识别——自定义OCR文字识别》
但是,之前没有现成的例子,从头写,从头训练模型,代价有点大,后来我们一致决定,使用百度智能云的OCR文字识别来实现这个小功能。具体怎么用,这玩意,有SDK,有官方文档,照着写就行了。这边 通用文字识别(标准版)就可以满足我的需求。其他的模式(高精度,交通场景,卡证等)我就没有深入研究。
这次,客户需求升级,需要读取仪器上边的电子仪表的数据,我这边使用之前接好的通用文字识别(标准版)的接口做测试,对电子屏幕的文字识别率很低。
我这边去百度的产品列表中看了一下,他是有 仪器仪表盘读数识别 这个功能的。价格如下图所示:
买了一万次的,开始霍霍。
他家的调用还是很简洁的,我这里使用的是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,啥意思呢?官方文档是这样告诉我们的:
我就不明白,我上传的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应该还有过期时间吧。天……
然后,我瞄了一眼他实例代码上方对参数的描述:
注意我红框标注的位置。
我又去他的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
欢迎访问我的小程序:打开微信->发现->小程序->搜索“时间里的”