一,、總體概述 本文主要介紹了由本人開(kāi)發(fā)的,、基于百度AI的云貓OCR軟件的主要功能,性能評(píng)價(jià)及核心代碼解讀,。因?yàn)槭菐讉€(gè)帖子合并成一個(gè),,所以篇幅較長(zhǎng),希望各位能耐心看完,,當(dāng)然也可以各取所需,。 本文主要分為以下幾個(gè)部分: 第一部分 云貓OCR的軟件介紹 一、云貓OCR簡(jiǎn)介 云貓OCR是基于百度云OCR算法,,由進(jìn)擊的狐貍進(jìn)行開(kāi)發(fā)的一款軟件,。本軟件由C#語(yǔ)言進(jìn)行開(kāi)發(fā),運(yùn)行在Windows平臺(tái)上,。主要調(diào)用的接口是通用文字識(shí)別,、通用文字識(shí)別(高精度)和表格識(shí)別等。 二,、云貓OCR目前實(shí)現(xiàn)的主要功能: 1.批量圖片文字識(shí)別,,可以預(yù)覽圖片,可以對(duì)識(shí)別結(jié)果進(jìn)行自動(dòng)換行和縮進(jìn),,可以控制QPS并發(fā)(QPS功能因?yàn)榘俣仍频膖imeout問(wèn)題而暫時(shí)擱置),; 2.批量表格圖片識(shí)別,支持自動(dòng)打開(kāi)識(shí)別結(jié)果,,用戶(hù)也可以選擇直接打開(kāi)保存目錄,; 3.PDF轉(zhuǎn)圖片,在我的筆記本(配置為I7處理器/8G內(nèi)存/128G SSD硬盤(pán))的硬件環(huán)境下,,PDF轉(zhuǎn)圖片程序模塊占用的內(nèi)存不超過(guò)400M,,同時(shí)可以在2分鐘左右的時(shí)間內(nèi)轉(zhuǎn)換超過(guò)500頁(yè)內(nèi)容的PDF文件。支持一鍵打開(kāi)轉(zhuǎn)換結(jié)果文件夾,。 4.云貓軟件支持換膚功能,,目前有兩套皮膚; 5.可以設(shè)置API Key和Secret Key,; 6.支持中途停止識(shí)別,; 7.支持把設(shè)置改變后對(duì)同一張圖片進(jìn)行重新識(shí)別; 8.支持多種語(yǔ)言,; 9.其他功能,,比如識(shí)別統(tǒng)計(jì)信息、控制字體大小,、右鍵把識(shí)別結(jié)果另存為rtf文件,、全選和復(fù)制識(shí)別結(jié)果等等,; 三、演示帖子鏈接 http://ai.baidu.com/forum/topic/show/492371 四,、云貓OCR演示視頻鏈接 https://v.qq.com/x/page/r0564n4a87e.html 建議大家用1.2x或者1.5x倍速觀看,因?yàn)楸救说穆曀儆悬c(diǎn)慢,。 第二部分 云貓OCR基于百度OCR的具體實(shí)現(xiàn)方式說(shuō)明 一,、概述 云貓OCR是基于百度AI,在Windows平臺(tái)運(yùn)行的一款軟件,。我是用C#語(yǔ)言在Visual Studio2017集成開(kāi)發(fā)環(huán)境中進(jìn)行開(kāi)發(fā)的,,開(kāi)發(fā)方式是SDK包開(kāi)發(fā)。在開(kāi)發(fā)中,,我們需要參考百度的技術(shù)文檔,。 百度云文字識(shí)別技術(shù)文檔地址: https://cloud.baidu.com/doc/OCR/index.html 二、準(zhǔn)備工作 首先,,我們需要下載最新的百度文字識(shí)別的SDK包,。 C# SDK包的下載地址如下: 下載完畢后解壓縮,最新的包在文件夾net45里面,。 打開(kāi)Visual Studio2017開(kāi)發(fā)環(huán)境,,選擇新建項(xiàng)目,因?yàn)槲掖蛩阌每刂婆_(tái)項(xiàng)目講解,,因此要選擇新建項(xiàng)目——C#控制臺(tái)項(xiàng)目,。建好項(xiàng)目之后,需要在項(xiàng)目中引用上面下載的SDK包,。 三,、核心代碼講解 (一)調(diào)用百度OCR函數(shù)識(shí)別圖片文字,返回的格式為Json 代碼如下: using System; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.IO; using System.Drawing; using System.Collections.Generic; using System.Linq;
namespace myOCRDemo { class Program { public static void GeneralBasicDemo() { // 設(shè)置APPID/AK/SK var API_KEY = "你的 Api Key"; var SECRET_KEY = "你的 Secret Key"; //創(chuàng)建對(duì)象 var client = new Baidu.Aip.Ocr.Ocr(API_KEY, SECRET_KEY); client.Timeout = 60000; // 修改超時(shí)時(shí)間 var image = File.ReadAllBytes("圖片文件路徑"); // 調(diào)用通用文字識(shí)別, 圖片參數(shù)為本地圖片,,可能會(huì)拋出網(wǎng)絡(luò)等異常,,請(qǐng)使用try/catch捕獲 var result = client.GeneralBasic(image); Console.WriteLine(result); } static void Main(string[] args) { GeneralBasicDemo(); Console.Read(); } } } 注意,具體開(kāi)發(fā)的時(shí)候要把上面的API Key和Secret Key分別改為你自己的,,至于怎么申請(qǐng)和查看這兩個(gè)Key,,可以參考我寫(xiě)的評(píng)測(cè)篇帖子。帖子鏈接如下: http://ai.baidu.com/forum/topic/show/955989 另外不要忘了把圖片文件路徑改為你自己的圖片路徑,。下面是識(shí)別的結(jié)果示例: 原圖如下: (二)解析Json格式,,把識(shí)別結(jié)果轉(zhuǎn)變?yōu)楦鼮橹庇^的文本類(lèi)型 代碼如下: using System; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.IO; using System.Drawing; using System.Collections.Generic; using System.Linq;
namespace myOCRDemo { class Program { public static void GeneralBasicDemo() { // 設(shè)置APPID/AK/SK var API_KEY = "你的Akey"; var SECRET_KEY = "你的SKey"; //創(chuàng)建對(duì)象 var client = new Baidu.Aip.Ocr.Ocr(API_KEY, SECRET_KEY); client.Timeout = 60000; // 修改超時(shí)時(shí)間 var image = File.ReadAllBytes(@"你的圖片路徑"); // 調(diào)用通用文字識(shí)別, 圖片參數(shù)為本地圖片,可能會(huì)拋出網(wǎng)絡(luò)等異常,,請(qǐng)使用try/catch捕獲 var result = client.GeneralBasic(image); //解析Json的代碼 JObject jo = (JObject)JsonConvert.DeserializeObject(result.ToString()); int num = (int)jo["words_result_num"]; string[] words = new string[num]; for (int i = 0; i < num; i++) words[i] = jo["words_result"][i]["words"].ToString(); //返回值 string txtOCR = null; for (int i = 0; i < num; i++) txtOCR += words[i] + "\n"; //顯示結(jié)果 Console.WriteLine(txtOCR); } static void Main(string[] args) { GeneralBasicDemo(); Console.Read(); } } } 程序運(yùn)行結(jié)果如下: 這樣就比較符合人類(lèi)的閱讀習(xí)慣了,,上面這段代碼也是核心的基礎(chǔ)代碼,可以通過(guò)這些核心的代碼去做一些優(yōu)化,,比如自動(dòng)換行,、自動(dòng)縮進(jìn),、根據(jù)語(yǔ)言習(xí)慣自動(dòng)改變標(biāo)點(diǎn)符號(hào)等等。 (三)表格識(shí)別 百度的表格文字識(shí)別的編程較為麻煩,,主要分成兩步:第一步是提交表格文字識(shí)別請(qǐng)求,,獲得requestId;第二步是根據(jù)requestId獲取表格文字識(shí)別的結(jié)果,,默認(rèn)是Excel文件格式,,Json結(jié)果會(huì)返回一段下載地址。 我的程序除了上面這兩步以外,,還添加了自動(dòng)下載Excel文件到本地電腦的代碼,,供各位參考。另外要注意的是,,提交識(shí)別請(qǐng)求和獲得識(shí)別結(jié)果這兩步之間,,程序必須設(shè)置延時(shí),否則不能獲得下載的URL ,。經(jīng)過(guò)實(shí)際測(cè)試,,延時(shí)為3秒以上較為合適,3秒以下可能會(huì)出錯(cuò),。 代碼如下: ///
/// 表格文字識(shí)別 ///
public static void myTableRecognitionRequestDemo() { // 設(shè)置APPID/AK/SK var API_KEY = "你的API Key"; var SECRET_KEY = "你的Secret Key"; //創(chuàng)建對(duì)象 var client = new Baidu.Aip.Ocr.Ocr(API_KEY, SECRET_KEY); client.Timeout = 60000; // 修改超時(shí)時(shí)間 var image = File.ReadAllBytes(@"F:\表格圖片1.jpg");//這里要改成你的表格圖片路徑 // 調(diào)用表格文字識(shí)別,,可能會(huì)拋出網(wǎng)絡(luò)等異常,請(qǐng)使用try/catch捕獲 var result = client.TableRecognitionRequest(image); //解析Json JObject jo = (JObject)JsonConvert.DeserializeObject(result.ToString()); string requestId = jo["result"][0]["request_id"].ToString(); Console.WriteLine("獲得requestId:"+requestId); //延時(shí)3秒,,這句是必須的 System.Threading.Thread.Sleep(3000); //獲取表格識(shí)別結(jié)果 //有時(shí)會(huì)得不到鏈接,,需要多嘗試幾次 var resultExcel = client.TableRecognitionGetResult(requestId); Console.WriteLine("獲得的表格識(shí)別結(jié)果如下:"); Console.WriteLine(resultExcel); //解析Json,獲得鏈接 JObject joResult = (JObject)JsonConvert.DeserializeObject(resultExcel.ToString()); string excelURL = joResult["result"]["result_data"].ToString(); Console.WriteLine("獲得的Excel文件下載地址是:\n" + excelURL); //自動(dòng)下載Excel文件到電腦 WebClient df = new WebClient(); df.DownloadFile(excelURL, @"F:\識(shí)別結(jié)果.xls");//這里要改成你的下載文件路徑 Console.WriteLine("下載完畢"); } 作者使用的測(cè)試用圖片: 表格文字識(shí)別結(jié)果截圖: 尾記:本文的示例代碼都是最新的代碼,,跟百度SDK文檔里面的代碼是一致的,,而云貓OCR是2017年末就已經(jīng)寫(xiě)好的了,代碼有些陳舊,,所以沒(méi)直接貼源代碼了,。 代碼篇的原帖子地址: http://ai.baidu.com/forum/topic/show/956037 第三部分 云貓OCR的使用說(shuō)明及效果評(píng)測(cè) 一、概述 筆者是在2017年接觸百度云服務(wù)平臺(tái)的,,在這里我也稱(chēng)之為百度AI ,。筆者根據(jù)百度AI提供的函數(shù)接口,自行編程實(shí)現(xiàn)了一款OCR軟件——云貓OCR,。云貓OCR大部分的代碼開(kāi)發(fā)是在2017年底前完成的,,之所以雪藏到現(xiàn)在,是因?yàn)楣P者的一些私人事務(wù)(小孩出生等)——我是利用業(yè)余時(shí)間進(jìn)行軟件開(kāi)發(fā)的,,所以中斷了大概一年多的時(shí)間,,現(xiàn)在才有空繼續(xù)這個(gè)項(xiàng)目。 評(píng)測(cè)篇的原帖子地址: http://ai.baidu.com/forum/topic/show/955989 二、評(píng)測(cè)的具體內(nèi)容 (一)準(zhǔn)備工作 在使用云貓OCR之前,,我們必須先去百度云官網(wǎng)進(jìn)行注冊(cè)賬號(hào),,有了賬號(hào)以后,我們還要去具體的云服務(wù)項(xiàng)目下申請(qǐng)API Key和Secret Key ,,一般這兩個(gè)Key是用戶(hù)各人保管的,,不能隨便透露給外人。因?yàn)榘俣仍片F(xiàn)在已經(jīng)正式收費(fèi),,而用戶(hù)每人每天的免費(fèi)調(diào)用次數(shù)都是有限的,,提高限額需要支付費(fèi)用,用戶(hù)使用百度云AI接口的依據(jù)主要就是這兩個(gè)Key,,所以我們要保管好。下面是簡(jiǎn)單的準(zhǔn)備工作圖片說(shuō)明: (二)正式使用云貓OCR 用戶(hù)有了百度云API Key和Secret Key之后,,就可以正式使用云貓OCR了,。具體使用步驟如下: (三)評(píng)測(cè)的具體內(nèi)容 首先介紹一下云貓OCR調(diào)用的百度AI的主要接口,首先是通用文字識(shí)別(帶位置版),,其次是通用文字識(shí)別(帶位置高精度版),,最后是表格文字識(shí)別,下面依次介紹這三種識(shí)別,。 1. 通用文字識(shí)別(帶位置版)和通用文字識(shí)別(帶位置高精度版)的混合使用 如上圖所示,,用戶(hù)可以選擇多種語(yǔ)言(包括德語(yǔ)、法語(yǔ),、西班牙語(yǔ)等等),,選擇好后點(diǎn)擊文字識(shí)別即可。因?yàn)榘俣仍铺峁┑母呔任淖肿R(shí)別接口只支持中英文,,而通用的文字識(shí)別支持除中英文以外的多種語(yǔ)言,,所以筆者在編寫(xiě)軟件中,這兩種接口是混合使用的,,具體怎么混合使用請(qǐng)看代碼篇,。一般情況下,高精度的文字識(shí)別效果比通用的好,,但也比較耗時(shí),。 本軟件支持識(shí)別的文字結(jié)果在本機(jī)保存為文件,具體如下圖操作: 保存的文件是rtf格式,,可以用WPS或者Office Word打開(kāi),。下面再給出一次性識(shí)別20張圖片的統(tǒng)計(jì)結(jié)果圖示: 從上圖可以看出,百度云的文字識(shí)別結(jié)果速度還是不錯(cuò)的,,識(shí)別速度是平均大概2-3秒一張圖,。 2. 表格文字識(shí)別 表格文字識(shí)別的主要步驟如下圖所示: 識(shí)別的結(jié)果軟件會(huì)自動(dòng)保存為Excel文件并打開(kāi),如圖: 從上圖可以看出,表格文字識(shí)別的速度比普通文字識(shí)別要慢一些,,大概需要5-6秒,。 評(píng)測(cè)總結(jié):百度OCR對(duì)于印刷體的識(shí)別還是不錯(cuò)的,比起以前的OCR軟件來(lái)說(shuō),,百度OCR可以說(shuō)是革命性的進(jìn)步,。當(dāng)然,它也有自己的短板,。比如手寫(xiě)體的識(shí)別,,筆者還沒(méi)有評(píng)測(cè),但百度云通用文字高精度接口對(duì)手寫(xiě)體的識(shí)別是較差的,。再比如QPS并發(fā),,我的理解是可以提高OCR文字識(shí)別的速度,對(duì)于大量的圖片文字識(shí)別來(lái)說(shuō)尤其是重要,,可以節(jié)省大量時(shí)間,。但遺憾的是,百度云對(duì)并發(fā)好像做的不太好,,程序不一定支持QPS并發(fā),,這個(gè)缺點(diǎn)我們也是希望百度后面能夠有所改正。
附錄: C#編程實(shí)現(xiàn)手寫(xiě)識(shí)別 一,、概述 本人是用C#編程,,調(diào)用百度API接口實(shí)現(xiàn)手寫(xiě)體識(shí)別的,參考了百度的產(chǎn)品文檔,。 文檔地址:https://cloud.baidu.com/doc/OCR/index.html 二,、代碼及解說(shuō) 本人的源代碼大部分是來(lái)自百度的產(chǎn)品文檔,但其中也遇到了一些麻煩,。比如文字識(shí)別的編碼問(wèn)題,,百度的代碼給出的編碼是Default,但在我的機(jī)器上這樣做會(huì)顯示亂碼,。經(jīng)過(guò)查找資料,,我把編碼改成UTF8,亂碼的問(wèn)題才得到解決,。 作者的所有源代碼如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.IO; using System.Drawing; using System.Web; using System.Net;
namespace myHandwrite { public static class FileUtils { ///
/// 轉(zhuǎn)base64編碼 ///
/// /// public static String getFileBase64(String fileName) { FileStream filestream = new FileStream(fileName, FileMode.Open); byte[] arr = new byte[filestream.Length]; filestream.Read(arr, 0, (int)filestream.Length); string baser64 = Convert.ToBase64String(arr); filestream.Close(); return baser64; } } class Program { // 調(diào)用getAccessToken()獲取的 access_token建議根據(jù)expires_in 時(shí)間 設(shè)置緩存 // 返回token示例 public static String TOKEN = "24.adda70c11b9786206253ddb70affdc46.2592000.1493524354.282335-1234567";
// 百度云中開(kāi)通對(duì)應(yīng)服務(wù)應(yīng)用的 API Key 建議開(kāi)通應(yīng)用的時(shí)候多選服務(wù) private static String clientId = "這里改成你的API Key"; // 百度云中開(kāi)通對(duì)應(yīng)服務(wù)應(yīng)用的 Secret Key private static String clientSecret = "這里改成你的Secret Key"; ///
/// 獲取token的函數(shù) ///
/// public static String getAccessToken() { String authHost = "https://aip./oauth/2.0/token"; HttpClient client = new HttpClient(); List> paraList = new List>(); paraList.Add(new KeyValuePair("grant_type", "client_credentials")); paraList.Add(new KeyValuePair("client_id", clientId)); paraList.Add(new KeyValuePair("client_secret", clientSecret));
HttpResponseMessage response = client.PostAsync(authHost, new FormUrlEncodedContent(paraList)).Result; String result = response.Content.ReadAsStringAsync().Result; //自己加的代碼 JObject jo = (JObject)JsonConvert.DeserializeObject(result.ToString()); string myToken = jo["access_token"].ToString(); Console.WriteLine("獲得的Token是:" + myToken); return myToken; }
///
/// 手寫(xiě)體文字識(shí)別 ///
/// /// /// public static string myHandwriting(string token,string filename) { //string token = "#####調(diào)用鑒權(quán)接口獲取的token#####"; // 圖片的base64編碼 string strbaser64 = FileUtils.getFileBase64(filename); string host = "https://aip./rest/2.0/ocr/v1/handwriting?access_token=" + token; Encoding encoding = Encoding.Default; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host); request.Method = "post"; request.ContentType = "application/x-www-form-urlencoded"; request.KeepAlive = true; //這里加上了一些參數(shù) String str = "recognize_granularity=big&image=" + HttpUtility.UrlEncode(strbaser64); byte[] buffer = encoding.GetBytes(str); request.ContentLength = buffer.Length; request.GetRequestStream().Write(buffer, 0, buffer.Length); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); //顯示結(jié)果是亂碼,,嘗試改變編碼,經(jīng)過(guò)測(cè)試需要改成UTF8編碼 StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8); string result = reader.ReadToEnd(); Console.WriteLine("手寫(xiě)文字識(shí)別:"); //解析Json的代碼 JObject jo = (JObject)JsonConvert.DeserializeObject(result.ToString()); int num = (int)jo["words_result_num"]; string[] words = new string[num]; for (int i = 0; i < num; i++) words[i] = jo["words_result"][i]["words"].ToString(); //返回值 string txtOCR = null; for (int i = 0; i < num; i++) txtOCR += words[i] + "\n"; //顯示結(jié)果 Console.WriteLine(txtOCR); return txtOCR; } static void Main(string[] args) { //這里要改成你的圖片路徑 string filename = @"F:\手寫(xiě)體5.jpg"; string token = getAccessToken(); myHandwriting(token,filename); Console.Read(); } } } 注意,,上面的代碼中需要各位改成自己的Akey和Skey,,另外要改一下圖片路徑。如果返回的是亂碼,,還需要改一下編碼,。 識(shí)別的結(jié)果如下: 程序用的圖片文件如下: 作者:kohakuarc |
|
來(lái)自: python_lover > 《待分類(lèi)》