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。

想解決這個問題,需要從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.asp

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

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

從上圖看,如果只想調用MODI接口,不需要應用層的支持,可以有以下選擇:

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

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

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

1、搞一個干凈的XP SP3虛擬機,再復制一份,姑且命名為“虛擬機A”、“虛擬機B”。
2、在虛擬機A中安裝InstallRite 2.5,用它監視安裝SharePoint Designer 2007中的MODI。
3、安裝完成后,用InstallRite導出安裝后新的注冊表,命名為aaa.reg。
4、將虛擬機A中的兩個文件夾
C:\Program Files\Common Files\Microsoft Shared\MODI
C:\Program Files\Common Files\Microsoft Shared\OFFICE12
復制到虛擬機B,並將aaa.reg導入虛擬機B。畢竟MODI接口是COM接口,與注冊表無關的COM接口是不存在的。
5、運行DjVuToy、FreePic2Pdf或Pdg2Pic,可以驗證在虛擬機B中能夠用第三方軟件正常OCR,只不過每OCR一頁都要自動安裝一次文件,似乎注冊表中摻入了垃圾。

以上可行性實驗清楚表明:
1、在不安裝Office或SharePoint Designer的情況下,可以通過復制相關文件和注冊表項,為第三方軟件提供OCR支持。
2、對於簡體中文來說,單獨安裝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的情況下的不得已方法,如果已經裝了,不僅節省不了多少空間,而且可能會出現文件或注冊表項的沖突。

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM