如何用百度大腦文字識別技術,快速集成實用小工具

1、整體概述html

本文主要介紹了由本人開發的、基於百度AI的雲貓OCR軟件的主要功能,性能評價及核心代碼解讀。由於是幾個帖子合併成一個,因此篇幅較長,但願各位能耐心看完,固然也能夠各取所需。算法

本文主要分爲如下幾個部分:
第一部分是雲貓OCR軟件介紹。 由開發者本人親自介紹軟件的主要功能。對標ABBYY等OCR軟件,雲貓OCR的功能更全面,使用更簡單,關鍵的是雲貓OCR目前是徹底免費給你們用的。固然由於是試用版,可能存在一些bug,你們使用的時候不要亂按就行。雲貓展現版本的下載地址見帖子:  https://ai.baidu.com/forum/topic/show/955975
第二部分是雲貓OCR基於百度OCR的具體實現方式說明。 同時也會對軟件的部分核心代碼進行展現,便於你們進行參考作出更有創意的產品。
第三部分是雲貓OCR使用說明及效果評測。 但由於雲貓OCR是2017年末左右開發的,因此用的不是百度OCR最新接口功能,若是雲貓能獲得你們的支持,我能夠考慮開發新版接入更多百度最新的AI接口,但願你們能多多捧場。
本文的最後部分是附錄,附上了我基於百度OCR進行開發的代碼解讀,使用的是最新的百度手寫體識別接口,也一併打包給你們參考。編程

第一部分  雲貓OCR的軟件介紹緩存

1、雲貓OCR簡介網絡

   雲貓OCR是基於百度雲OCR算法,由進擊的狐狸進行開發的一款軟件。本軟件由C#語言進行開發,運行在Windows平臺上。主要調用的接口是通用文字識別、通用文字識別(高精度)和表格識別等。併發

2、雲貓OCR目前實現的主要功能:app

1.批量圖片文字識別,能夠預覽圖片,能夠對識別結果進行自動換行和縮進,能夠控制QPS併發(QPS功能由於百度雲的timeout問題而暫時擱置);函數

2.批量表格圖片識別,支持自動打開識別結果,用戶也能夠選擇直接打開保存目錄;post

3.PDF轉圖片,在個人筆記本(配置爲I7處理器/8G內存/128G SSD硬盤)的硬件環境下,PDF轉圖片程序模塊佔用的內存不超過400M,同時能夠在2分鐘左右的時間內轉換超過500頁內容的PDF文件。支持一鍵打開轉換結果文件夾。性能

4.雲貓軟件支持換膚功能,目前有兩套皮膚;

5.能夠設置API Key和Secret Key;

6.支持中途中止識別;

7.支持把設置改變後對同一張圖片進行從新識別;

8.支持多種語言;

9.其餘功能,好比識別統計信息、控制字體大小、右鍵把識別結果另存爲rtf文件、全選和複製識別結果等等;

3、演示帖子連接

http://ai.baidu.com/forum/topic/show/492371

4、雲貓OCR演示視頻連接

https://v.qq.com/x/page/r0564n4a87e.html

建議你們用1.2x或者1.5x倍速觀看,由於本人的聲速有點慢。

第二部分  雲貓OCR基於百度OCR的具體實現方式說明

1、概述

   雲貓OCR是基於百度AI,在Windows平臺運行的一款軟件。我是用C#語言在Visual Studio2017集成開發環境中進行開發的,開發方式是SDK包開發。在開發中,咱們須要參考百度的技術文檔。

百度雲文字識別技術文檔地址:

https://cloud.baidu.com/doc/OCR/index.html

2、準備工做

首先,咱們須要下載最新的百度文字識別的SDK包。

C# SDK包的下載地址以下:

http://ai.baidu.com/sdk#ocr

下載完畢後解壓縮,最新的包在文件夾net45裏面。

打開Visual Studio2017開發環境,選擇新建項目,由於我打算用控制檯項目講解,所以要選擇新建項目——C#控制檯項目。建好項目以後,須要在項目中引用上面下載的SDK包。

3、核心代碼講解

(一)調用百度OCR函數識別圖片文字,返回的格式爲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()

        {

            // 設置APPID/AK/SK

            var API_KEY = "你的 Api Key";

            var SECRET_KEY = "你的 Secret Key";

            //建立對象

            var client = new Baidu.Aip.Ocr.Ocr(API_KEY, SECRET_KEY);

            client.Timeout = 60000;  // 修改超時時間

            var image = File.ReadAllBytes("圖片文件路徑");

            // 調用通用文字識別, 圖片參數爲本地圖片,可能會拋出網絡等異常,請使用try/catch捕獲

            var result = client.GeneralBasic(image);

            Console.WriteLine(result);

        }

        static void Main(string[] args)

        {

            GeneralBasicDemo();

            Console.Read();

        }

    }

}

注意,具體開發的時候要把上面的API Key和Secret Key分別改成你本身的,至於怎麼申請和查看這兩個Key,能夠參考我寫的評測篇帖子。帖子連接以下:

http://ai.baidu.com/forum/topic/show/955989

另外不要忘了把圖片文件路徑改成你本身的圖片路徑。下面是識別的結果示例:

原圖以下:

(二)解析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()

        {

            // 設置APPID/AK/SK

            var API_KEY = "你的Akey";

            var SECRET_KEY = "你的SKey";

            //建立對象

            var client = new Baidu.Aip.Ocr.Ocr(API_KEY, SECRET_KEY);

            client.Timeout = 60000;  // 修改超時時間

            var image = File.ReadAllBytes(@"你的圖片路徑");

            // 調用通用文字識別, 圖片參數爲本地圖片,可能會拋出網絡等異常,請使用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";

            //顯示結果

            Console.WriteLine(txtOCR);

        }

        static void Main(string[] args)

        {

            GeneralBasicDemo();

            Console.Read();

        }

    }

}

程序運行結果以下:

這樣就比較符合人類的閱讀習慣了,上面這段代碼也是核心的基礎代碼,能夠經過這些核心的代碼去作一些優化,好比自動換行、自動縮進、根據語言習慣自動改變標點符號等等。

(三)表格識別

百度的表格文字識別的編程較爲麻煩,主要分紅兩步:第一步是提交表格文字識別請求,得到requestId;第二步是根據requestId獲取表格文字識別的結果,默認是Excel文件格式,Json結果會返回一段下載地址。

個人程序除了上面這兩步之外,還添加了自動下載Excel文件到本地電腦的代碼,供各位參考。另外要注意的是,提交識別請求和得到識別結果這兩步之間,程序必須設置延時,不然不能得到下載的URL 。通過實際測試,延時爲3秒以上較爲合適,3秒如下可能會出錯。

代碼以下:

/// 

 

        /// 表格文字識別

        /// 

 

        public static void myTableRecognitionRequestDemo()

        {

            // 設置APPID/AK/SK

            var API_KEY = "你的API Key";

            var SECRET_KEY = "你的Secret Key";

            //建立對象

            var client = new Baidu.Aip.Ocr.Ocr(API_KEY, SECRET_KEY);

            client.Timeout = 60000;  // 修改超時時間

            var image = File.ReadAllBytes(@"F:\表格圖片1.jpg");//這裏要改爲你的表格圖片路徑

            // 調用表格文字識別,可能會拋出網絡等異常,請使用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);

            //延時3秒,這句是必須的

            System.Threading.Thread.Sleep(3000);

            //獲取表格識別結果

            //有時會得不到連接,須要多嘗試幾回

            var resultExcel = client.TableRecognitionGetResult(requestId);

            Console.WriteLine("得到的表格識別結果以下:");

            Console.WriteLine(resultExcel);

            //解析Json,得到連接

            JObject joResult = (JObject)JsonConvert.DeserializeObject(resultExcel.ToString());

            string excelURL = joResult["result"]["result_data"].ToString();

            Console.WriteLine("得到的Excel文件下載地址是:\n" + excelURL);

            //自動下載Excel文件到電腦

            WebClient df = new WebClient();

            df.DownloadFile(excelURL, @"F:\識別結果.xls");//這裏要改爲你的下載文件路徑

            Console.WriteLine("下載完畢");

        }

做者使用的測試用圖片:

表格文字識別結果截圖:

尾記:本文的示例代碼都是最新的代碼,跟百度SDK文檔裏面的代碼是一致的,而云貓OCR是2017年底就已經寫好的了,代碼有些陳舊,因此沒直接貼源代碼了。

代碼篇的原帖子地址:

http://ai.baidu.com/forum/topic/show/956037

第三部分  雲貓OCR的使用說明及效果評測

1、概述

   筆者是在2017年接觸百度雲服務平臺的,在這裏我也稱之爲百度AI 。筆者根據百度AI提供的函數接口,自行編程實現了一款OCR軟件——雲貓OCR。雲貓OCR大部分的代碼開發是在2017年末前完成的,之因此雪藏到如今,是由於筆者的一些私人事務(小孩出生等)——我是利用業餘時間進行軟件開發的,因此中斷了大概一年多的時間,如今纔有空繼續這個項目。

評測篇的原帖子地址:

http://ai.baidu.com/forum/topic/show/955989

2、評測的具體內容

(一)準備工做

   在使用雲貓OCR以前,咱們必須先去百度雲官網進行註冊帳號,有了帳號之後,咱們還要去具體的雲服務項目下申請API Key和Secret Key ,通常這兩個Key是用戶各人保管的,不能隨便透露給外人。由於百度雲如今已經正式收費,而用戶每人天天的免費調用次數都是有限的,提升限額須要支付費用,用戶使用百度雲AI接口的依據主要就是這兩個Key,因此咱們要保管好。下面是簡單的準備工做圖片說明:

(二)正式使用雲貓OCR

用戶有了百度雲API Key和Secret Key以後,就能夠正式使用雲貓OCR了。具體使用步驟以下:

(三)評測的具體內容

   首先介紹一下雲貓OCR調用的百度AI的主要接口,首先是通用文字識別(帶位置版),其次是通用文字識別(帶位置高精度版),最後是表格文字識別,下面依次介紹這三種識別。

1. 通用文字識別(帶位置版)和通用文字識別(帶位置高精度版)的混合使用

如上圖所示,用戶能夠選擇多種語言(包括德語、法語、西班牙語等等),選擇好後點擊文字識別便可。由於百度雲提供的高精度文字識別接口只支持中英文,而通用的文字識別支持除中英文之外的多種語言,因此筆者在編寫軟件中,這兩種接口是混合使用的,具體怎麼混合使用請看代碼篇。通常狀況下,高精度的文字識別效果比通用的好,但也比較耗時。

本軟件支持識別的文字結果在本機保存爲文件,具體以下圖操做:

保存的文件是rtf格式,能夠用WPS或者Office Word打開。下面再給出一次性識別20張圖片的統計結果圖示:

從上圖能夠看出,百度雲的文字識別結果速度仍是不錯的,識別速度是平均大概2-3秒一張圖。

2. 表格文字識別

表格文字識別的主要步驟以下圖所示:

識別的結果軟件會自動保存爲Excel文件並打開,如圖:

從上圖能夠看出,表格文字識別的速度比普通文字識別要慢一些,大概須要5-6秒。

評測總結:百度OCR對於印刷體的識別仍是不錯的,比起之前的OCR軟件來講,百度OCR能夠說是革命性的進步。固然,它也有本身的短板。好比手寫體的識別,筆者尚未評測,但百度雲通用文字高精度接口對手寫體的識別是較差的。再好比QPS併發,個人理解是能夠提升OCR文字識別的速度,對於大量的圖片文字識別來講尤爲是重要,能夠節省大量時間。但遺憾的是,百度雲對併發好像作的不太好,程序不必定支持QPS併發,這個缺點咱們也是但願百度後面可以有所改正。

 

附錄:

C#編程實現手寫識別

1、概述

    本人是用C#編程,調用百度API接口實現手寫體識別的,參考了百度的產品文檔。

文檔地址:https://cloud.baidu.com/doc/OCR/index.html

2、代碼及解說

本人的源代碼大部分是來自百度的產品文檔,但其中也遇到了一些麻煩。好比文字識別的編碼問題,百度的代碼給出的編碼是Default,但在個人機器上這樣作會顯示亂碼。通過查找資料,我把編碼改爲UTF8,亂碼的問題才獲得解決。

做者的全部源代碼以下:

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

    {

        /// 

 

        /// 轉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

    {

        // 調用getAccessToken()獲取的 access_token建議根據expires_in 時間 設置緩存

        // 返回token示例

        public static String TOKEN = "24.adda70c11b9786206253ddb70affdc46.2592000.1493524354.282335-1234567";

 

        // 百度雲中開通對應服務應用的 API Key 建議開通應用的時候多選服務

        private static String clientId = "這裏改爲你的API Key";

        // 百度雲中開通對應服務應用的 Secret Key

        private static String clientSecret = "這裏改爲你的Secret Key";

        /// 

 

        /// 獲取token的函數

        /// 

 

        /// 

        public static String getAccessToken()

        {

            String authHost = "https://aip.baidubce.com/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;

            //Console.WriteLine(result);

            //本身加的代碼

            JObject jo = (JObject)JsonConvert.DeserializeObject(result.ToString());

            string myToken = jo["access_token"].ToString();

            Console.WriteLine("得到的Token是:" + myToken);

            return myToken;

        }

        

        /// 

 

        /// 手寫體文字識別

        /// 

 

        /// 

        /// 

        /// 

        public static string myHandwriting(string token,string filename)

        {

            //string token = "#####調用鑑權接口獲取的token#####";

            // 圖片的base64編碼

            string strbaser64 = FileUtils.getFileBase64(filename); 

            string host = "https://aip.baidubce.com/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;

            //這裏加上了一些參數

            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();

            //顯示結果是亂碼,嘗試改變編碼,通過測試須要改爲UTF8編碼

            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);

            string result = reader.ReadToEnd();

            Console.WriteLine("手寫文字識別:");

            //Console.WriteLine(result);

            //解析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";

            //顯示結果

            Console.WriteLine(txtOCR);

            return txtOCR;

        }

        static void Main(string[] args)

        {

            //這裏要改爲你的圖片路徑

            string filename = @"F:\手寫體5.jpg";

            string token = getAccessToken();

            myHandwriting(token,filename);

            Console.Read();

        }

    }

}

注意,上面的代碼中須要各位改爲本身的Akey和Skey,另外要改一下圖片路徑。若是返回的是亂碼,還須要改一下編碼。

識別的結果以下:

程序用的圖片文件以下:

做者kohakuarc

相關文章
相關標籤/搜索