拍照速算识别 API 文档

接口说明

拍照速算识别基于深度学习的端到端识别技术,自动识别图片中的速算题并智能批改,返回标准LaTeX公式及批改结果。覆盖K12教育范围内15种题型,支持口算、竖式、方程、脱式计算等,详细请参照 速算题型 。支持的场景有印刷体、手写体、拍照场景。

该能力是通过HTTP API的方式给开发者提供一个通用的接口。HTTP API适用于一次性交互数据传输的AI服务场景,比如上传图片识别其中的文字等;相较于SDK,API具有轻量、跨语言的特点。另外,请注意该接口使用的HTTP API协议不支持跨域。

接口Demo

示例demo请点击 这里 下载。
目前仅提供部分开发语言的demo,其他语言请参照下方接口文档进行开发。
也欢迎热心的开发者到 讯飞开放平台社区 分享你们的demo。

接口要求

集成拍照速算识别API时,需按照以下要求。

内容 说明
传输方式 http[s] (为提高安全性,强烈推荐https)
请求地址 http[s]: //rest-api.xfyun.cn/v2/itr
注:服务器IP不固定,为保证您的接口稳定,请勿通过指定IP的方式调用接口,使用域名方式调用
请求行 POST /v2/itr HTTP/1.1
接口鉴权 签名机制,详情请参照下方鉴权认证
字符编码 UTF-8
响应格式 统一采用JSON格式
开发语言 任意,只要可以向讯飞云服务发起HTTP请求的均可
适用范围 任意操作系统,但因不支持跨域不适用于浏览器
图片属性 最短边至少15px,最长边最大4096px,支持文字与水平轴小于±15°夹角偏转
图片格式 jpg/png/bmp
图片大小 base64编码后大小不超过4M

接口调用流程

· 通过接口密钥基于hmac-sha256计算签名,将签名以及其他参数放在Http Request Header中。详见下方 鉴权认证 。 · 将请求参数以及图片数据放在Http Request Body中,以POST表单的形式提交,详见下方 请求参数 。 · 向服务器端发送Http请求后,接收服务器端的返回结果。

白名单

默认关闭IP白名单,即该服务不限制调用IP。
在调用该业务接口时

  • 若关闭IP白名单,接口认为IP不限,不会校验IP。
  • 若打开IP白名单,则服务端会检查调用方IP是否在讯飞开放平台配置的IP白名单中,对于没有配置到白名单中的IP发来的请求,服务端会拒绝服务。

IP白名单规则

  • 在 控制台-相应服务的IP白名单处编辑,保存后五分钟左右生效。
  • 不同Appid的不同服务都需要分别设置IP白名单。
  • IP白名单需设置为外网IP,请勿设置局域网IP;
  • 如果握手阶段返回{"message":"Your IP address is not allowed"},则表示由于IP白名单配置有误或还未生效,服务端拒绝服务。

鉴权认证

在调用业务接口时,须对HTTP请求进行签名,服务端通过签名来识别用户并验证其合法性。

鉴权方法

在Http Request Header中配置以下鉴权参数用于授权认证,其中签名信息放在请求头Authorization中。
Header示例:

    Content-Type:application/json
    Accept:application/json,version=1.0
    Host:rest-api.xfyun.cn
    Date:Mon, 18 Mar 2019 08:32:07 GMT
    Digest:SHA-256=MGNjNThlMTU3ZWNmYjU4YTlhNTAwNDI5NWE4NTBmNWM5ZTMwMmM5OGZiNzE2ODY4ZjM2ZTQxYmNjMzkzZjIwYQ==
    Authorization:api_key="your_key", algorithm="hmac-sha256", headers="host date request-line digest", signature="$signature"

鉴权参数:

参数 类型 必须 说明 示例
Host string 请求主机 rest-api.xfyun.cn
Date string 当前时间戳,RFC1123格式("EEE, dd MMM yyyy HH:mm:ss z") Tue, 30 Jul 2019 07:51:27 GMT
Digest string 加密请求body
SHA-256=Base64(SHA256(请求body))
body请参考下方公共请求参数
SHA-256=AmSJeAtB....
Authorization string 使用base64编码的签名相关信息(签名基于hamc-sha256计算) 参考下方签名详细生成规则

· date参数生成规则:

date必须是UTC+0或GMT时区,RFC1123格式(Tue, 30 Jul 2019 07:51:27 GMT)。
服务端会对Date进行时钟偏移检查,最大允许300秒的偏差,超出偏差的请求都将被拒绝。

· Authorization参数生成格式:

    Authorization: api_key="your_key", algorithm="hmac-sha256", headers="host date request-line digest", signature="$signature"
    示例:api_key="apikeyXXXXXXXXXXXXXXXXXXXXXXXXXX", algorithm="hmac-sha256", headers="host date request-line digest", signature="RhJ/0FO+Df2zuTQcseN1jxRoonKeuKi0wXRByQUgIA0="

其中 api_key 是在控制台获取的APIKey(在控制台的拍照速算识别页面可查看,为32位字符串。),这里以api_key="apikeyXXXXXXXXXXXXXXXXXXXXXXXXXX"为例
algorithm 是加密算法(仅支持hmac-sha256),headers 是参与签名的参数。
signature 是使用加密算法对参与签名的参数签名后并使用base64编码的字符串,详见下方。

· signature参数生成规则:

signature原始字段由 host,date,request-line,digest四个参数按照格式拼接成
拼接的格式为(\n为换行符,’:’后面有一个空格):

	host: $host\ndate: $date\n$request-line\ndigest: $digest

例如,请求的url为:https://rest-api.xfyun.cn/v2/itr
请求的body为:

{"common":{"app_id":"5dXXXXXX"},"business":{"ent":"math-arith","aue":"raw"},"data":{"image":"/9j/4AAQSkZJRgABAQAAAQABAA...."}}

则signature生成步骤如下:

1)对请求body进行SHA256计算,把计算结果进行Base64编码后的字符串写在"SHA-256="后,即字段digest的值

    digest: SHA-256=Base64(SHA256(请求body))
    例:digest: SHA-256=AmSJeAtBmL+v9F4RZfeKkubQP2YIuVDkH76yFwyO/Sg=

2)构建signature原始字段(signature_origin)

    host: rest-api.xfyun.cn
    date: Tue, 30 Jul 2019 07:51:27 GMT
    POST /v2/itr HTTP/1.1
    digest: SHA-256=AmSJeAtBmL+v9F4RZfeKkubQP2YIuVDkH76yFwyO/Sg=

3)使用hmac-sha256算法结合apiSecret对signature_origin签名,获得签名后的摘要signature_sha
apiSecret在控制台的拍照速算识别页面可查看,这里以apisecretXXXXXXXXXXXXXXXXXXXXXXX为例。

    signature_sha=hmac-sha256(signature_origin,$apiSecret)

4)使用base64编码对signature_sha进行编码,获得最终的signature

    signature=base64(signature_sha)
    例:RhJ/0FO+Df2zuTQcseN1jxRoonKeuKi0wXRByQUgIA0=

鉴权示例(golang)

    package main
    import (
    	"crypto/hmac"
    	"crypto/sha256"
    	"encoding/base64"
    	"fmt"
    	"time"
    	"github.com/valyala/fasthttp"
    )
    const (
    	//支持的算法
    	Algorithm = "hmac-sha256"
    	//版本协议
    	HttpProto = "HTTP/1.1"
    	//假定的secret
    	Secret = "12345"
    )
    func assemblyRequestHeader(req *fasthttp.Request, apiKey, host, uri string, body []byte) {
    	req.Header.Set("Content-Type", "application/json")
    	//设置请求头 其中Host Date 必须有
    	req.Header.Set("Host", host)
    	//date必须是utc时区,且不能和服务器时间相差300s
    	currentTime := time.Now().UTC().Format(time.RFC1123)
    	req.Header.Set("Date", currentTime)
    	//对body进行sha256签名,生成digest头部,POST请求必须对body验证
    	digest := "SHA-256=" + signBody(body)
    	req.Header.Set("Digest", digest)
    	//根据请求头部内容,生成签名
    	sign := generateSignature(host, currentTime,"POST", uri, HttpProto, digest,Secret)
    	//组装Authorization头部
    	authHeader := fmt.Sprintf(`api_key="%s", algorithm="%s", headers="host date request-line digest", signature="%s"`, apiKey, Algorithm, sign)
    	req.Header.Set("Authorization", authHeader)
    }
    func generateSignature(host, date, httpMethod, requestUri, httpProto, digest string, secret string) string {
    	//不是request-line的话,则以 header名称,后跟ASCII冒号:和ASCII空格,再附加header值
    	var signatureStr string
    	if len(host) != 0 {
    		signatureStr = "host: " + host + "\n"
    	}
    	signatureStr += "date: " + date + "\n"
    	//如果是request-line的话,则以 http_method request_uri http_proto
    	signatureStr += httpMethod + " " + requestUri + " " + httpProto + "\n"
    	signatureStr += "digest: " + digest
    	return hmacsign(signatureStr, secret)
    }
    func hmacsign(data, secret string) string {
    	mac := hmac.New(sha256.New, []byte(secret))
    	mac.Write([]byte(data))
    	encodeData := mac.Sum(nil)
    	return base64.StdEncoding.EncodeToString(encodeData)
    }
    func signBody(data []byte) string {
    	//进行sha256签名
    	sha := sha256.New()
    	sha.Write(data)
    	encodeData := sha.Sum(nil)
    	//经过base64转换
    	return base64.StdEncoding.EncodeToString(encodeData)
    }

鉴权结果

如果鉴权失败,则根据不同错误类型返回不同HTTP Code状态码,同时携带错误描述信息,详细错误说明如下:

HTTP Code 说明 错误描述信息 解决方法
401 缺少authorization参数 {“message”:”Unauthorized”} 检查是否有authorization参数,详情见authorization参数详细生成规则
401 签名参数解析失败 {“message”:”HMAC signature cannot be verified”} 检查签名的各个参数是否有缺失是否正确,特别确认下复制的api_key是否正确
401 签名校验失败 {“message”:”HMAC signature does not match”} 签名验证失败,可能原因有很多。
1. 检查api_key,api_secret 是否正确。
2.检查计算签名的参数host,date,request-line是否按照协议要求拼接。
3. 检查signature签名的base64长度是否正常(正常44个字节)。
403 时钟偏移校验失败 {“message”:”HMAC signature cannot be verified, a valid date or x-date header is required for HMAC Authentication”} 检查服务器时间是否标准,相差5分钟以上会报此错误
403 IP白名单校验失败 {"message":"Your IP address is not allowed"} 可在控制台关闭IP白名单,或者检查IP白名单设置的IP地址是否为本机外网IP地址

认证失败返回示例:

    HTTP/1.1 401 Forbidden
    Date: Thu, 06 Dec 2018 07:55:16 GMT
    Content-Length: 116
    Content-Type: text/plain; charset=utf-8
    {
        "message": "HMAC signature does not match"
    }

请求参数

在调用业务接口时,都需要在 Http Request Body 中配置以下参数,请求数据均为json字符串。

参数名 类型 必传 描述
common object 用于上传公共参数
common.app_id string 在平台申请的appid信息
business object 用于上传业务参数
business.ent string 请求引擎类型,只支持math-arith
business.aue string 预留压缩格式,暂时只支持raw
data object 用于上传识别图像数据
data.image bytes 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式

**注**: base64编码后大小会增加约1/3
请求参数示例:
    {	   
	   "common":{
           "app_id":"xxxxxxxx"
       },
	   "business":{
           "ent":"math-arith",
		   "aue" :"raw"
       },
	   "data":{
		"image":"/9j/4AAQSkZJRgABAQAAAQABAAD/2..."    
	   }
    }

返回参数

参数名 类型 描述
sid string 本次会话id
code int 返回码,0表示成功,其它表示异常,详情请参考错误码
message string 描述信息
data object 拍照速算识别返回信息,详见下方

data字段具体信息
参数名 类型 描述 备注
ITRResult.attr_exception int 异常信息属性 正常情况为“0x0”,空白图为“0x7011”
ITRResult.category string 题型 只有math_phfw_arith
ITRResult.version string 接口版本号
ITRResult.multi_line_info 对象 当前题型所有小题的位置等信息 当前题型只有一个
multi_line_info.imp_line_info 对象 每个小题的位置等信息 见后面描述
imp_line_info.imp_line_rect 对象 该行公式所在的区域位置 见后面描述
imp_line_rect.left_up_point_x int 该行公式所在矩形区域左上角顶点的像素横坐标 数字,大于等于0
imp_line_rect.left_up_point_y int 该行公式所在矩形区域左上角顶点的像素纵坐标 数字,大于等于0
imp_line_rect.right_down_point_x int 该行公式所在矩形区域右下角顶点的像素横坐标 数字,大于等于0
imp_line_rect.right_down_point_y int 该行公式所在矩形区域右下角顶点的像素纵坐标 数字,大于等于0
imp_line_info.total_score int 该速算题判决正误信息 1(正确)/0(错误)
imp_line_info.rec_rejection int 拒识标志 不为0(拒识,说明该行公式输出结果不可信)
imp_line_info.strict_score int 预留字段,无需关注
ITRResult.recog_result 对象数组 当前题型所有小题的识别结果 当前题型只有一个
recog_result.line_char_result 对象 预留字段,无需关注
recog_result.line_word_result 对象 每个小题的识别结果 见后面描述
line_word_result.beg_pos_x int 该行公式起始位置横坐标 数字,大于等于0
line_word_result.beg_pos_y int 该行公式起始位置纵坐标 数字,大于等于0
line_word_result.end_pos_x int 该行公式结束位置横坐标 数字,大于等于0
line_word_result.end_pos_y int 该行公式结束位置纵坐标 数字,大于等于0
line_word_result.word_content string 该行公式识别结果 Latex公式
line_word_result.word_gwpp float 该行公式的后验概率 数字,大于等于0

*注*: 其中加粗部分为获取速算题识别结果、区域和批改正误信息的关键字段。

返回参数示例:

    {
    	"code": 0,
    	"message": "",
    	"sid": "itr0001d1af@gz16990297366463e902",
    	"data": {
    		"ITRResult": {
    			"attr_exception": 0,
    			"category": "math_phfw_arith",
    			"multi_line_info": {
    				"imp_line_info": [{
    					"imp_line_rect": {
    						"left_up_point_x": 156,
    						"left_up_point_y": 183,
    						"right_down_point_x": 416,
    						"right_down_point_y": 259
    					},
    					"rec_rejection": 0,
    					"strict_score": 0,
    					"total_score": 1
    				}, 
                    ......
                    {
    					"imp_line_rect": {
    						"left_up_point_x": 634,
    						"left_up_point_y": 1303,
    						"right_down_point_x": 897,
    						"right_down_point_y": 1395
    					},
    					"rec_rejection": 0,
    					"strict_score": 0,
    					"total_score": 1
    				}]
    			},
    			"recog_result": [{
    				"line_char_result": null,
    				"line_word_result": [{
    					"beg_pos": [0],
    					"beg_pos_x": [0],
    					"beg_pos_y": [0],
    					"end_pos": [258],
    					"end_pos_x": [258],
    					"end_pos_y": [74],
    					"word_content": ["3 7 - 8 = 2 9"],
    					"word_gwpp": [0.9989326596260071]
    				}, 
                    ......
                    {
    					"beg_pos": [0],
    					"beg_pos_x": [0],
    					"beg_pos_y": [0],
    					"end_pos": [262],
    					"end_pos_x": [262],
    					"end_pos_y": [91],
    					"word_content": ["7 2 - 8 = 6 4"],
    					"word_gwpp": [0.9990690350532532]
    				}]
    			}],
    			"version": "3.6.0.1022"
    		}
    	}
    }

速算题型

No. 题型名称 题型示例
1 四则混合运算 示例图片
2 带题标号的四则混合运算 示例图片
3 已知结果求运算因子 示例图片
4 填写“<” “>” “=” 示例图片
5 填最大数、最小数 示例图片
6 约等于估算 示例图片
7 带余除数法 示例图片
8 相邻数 示例图片
9 分数四则运算 示例图片
10 单位换算 示例图片
11 竖式加减法 示例图片
12 竖式乘除法 示例图片
13 脱式运算 示例图片
14 解方程 示例图片
15 求平方 示例图片

调用示例

注: demo只是一个简单的调用示例,不适合直接放在复杂多变的生产环境使用

拍照速算识别demo python3语言

拍照速算识别demo java语言

拍照速算识别demo nodejs语言

拍照速算识别demo php语言

注: 其他开发语言请参照 接口调用流程 进行开发,也欢迎热心的开发者到 讯飞开放平台社区 分享你们的demo。

图片样例

拍照速算识别 图片样例 JPG文件

拍照速算识别 图片样例 PNG文件

拍照速算识别 图片样例 BMP文件

注: 如果测试过程中,发现图片符合要求但却不能识别,有可能是由于图片的真实格式和文件后缀不符,请通过图片的二进制流的头文件确认图片真实格式,不符合要求需要进行格式转换。

视频教程

如何分分钟实现速算题的自动批改

常见问题

拍照速算识别的主要功能是什么?

答:拍照速算识别基于深度学习的端到端识别技术,自动识别图片中的速算题并智能批改,返回标准LaTeX公式及批改结果。

拍照速算识别支持什么应用平台?

答:目前支持Web API应用平台。

拍照速算上传什么图片识别效果最佳

答:图片格式仅支持jpeg/png/bmp,图片大小≤2M 建议使用清晰的、算式规整、文字与空白占比较大的照片,效果更好。

支持的速算题型有哪些

答:四则混合运算、带题标号的四则混合运算、已知结果求运算因子、填写“<”“>”“=”、填最大数/最小数、约等于估算、带余除数法、相邻数、分数四则运算、单位换算、竖式加减法、竖式乘除法、脱式运算、解方程、求平方。

拍照速算交互次数怎么收费

答:拍照速算免费100000次/天调用,超过可在控制台申请提额。