MODI中的OCR模塊

做者:馬健
郵箱:stronghorse_mj@hotmail.com
發佈:2012.07.02
更新:
2012.07.09
補充非簡體中文版內容程序員

自從基於MODI的DjVuToy、FreePic2Pdf、Pdg2Pic發佈後,不少人就在問同一個問題:能不能在不裝Office 2003/2007或SharePoint Designer 2007的狀況下,讓基於MODI的軟件正常OCR?畢竟對於簡體中文來講,就算只裝SharePoint Designer 2007中的MODI,也要近650 MB,裝Office 2007的MODI則更誇張,要近1 GB。web

想解決這個問題,須要從MODI中OCR模塊的來歷提及。在《用MODI OCR 21種語言》一文中已經說過,MODI其實只是封裝了ScanSoft API,而google(注意我說的是google,不是baidu)一下關鍵詞「ScanSoft API」,能夠發現兩個網頁:
http://www.corrupteddatarecovery.com/Products/ScanSoft-API.asp
http://www.corrupteddatarecovery.com/Products/Asian-OCR-for-ScanSoft-API.aspide

從這兩個帖子及其餘一些相關信息推斷,ScanSoft API封裝了清華文通以支持亞洲語言,而MODI又在ScanSoft API上封裝出MODI接口,並在此基礎上提供MODI應用(MSPVIEW.EXE),整個層次結構應該以下圖所示:函數

——————           MSPVIEW.EXE
應用層                ┃
——————            MODI接口
接口層                ┃
                 ScanSoft API
             ┏━━━━━┻━━━━━┓
             ┃     ScanSoft API亞洲語言支持(清華文通)
——————       ┃              ┃
數據層      西歐11國、東歐3國、     亞洲語言文件
         俄、希、土語言文件    (簡、繁、日、朝)測試

從上圖看,若是隻想調用MODI接口,不須要應用層的支持,能夠有如下選擇:ui

  1. 直接調用ScanSoft API。這個比較有難度,至少我到目前爲止還找不到相關文檔。
  2. 仍是調用MODI接口,至少這個的文檔是公開的。

因此上面的問題就轉換成了:可否抽取出支持MODI接口的最小集合,實現OCR接口功能?google

身爲資深技術人員,對於這種問題的回答固然不能胡言亂語,而應該以實驗爲基礎:編碼

一、搞一個乾淨的XP SP3虛擬機,再複製一份,姑且命名爲「虛擬機A」、「虛擬機B」。
二、在虛擬機A中安裝InstallRite 2.5,用它監視安裝SharePoint Designer 2007中的MODI。
三、安裝完成後,用InstallRite導出安裝後新的註冊表,命名爲aaa.reg。
四、將虛擬機A中的兩個文件夾
C:\Program Files\Common Files\Microsoft Shared\MODI
C:\Program Files\Common Files\Microsoft Shared\OFFICE12
複製到虛擬機B,並將aaa.reg導入虛擬機B。畢竟MODI接口是COM接口,與註冊表無關的COM接口是不存在的。
五、運行DjVuToy、FreePic2Pdf或Pdg2Pic,能夠驗證在虛擬機B中可以用第三方軟件正常OCR,只不過每OCR一頁都要自動安裝一次文件,彷佛註冊表中摻入了垃圾。spa

以上可行性實驗清楚代表:
一、在不安裝Office或SharePoint Designer的狀況下,能夠經過複製相關文件和註冊表項,爲第三方軟件提供OCR支持。
二、對於簡體中文來講,單獨安裝Office 2007中的MODI須要約1 GB硬盤空間,單獨安裝SharePoint Designer 2007中的MODI則需約650 MB,而上面兩個文件夾加起來也只有約76 MB,況且中間還有水分可擠,空間的節省仍是很可觀的,因此這筆買賣作得過。命令行

無聊但又必不可少的理論扯完了,下面開始進入實戰:哪些文件和註冊表項纔是必不可少的?

先說文件。上面兩個URL中的內容,其實已經說明了接口層中ScanSoft API所需的文件,剩下須要解決的就是MODI接口部分的文件。

在第三方軟件中調用MODI接口的初始化代碼爲:
IDocument doc;
doc.CreateDispatch(_T("MODI.Document"));

在註冊表中搜索字符串「MODI.Document」,能夠知道此COM對象對應的DLL是MODI安裝文件夾下的MDIVWCTL.DLL。再看一眼VC++的Debug窗口,能夠知道在調用此DLL後,還接着調用了同文件夾下的MSPGIMME.DLL、MSPCORE.DLL,及OFFICE12文件夾下的MSO.DLL等。從文件屬性看,這些文件都是微軟鼓搗出來的,所以能夠認爲是接口層中MODI接口部分的東西。

從VC++的Debug窗口輸出信息看,除了上述DLL文件外,OCR過程當中還加載了MODI安裝文件夾下的XOCR3.PSP、THOCR.PSP、XFILE.PSP。這3個文件雖然擴展名是PSP,但實際上是DLL文件,從文件屬性看屬於ScanSoft API的範疇,能夠看做是對上面兩個URL中內容的補充。

另外VC++的Debug窗口中還記錄到OCR過程調用了OFFICE12文件夾下的OGL.DLL、MSORES.DLL、2052\MSOINTL.DLL,但在後來的迴歸性測試中證實,在對註冊表項進行簡化後,這幾個文件沒有也不要緊。

結合上面分析,及《用MODI OCR 21種語言》中的相關信息,可知要OCR簡體中文、英語,至少須要的文件以下表所示,加一塊兒也就約30 MB。其中「說明」部分的英文是從DLL文件的文件屬性中複製過來的,中文是我本身加的;數據層的數據文件是用文件監視器抓取的。

層次 文件名 說明
接口層 MODI MDIVWCTL.DLL Microsoft Office Document Imaging Viewer Control
MSPCORE.DLL Microsoft® Office Document Imaging Object Library
MSPGIMME.DLL Microsoft® Gimme library
OFFICE12\MSO.DLL 2007 Microsoft Office component
ScanSpft
API
BINDER.DLL XDoc Binder module for the ScanSoft SDK
PSOM.DLL Component Management Module for PefectScan API
XIMAGE3B.DLL Image Processing Module for the ScanSoft SDK
XPAGE3C.DLL Page Management Module for ScanSoft SDK
XOCR3.PSP OCR Module for ScanSoft SDK
XFILE.PSP Asian OCR Module for ScanSoft SDK
THOCR.PSP Asian OCR Module for ScanSoft SDK
ScanSoft
API亞洲
語言
FORM.DLL Table Recognition for Asian OCR
REVERSE.DLL Reverse Video Detection for Asian OCR
THOCRAPI.DLL Asian OCR API
TWCUTCHR.DLL Character Segmentation for Asian OCR
TWCUTLIN.DLL Line Segmentation for Asian OCR
TWLAY32.DLL Layout Analysis for Asian OCR
TWORIENT.DLL Orientataion Detection for Asian OCR
TWRECC.DLL Chinese Recognition for Asian OCR
TWRECE.DLL English Recognition for Asian OCR
TWRECS.DLL Punctuation Recognition for Asian OCR
TWSTRUCT.DLL Document Structure Processing for Asian OCR
數據層 英文 LATIN1.SHP 西歐11國(含英文)通用特徵庫
CharSetTable.chr 字符編碼轉換表,文本文件
ENGLISH.LNG 英文語言文件
簡體中文 ENGDIC.DAT 清華文通的英文字典文件,貌似它也支持中、英文
ENGIDX.DAT 清華文通的英文索引
JFONT.DAT  
LOOKUP.DAT  
OCRHC.DAT  
OCRVC.DAT  
TWGB32.DLL Simplified Chinese code Conversion
SCCODE.UNI  
SCPRINT.DAT  
SCPRINT2.DAT  
SCSERHT.DAT  
SCTREE.DAT  
TW_GU.DAT  
TW_UG.DAT  

若是還想增長對其餘語言的OCR能力,能夠參閱《用MODI OCR 21種語言》,增長相關語言對應的文件。

另外在上表中,在PSOM.DLL文件描述中出現了一個新的名字:PefectScan API。google了一下,找到其官網http://perfectscan.com/,從介紹上看是作圖像處理的:
PerfectScan is an image processing program that automatically analyzes an image, then makes adjustments to that image rendering a black and white image that contains all viewable data as if it were a gray scale scan, only at 15% of the size of a gray scale image.
看來MODI還真是一個大雜燴。不過PefectScan官網上的一句話,感受道盡了程序員的悲涼:
We built the software after 10 years of hard work, now all we have to do is build the website...OOPS!!

言歸正傳。搞定文件後,還須要搞定註冊表項才行。與MODI相關的註冊表項包括兩個部分:COM相關與Office相關。

COM相關就是與MODI的COM組件相關的註冊表項,這個直接用regsvr32導入便可:啓動命令行,進入MODI安裝文件夾,執行下面的命令:
regsvr32 MDIVWCTL.DLL
regsvr32 MSPCORE.DLL
便可完成MODI COM組件的註冊。

但與Office相關的註冊表項就沒那麼好搞定了。我曾經試過用註冊表監視器對OCR過程進行監視,結果發現真相淹沒在了細節的海洋裏。最終不得不採用了一個笨辦法:專門寫了一套測試軟件,在前面的可行性實驗中搭建的虛擬機B裏猛跑,逐一嘗試刪除從aaa.reg中導入的註冊表項,每刪除一項就檢查一下對OCR會不會形成影響。最終試出來約20個註冊表項是必不可少的,其中近一半與前面用regsvr32註冊COM組件時自動插入的註冊表項重複。

最終通過手工調整後,確認在上面表格所列文件及COM註冊基礎上,再增長下列註冊表項便可正經常使用第三方軟件在簡體中文環境下OCR簡體中文、英文:

[HKEY_CLASSES_ROOT\Installer\Components\61BA386016BD0C340BBEAC273D84FD5F]
"2052"=hex(7):76,00,55,00,70,00,41,00,56,00,53,00,2e,00,7d,00,58,00,25,00,21,\
00,21,00,21,00,21,00,21,00,4d,00,4b,00,4b,00,53,00,6b,00,4f,00,43,00,52,00,\
5f,00,32,00,30,00,35,00,32,00,3c,00,00,00,00,00

[HKEY_CLASSES_ROOT\Installer\Features\00002109F10040800000000000F01FEC]
"OCR_2052"=""

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\00002109F10040800000000000F01FEC\Features]
"OCR_2052"="%mEMae,7q9*DXdU@EPi="

[HKEY_CLASSES_ROOT\Installer\Products\00002109710000000000000000F01FEC]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\3F745FF6A76FF2F4797DB74FC7B3FD8B]
"00002109710000000000000000F01FEC"="C:\\Program Files\\Common Files\\Microsoft Shared\\MODI\\12.0\\XPAGE3C.DLL"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\4080B9FA1A0BBF34FB7813E87159FC64]
"00002109F10040800000000000F01FEC"="C:\\Program Files\\Common Files\\Microsoft Shared\\MODI\\12.0\\SCCODE.UNI"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\48AD0082D02B3D24C9A56FA50728CCAB]
"00002109710000000000000000F01FEC"="C:\\Program Files\\Common Files\\Microsoft Shared\\MODI\\12.0\\MSPCORE.DLL"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\D94C8360B8BB1DC41B1950E0F8237563]
"00002109710000000000000000F01FEC"="C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\00002109710000000000000000F01FEC\InstallProperties]
"WindowsInstaller"=dword:00000001

前三項的語言編碼2052對應簡體中文,但只要文件不缺,OCR中文、英文或其餘語言都沒有問題。不過在面對其餘國家的用戶時,解釋採用簡體中文的語言編碼仍是有點費勁,因此仍然須要繼續嘗試其餘語言編碼。

把兩個虛擬機復原,重複上面可行性實驗步驟:在虛擬機A中監視安裝英文版SharePoint Designer 2007(安裝後支持英、法、西班牙語),導出安裝後的註冊表和文件到虛擬機B,用同一套測試軟件進行檢查,出來的是否是與英文語言編碼1033相關的註冊表項呢?錯,大錯特錯,跑出來不能刪的是與法語(語言編碼1036)相關的註冊表項:

[HKEY_CLASSES_ROOT\Installer\Components\61BA386016BD0C340BBEAC273D84FD5F]
"1036"=hex(7):76,00,55,00,70,00,41,00,56,00,57,00,3f,00,57,00,41,00,24,00,21,\
00,21,00,21,00,21,00,21,00,4d,00,4b,00,4b,00,53,00,6b,00,4f,00,43,00,52,00,\
5f,00,31,00,30,00,33,00,36,00,3c,00,00,00,00,00

[HKEY_CLASSES_ROOT\Installer\Features\00002109F100C0400000000000F01FEC]
"OCR_1036"=""

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\00002109F100C0400000000000F01FEC\Features]
"OCR_1036"=")aEMae,7q9*DXdU@EPi="

[HKEY_CLASSES_ROOT\Installer\Products\00002109710000000000000000F01FEC]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\3F745FF6A76FF2F4797DB74FC7B3FD8B]
"00002109710000000000000000F01FEC"="C:\\Program Files\\Common Files\\Microsoft Shared\\MODI\\12.0\\XPAGE3C.DLL"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\48AD0082D02B3D24C9A56FA50728CCAB]
"00002109710000000000000000F01FEC"="C:\\Program Files\\Common Files\\Microsoft Shared\\MODI\\12.0\\MSPCORE.DLL"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\C040B9FA1A0BBF34FB7813E87159FC64]
"00002109F100C0400000000000F01FEC"="C:\\Program Files\\Common Files\\Microsoft Shared\\MODI\\12.0\\FRENCH.LNG"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\D94C8360B8BB1DC41B1950E0F8237563]
"00002109710000000000000000F01FEC"="C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\00002109710000000000000000F01FEC\InstallProperties]
"WindowsInstaller"=dword:00000001

對比兩個結果,能夠看出:

  1. 與語言相關的註冊表項共4項,其餘註冊表項都是相同的。
  2. 與語言相關的註冊表項前3項直接用語言編碼標識,第4項用語言文件標識,簡體中文的文件是SCCODE.UNI,法語是FRENCH.LNG。
  3. 與語言相關的註冊表項鍵值不是隨便亂起的,是在產品基本鍵值(SharePoint Designer的基本鍵值是00002109710000000000000000F01FEC)的基礎上,疊加相關語言編碼(簡體中文語言編碼2052,十六進制0804,Intel表示爲0408;法語語言編碼1036,Intel表示爲0C04)。敢這麼玩GUID的我就見過這麼一個,別人彷佛都沒這膽子。
  4. 無論採用什麼語言,均可以只有一種語言,但這種語言不能是英語(語言編碼1033)。

爲了驗證第4點,我從虛擬機A中手工導出英語相關注冊表項,在虛擬機B中把與法語相關的註冊表項所有換成英語的,結果OCR失敗。與英語相關的4個註冊表項爲:

[HKEY_CLASSES_ROOT\Installer\Components\61BA386016BD0C340BBEAC273D84FD5F]
"1033"=hex(7):76,00,55,00,70,00,41,00,56,00,54,00,28,00,38,00,41,00,24,00,21,\
00,21,00,21,00,21,00,21,00,4d,00,4b,00,4b,00,53,00,6b,00,4f,00,43,00,52,00,\
5f,00,31,00,30,00,33,00,33,00,3e,00,26,00,61,00,45,00,4d,00,61,00,65,00,2c,\
00,37,00,71,00,39,00,2a,00,44,00,58,00,64,00,55,00,40,00,45,00,50,00,69,00,\
3d,00,00,00,00,00

[HKEY_CLASSES_ROOT\Installer\Features\00002109F10090400000000000F01FEC]
"OCR_1033"=""

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\00002109F10090400000000000F01FEC\Features]
"OCR_1033"="&aEMae,7q9*DXdU@EPi=OFu[`t.WO9zoh+x^{BHE"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\9040B9FA1A0BBF34FB7813E87159FC64]
"00002109F10090400000000000F01FEC"="C:\\Program Files\\Common Files\\Microsoft Shared\\MODI\\12.0\\ENGLISH.LNG"

所以對於國內的用戶,直接上簡體中文的註冊表項就好;對於國外的用戶,若是對簡體中文解釋起來比較麻煩,就上法語或其餘語言的註冊表項吧 。但注意一次只能上一種語言,並且不能是英語。若是在上了一種語言的註冊表項的基礎上,再多此一舉上英語的註冊表項,會有問題:因爲前面對文件和註冊表項進行了精簡,在OCR時MODI組件若是發現有英文的註冊表項, 就會嘗試恢復被精簡的文件,形成OCR速度緩慢。

固然不管是哪種語言,在導入x64 Windows時,都要注意x64下32位軟件對應的Program Files文件夾多了一個後綴,改叫Program Files (x86)了。另外在理論上Program Files文件夾也是能夠不在C盤上的,因此最保險的方法是經過環境變量CommonProgramFiles、CommonProgramFiles(x86),或SHGetFolderPath等SDK函數獲取實際文件夾名稱。

另一個容易被問到的問題是:貌似導入的註冊表項中包含了文件路徑,那麼能不能經過改註冊表項的方法,改變MODI的安裝路徑,不裝到CommonProgramFiles文件夾下?答案是:不行。事實上,InstallRite 2.5導出的aaa.reg文件中的原始註冊表項裏,路徑名中是含有非法字符(問號)的,但並不影響使用,因此我懷疑文件夾是被寫死在MODI代碼裏的。

總之,上面說的都是在沒有安裝Office 2003/2007的狀況下的不得已方法,若是已經裝了,不只節省不了多少空間,並且可能會出現文件或註冊表項的衝突。

(完)

相關文章
相關標籤/搜索