钻探调用腾讯云

① 、写在前面

近些年做项目必要用到识别图片汉语字的功能,本来用的Tesseract这么些写的,然则效果不是很雅观妙。

进而上网搜了一晃OCCR-V接口,就准备利用腾讯云、百度的OC酷威接口试一下效果。可是这些腾讯云OCENCORE就折腾了一天!

一 、写在头里

近期做项目供给用到识别图片汉语字的功效,本来用的Tesseract这几个写的,然则效果不是很理想。

跟着上网搜了一下OC奥迪Q7接口,就准备选取腾讯云、百度的OC汉兰达接口试一下效果。然则那么些腾讯云OC本田UR-V就折腾了一天!

② 、OC卡宴-通用印刷体识别

先是附上文书档案地址:OC君越-通用印刷体识别

贰 、OCCRUISER-通用印刷体识别

率先附上文档地址:OCPAJERO-通用印刷体识别

1、通用OCR简介

通用OCLAND技术提供图片全部文字的检查和测试和辨识服务,再次回到文字框地方与文字内容。扶助多现象、任意版面下整图像和文字字的分辨,以及中国和英国文、字母、数字的识别。被广泛应用于印刷文档识别、广告图像和文字字识别、街景店招识别、菜单识别、摄像标题识别、互连网头像文字识别等。

1、通用OCR简介

通用OC奥迪Q3技术提供图片全部文字的检查和测试和甄别服务,再次来到文字框地点与文字内容。支持多处境、任意版面下整图像和文字字的辨别,以及中国和英国文、字母、数字的分辨。被广泛应用于印刷文档识别、广告图像和文字字识别、街景店招识别、菜单识别、录像标题识别、网络头像文字识别等。

2、接口url地址

http://recognition.image.myqcloud.com/ocr/general

2、接口url地址

http://recognition.image.myqcloud.com/ocr/general

3、请求包header

接口接纳http协议,援助钦定图片URL和上传本地图片文件几种办法。

抱有请求都须要包括下列的头顶音讯:

Host、Content-Length、Content-Type、Authorization

3、请求包header

接口接纳http协议,支持内定图片U昂科雷L和上传本地图片文件二种办法。

持有请求都要求涵盖下列的底部音讯:

Host、Content-Length、Content-Type、Authorization

三、示例

三、示例

壹 、使用 url 的伸手包

POST /ocr/general HTTP/1.1
Authorization: FCHXdPTEwMDAwMzc5Jms9QUtJRGVRZDBrRU1yM2J4ZjhRckJi==
Host: recognition.image.myqcloud.com
Content-Length: 187
Content-Type: application/json
{
  "appid":"123456",
  "bucket":"test",
  "url":"http://test-123456.image.myqcloud.com/test.jpg"
} 

以此url是万象优图中图纸的url地址。

图片 1

来看那种格式,心里大致有数了,初叶敲代码。

壹 、使用 url 的呼吁包

POST /ocr/general HTTP/1.1
Authorization: FCHXdPTEwMDAwMzc5Jms9QUtJRGVRZDBrRU1yM2J4ZjhRckJi==
Host: recognition.image.myqcloud.com
Content-Length: 187
Content-Type: application/json
{
  "appid":"123456",
  "bucket":"test",
  "url":"http://test-123456.image.myqcloud.com/test.jpg"
} 

本条url是万象优图中图纸的url地址。

图片 2

见到那种格式,心里大约有数了,开端敲代码。

二 、具体贯彻

HttpClient client = new HttpClient();
var para = new
{
    appid = "123456",
    bucket = "test",
    url = "http://test-123456.image.myqcloud.com/test.jpg"
};
var jsonPara = JsonConvert.SerializeObject(para);
StringContent content = new StringContent(jsonPara);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
content.Headers.ContentLength = jsonPara.Length;
content.Headers.Add("Host", "recognition.image.myqcloud.com");
content.Headers.Add("Authorization", aut);
var taskHrm = client.PostAsync(postUrl, content);
taskHrm.Wait();
var taskStr = taskHrm.Result.Content.ReadAsStringAsync();
taskStr.Wait();
var result = taskStr.Result;

F5周转,结果报错了:

图片 3

以此错误的原因为:Host和Authorization无法这么添加到Headers中。于是乎笔者自作聪明的把它们放到参数中了:

var para = new
{
    appid = "123456",
    bucket = "test",
    url = "http://test-123456.image.myqcloud.com/test.jpg",
    Host = "recognition.image.myqcloud.com",
    Authorization = aut
};   

那般运营代码是从未有过报错,可是后台重回“has
no sign or sign is empty”,没有签定。

再回头看看参数必要,Host和Authorization必须添加在请求包Header中。于是百度时而,如何选取Httpclient设置Authorization。最后解决方案如下:

client.DefaultRequestHeaders.Host = "recognition.image.myqcloud.com";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", aut); 

中标运营!

可是项目中应用url的可能率终归少,基本上都以上传一张当地图片,然后识别出来文字。

上边来看一下识别一张地点图片。

贰 、具体贯彻

HttpClient client = new HttpClient();
var para = new
{
    appid = "123456",
    bucket = "test",
    url = "http://test-123456.image.myqcloud.com/test.jpg"
};
var jsonPara = JsonConvert.SerializeObject(para);
StringContent content = new StringContent(jsonPara);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
content.Headers.ContentLength = jsonPara.Length;
content.Headers.Add("Host", "recognition.image.myqcloud.com");
content.Headers.Add("Authorization", aut);
var taskHrm = client.PostAsync(postUrl, content);
taskHrm.Wait();
var taskStr = taskHrm.Result.Content.ReadAsStringAsync();
taskStr.Wait();
var result = taskStr.Result;

F5周转,结果报错了:

图片 4

本条错误的原因为:Host和Authorization不可能这么添加到Headers中。于是乎笔者班门弄斧的把它们放到参数中了:

var para = new
{
    appid = "123456",
    bucket = "test",
    url = "http://test-123456.image.myqcloud.com/test.jpg",
    Host = "recognition.image.myqcloud.com",
    Authorization = aut
};   

如此运转代码是尚未报错,不过后台重回“has
no sign or sign is empty”,没有署名。

再回头看看参数须求,Host和Authorization必须添加在请求包Header中。于是百度时而,怎么样利用Httpclient设置Authorization。最后化解方案如下:

client.DefaultRequestHeaders.Host = "recognition.image.myqcloud.com";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", aut); 

打响运转!

只是项目中利用url的概率究竟少,基本上都是上传一张地点图片,然后识别出来文字。

上边来看一下分辨一张当地图片。

③ 、使用 image 的伸手包

POST /ocr/general HTTP/1.1
Authorization: FCHXdPTEwMDAwMzc5Jms9QUtJRGVRZDBrRU1yM2J4ZjhRckJi==
Host: recognition.image.myqcloud.com
Content-Length: 735
Content-Type: multipart/form-data;boundary=--------------acebdf13572468

----------------acebdf13572468
Content-Disposition: form-data; name="appid";

123456
----------------acebdf13572468
Content-Disposition: form-data; name="bucket";

test
----------------acebdf13572468
Content-Disposition: form-data; name="image"; filename="test.jpg"
Content-Type: image/jpeg

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
----------------acebdf13572468--

说实话见到那种格式,一开端真是一脸懵逼,后面几个参数幸而,前面这一大串不领会怎么传递过去,后来百度了一晃,那种格式符合RFC
2045协议

具体解释一下:

第⑤行:注明Content
Type类型,并定义边界字符串。边界符能够自定义,不过最佳是用破折号等数据中貌似不会冒出的字符;

第陆、9、13以及18行是换行,传递的时候使用‘\r\n’;

第⑦ 、11以及15行是‘–’加上第④行的boundary即边界字符串。此间要专注是必然要拉长前边的连字符‘–’,作者起来没在意写的是和boundary一样,结果一向报错。

第七、10、1② 、14正是传递的Key_Value类型的多寡。“appid”和“bucket”正是要传送的key,而“123456”以及“test”就是个别对应的value。

第贰⑥ 、17行表示其它二个数量,key是image,filename是“test.jpg”。

末尾两行正是落成了。注意最后一行是boundary加上‘–’。

弄明白是怎么着意思了,就能够伊始写代码了。那里大家用WebRequest,至于缘何不用HttpClient,研商ing。不知哪位仁兄使用HttpClient写过,请不吝赐教。

③ 、使用 image 的请求包

POST /ocr/general HTTP/1.1
Authorization: FCHXdPTEwMDAwMzc5Jms9QUtJRGVRZDBrRU1yM2J4ZjhRckJi==
Host: recognition.image.myqcloud.com
Content-Length: 735
Content-Type: multipart/form-data;boundary=--------------acebdf13572468

----------------acebdf13572468
Content-Disposition: form-data; name="appid";

123456
----------------acebdf13572468
Content-Disposition: form-data; name="bucket";

test
----------------acebdf13572468
Content-Disposition: form-data; name="image"; filename="test.jpg"
Content-Type: image/jpeg

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
----------------acebdf13572468--

说实话见到那种格式,一最先真是一脸懵逼,前面多少个参数幸而,后边这一大串不知晓怎么传递过去,后来百度了须臾间,那种格式符合RFC
2045协议

切切实实解释一下:

第6行:证明Content
Type类型,并定义边界字符串。边界符能够自定义,可是最佳是用破折号等数据中一般不会油然则生的字符;

第伍 、⑨ 、13以及18行是换行,传递的时候使用‘\r\n’;

第捌 、11以及15行是‘–’加上第6行的boundary即边界字符串。那里要留意是必然要充足后面包车型地铁连字符‘–’,笔者初阶没在意写的是和boundary一样,结果一直报错。

第八 、⑩ 、1贰 、14正是传递的Key_Value类型的多寡。“appid”和“bucket”便是要传递的key,而“123456”以及“test”正是独家对应的value。

第③六 、17行代表其余三个数据,key是image,filename是“test.jpg”。

末尾两行便是得了了。注意最终一行是boundary加上‘–’。

弄通晓是什么意思了,就足以起始写代码了。那里我们用WebRequest,至于为啥不用HttpClient,切磋ing。不知哪位仁兄使用HttpClient写过,请不吝赐教。

④ 、具体落实

要辨其他图形如下:

图片 5

HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));
Stream memStream = new MemoryStream();
webReq.Method = "POST";
string boundary = "--------------" + DateTime.Now.Ticks.ToString("x");// 边界符  
webReq.ContentType = "multipart/form-data; boundary=" + boundary;

接下去是三个换行符,对应第肆行:

byte[] enter = Encoding.ASCII.GetBytes("\r\n");  //换行
memStream.Write(enter, 0, enter.Length);                       

传递key_value的时候格式都是如出一辙,于是大家写在一个巡回之中:

Dictionary<string, string> dic = new Dictionary<string, string>()
{
    {"appid","1255710379"} ,
    {"bucket","test1"}
};
//写入文本字段
string inputPartHeaderFormat = "--" + boundary + "\r\n" + "Content-Disposition:form-data;name=\"{0}\";" + "\r\n\r\n{1}\r\n";
foreach (var kv in dic)
{
    string inputPartHeader = string.Format(inputPartHeaderFormat, kv.Key, kv.Value);
    var inputPartHeaderBytes = Encoding.ASCII.GetBytes(inputPartHeader);
    memStream.Write(inputPartHeaderBytes, 0, inputPartHeaderBytes.Length);
}

接着该写入image了,这里大家在bin/debug里面有一张名为1.jpg的图形(即为下边包车型大巴图样)。

var fileStream = new FileStream("1.jpg", FileMode.Open, FileAccess.Read);
// 写入文件  
string imagePartHeader = "--" + boundary + "\r\n" +
                         "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
                         "Content-Type: image/jpeg\r\n\r\n";
var header = string.Format(imagePartHeader, "image", "1.jpg");
var headerbytes = Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
var buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
    memStream.Write(buffer, 0, bytesRead);
} 

最后即是终结符了:

 // 最后的结束符  
byte[] endBoundary = Encoding.ASCII.GetBytes("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "\r\n" + boundary + "--\r\n");
memStream.Write(endBoundary, 0, endBoundary.Length); 

接下去设置任何Header参数:

webReq.ContentLength = memStream.Length;
webReq.Headers.Add(HttpRequestHeader.Authorization, aut);
webReq.Host = "recognition.image.myqcloud.com";

此间需求留意的一些是安装Host值的时候不能够应用

webReq.Headers.Add(HttpRequestHeader.Host, "recognition.image.myqcloud.com");

其一法子,不然会有卓殊。 

var requestStream = webReq.GetRequestStream();
memStream.Position = 0;
memStream.CopyTo(requestStream);
HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
var ret = sr.ReadToEnd();
sr.Close();
response.Close();
requestStream.Close();
memStream.Close();

全盘运维!识别结果如下:

图片 6 

④ 、具体贯彻

要辨别的图形如下:

图片 7

HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));
Stream memStream = new MemoryStream();
webReq.Method = "POST";
string boundary = "--------------" + DateTime.Now.Ticks.ToString("x");// 边界符  
webReq.ContentType = "multipart/form-data; boundary=" + boundary;

接下去是3个换行符,对应第⑤行:

byte[] enter = Encoding.ASCII.GetBytes("\r\n");  //换行
memStream.Write(enter, 0, enter.Length);                       

传递key_value的时候格式都以一致,于是大家写在一个循环之中:

Dictionary<string, string> dic = new Dictionary<string, string>()
{
    {"appid","1255710379"} ,
    {"bucket","test1"}
};
//写入文本字段
string inputPartHeaderFormat = "--" + boundary + "\r\n" + "Content-Disposition:form-data;name=\"{0}\";" + "\r\n\r\n{1}\r\n";
foreach (var kv in dic)
{
    string inputPartHeader = string.Format(inputPartHeaderFormat, kv.Key, kv.Value);
    var inputPartHeaderBytes = Encoding.ASCII.GetBytes(inputPartHeader);
    memStream.Write(inputPartHeaderBytes, 0, inputPartHeaderBytes.Length);
}

跟着该写入image了,那里我们在bin/debug里面有一张名为1.jpg的图纸(即为上面的图形)。

var fileStream = new FileStream("1.jpg", FileMode.Open, FileAccess.Read);
// 写入文件  
string imagePartHeader = "--" + boundary + "\r\n" +
                         "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
                         "Content-Type: image/jpeg\r\n\r\n";
var header = string.Format(imagePartHeader, "image", "1.jpg");
var headerbytes = Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
var buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
    memStream.Write(buffer, 0, bytesRead);
} 

说到底正是得了符了:

 // 最后的结束符  
byte[] endBoundary = Encoding.ASCII.GetBytes("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "\r\n" + boundary + "--\r\n");
memStream.Write(endBoundary, 0, endBoundary.Length); 

接下去设置任何Header参数:

webReq.ContentLength = memStream.Length;
webReq.Headers.Add(HttpRequestHeader.Authorization, aut);
webReq.Host = "recognition.image.myqcloud.com";

此处需求注意的少数是设置Host值的时候不可能运用

webReq.Headers.Add(HttpRequestHeader.Host, "recognition.image.myqcloud.com");

本条方式,不然会有卓殊。 

var requestStream = webReq.GetRequestStream();
memStream.Position = 0;
memStream.CopyTo(requestStream);
HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
var ret = sr.ReadToEnd();
sr.Close();
response.Close();
requestStream.Close();
memStream.Close();

一应俱全运会行!识别结果如下:

图片 8 

四 、须求留意的点

④ 、供给专注的点

壹 、总括Authorization授权签名

签订契约分为多次立竿见影签名和单次有效签名。它们拼接成的签字串格式为:

a=[appid]&b=[bucket]&k=[SecretID]&e=[expiredTime]&t=[currentTime]&r=[rand]&u=[userid]&f=[fileid]

具体每一种字段的意义请参见官方文书档案:签字和鉴权文书档案

急需专注的有两点:

① 、使用 HMAC-SHA1
算法对请求实行加密;

贰 、签名串要求选用Base64
编码(首先对orignal使用HMAC-SHA1算法进行签订契约,然后将orignal附加到签订契约结果的最后,再进行Base64编码,获得终极的sign)。

 /// <summary>
 /// HMAC-SHA1加密算法
 /// </summary>
 /// <param name="secret_key">密钥</param>
 /// <param name="orignalStr">源文</param>
 /// <returns></returns>
 public static string HmacSha1Sign(string secret_key, string orignalStr)
 {
     var hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(secret_key));
     var orignalBytes = Encoding.UTF8.GetBytes(orignalStr);
     var hashBytes = hmacsha1.ComputeHash(orignalBytes);
     List<byte> bytes = new List<byte>();
     bytes.AddRange(hashBytes);
     bytes.AddRange(orignalBytes);
     return Convert.ToBase64String(bytes.ToArray());
 }

壹 、总结Authorization授权签名

署名分为多次立竿见影签名和单次有效签名。它们拼接成的签订契约串格式为:

a=[appid]&b=[bucket]&k=[SecretID]&e=[expiredTime]&t=[currentTime]&r=[rand]&u=[userid]&f=[fileid]

现实每一个字段的意义请参见官方文书档案:签订契约和鉴权文书档案

亟需专注的有两点:

① 、使用 HMAC-SHA1
算法对请求进行加密;

贰 、签名串需求接纳Base64
编码(首先对orignal使用HMAC-SHA1算法举行签订契约,然后将orignal附加到签订契约结果的最终,再开始展览Base64编码,获得终极的sign)。

 /// <summary>
 /// HMAC-SHA1加密算法
 /// </summary>
 /// <param name="secret_key">密钥</param>
 /// <param name="orignalStr">源文</param>
 /// <returns></returns>
 public static string HmacSha1Sign(string secret_key, string orignalStr)
 {
     var hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(secret_key));
     var orignalBytes = Encoding.UTF8.GetBytes(orignalStr);
     var hashBytes = hmacsha1.ComputeHash(orignalBytes);
     List<byte> bytes = new List<byte>();
     bytes.AddRange(hashBytes);
     bytes.AddRange(orignalBytes);
     return Convert.ToBase64String(bytes.ToArray());
 }

② 、一些其它急需留意的  

① 、文中使用的appid、bucket、secret_id、``secret_key需要注册万象优图后,才能得到。至于如何得到,文档中说的很清楚,有详细的步骤。

2、在设置Header参数时,Content_Length和Host能够不用安装。

贰 、一些别的急需留意的  

壹 、文中使用的appid、bucket、secret_id、``secret_key需要注册万象优图后,才能得到。至于如何得到,文档中说的很清楚,有详细的步骤。

2、在设置Header参数时,Content_Length和Host能够绝不安装。

五、最后

意在您在调用腾讯云-OCTiguan通用印刷体识别Api的时候能够少走些弯路,少踩一些坑。当然了这个可能算不上坑,恐怕是私人住房一些基础知识没控制。不管怎么,就算您在选择OCPAJERO的时候,本文对你有有些支持,那它就表明了应当的效果。

正文的源代码有趣味的能够下载

 

五、最后

盼望你在调用腾讯云-OC奔驰G级通用印刷体识别Api的时候能够少走些弯路,少踩一些坑。当然了这么些也许算不上坑,大概是私有一些基础知识没控制。不管什么样,假诺你在选择OC奥迪Q3的时候,本文对您有几许扶助,那它就表明了应当的效果。

正文的源代码有趣味的能够下载