-前言-
在日常工作難免會遇到將美術圖中的文字提取標識出來,接下來我們就講一講OCR及通過百度OCR識別我們自己的美術圖中的資源。
-正文-
OCR是圖像文字識別技術,應用場景非常的廣,百度OCR技術說是基於人工智能的OCR,普通場景識別精度高達98%。這裏我們不談OCR相關技術,只是實現一下如何使用百度OCR。
賬號註冊
首先我們需要有一個百度智能雲的賬號,並且創建一個文字識別的應用。這裏就不多贅述,直接創建一個免費賬號即可,對於個人開發使用免費賬戶完全夠用。接着我們會拿到一個API Key及Secret Key,這是我們在請求發送的時候獲取token的參數。
上傳文件並識別
上傳文件我繼續沿用了之前分解圖集項目的框架,該功能也是在那個項目基礎上擴展的。
/**
* 百度圖像文字識別
*/
class BaiduOCR{
constructor(){
/**
* token
*/
this.token;
/**
* string 圖像數據
*/
this.image;
}
/**
* 將文件寫入Canvas
*/
findFileWords(file) {
var $this = this;
createImageBitmap(file).then((data) => {
var canvas = document.createElement("canvas");
canvas.width = data.width;
canvas.height = data.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(data,0,0);
var base = canvas.toDataURL("image/png", 1);
$this._doReqOCR(base);
});
}
/**
* 請求識別
* @param {string} image Base64圖形數據
*/
_doReqOCR(image){
this.image = image;
if(this.token){
this._reqOCR();
}else{
this._reqToken();
}
}
/**
* 請求識別圖像內容
*/
_reqOCR(){
var http = new Tool.HttpRequest();
var url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=" + this.token;
var img = "image="+encodeURIComponent(this.image.split(',')[1]);
http.once("complete",this,(data)=>{
console.log(data);
});
http.send(url,img,"post","text",['content-type','application/x-www-form-urlencoded']);
}
/**
* 請求token
*/
_reqToken(){
var tokenHttp = new Tool.HttpRequest();
var url = `https://aip.baidubce.com/oauth/2.0/token?
grant_type=client_credentials&
client_id=【API Key】&
client_secret=【Secret Key】&`;
tokenHttp.once("complete",this,(data)=>{
var jd = JSON.parse(data);
this.token = jd.access_token;
this._reqOCR();
});
tokenHttp.once("error",this,()=>{
console.warn("ERROR ON HTTP POST");
});
tokenHttp.send(url,null,"post");
}
}
上面是該功能的完整代碼,實現圖像識別的功能,我們還是首先通過傳到瀏覽器的圖片文件轉換成Canvas上的圖像,再通過Canvas的API去獲取像素數據。百度OCR需要的圖像數據是Base64編碼的圖像數據,正好我們的Canvas方式toDataURL就是轉換爲Base64後的編碼數據。
在獲取了我們的編碼數據base之後開始發起識別請求,首先通過API key及Secret Key獲取token,再通過token獲取圖像內文字數據。
開發問題
HTTPRequest
上面的Tool.HttpRequest是我封裝了XMLHttpRequest,直接使用XMLHttpRequest進行請求即可。下面以_reqOCR方法爲例請求圖像數據修改爲
/**
* 請求識別圖像內容
*/
_reqOCR(){
var http = new XMLHttpRequest();
var url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=" + this.token;
var img = "image="+encodeURIComponent(this.image.split(',')[1]);
http.open("post",url);
http.setRequestHeader('content-type','application/x-www-form-urlencoded');
http.send(img);
http.onload = function (e) {
console.log(e.target.response);
};
}
另外Http請求要使用post方法
216101 param image not exist
報這個錯誤是你沒有在body內發送image數據,注意http參數形式以字符串拼接形式發送。
var data = "image=" + 數據內容
216201 image format error
這個錯誤是圖形數據在百度那邊解析錯誤,說明我們沒有按照百度那邊的解析規則去傳image數據。我們獲取得到的Base64字符串數據需要做以下兩部更改:
- 去掉Base64數據頭(data:image/png;base64,)
- 將Base64去掉數據頭的數據進行URL編碼,將數據內容轉義
第一步我們通過字符串API 取“,”後字符串內容,第二步通過encodeURIComponent轉換即可