2017-08-14 57 views
1

我正在嘗試使用Tessnet庫進行實時OCR應用程序。這個想法是將5個圖像存儲在一個位圖數組中,並對它們執行OCR(每2秒)。代碼運行正常,但它似乎佔用了大量的內存。應用程序運行時間爲30分鐘(當它耗用大約2GB內存時),然後引發內存不足異常。任何想法來解決這個問題?由於Tessnet使用所有內存

這是我的OCR功能:

private void makeOCR() 
{ 
    //Perform OCR in the image array 

    x1 = string.Empty; 

    //initialize OCR 
    Tesseract ocr = new tessnet2.Tesseract(); 
    ocr.Init(null, "eng", true); 

    //loop through 5 bitmaps 
    for (int i = 0; i < 5; i++) 
    { 
    var result = ocr.DoOCR(imageArray[i], Rectangle.Empty); 
    foreach (tessnet2.Word word in result) 
    { 
     x1 = x1 + word.Text; 
    } 
    x1 = x1 + Environment.NewLine; 
    } 

    ocr.Dispose(); 
    GC.Collect(); 

} 

而且,我想叫上一個新的線程計時器滴答事件(每2秒)這個函數。

private void timer1_Tick(object sender, EventArgs e) 
{ 
    System.Threading.Thread t1 = new System.Threading.Thread(makeOCR); 
    t1.Start(); 
    textBox1.Text = x1;    
} 

回答

1

在WEB搜索後發現,由於Tessaract中的代碼,在使用Tessnet時存在很多內存泄漏的報告。有人將Tessnet代碼加載到單獨的可執行文件中。我分享我的代碼,我曾經這樣做過。 (現在內存的使用只在主應用程序一直穩定在45 MB)

首先使用下面的代碼單獨的控制檯應用程序:

static void Main(string[] args) 
{ 
    // Runtime arguments: 
    // [0] Folder Path 
    // [1] N for numeral, A for all 
    // [2] separator string 
    // [3] echo (N for app closes silently, Y app waits for user input to close 

    //Initialize 
    string path = args[0]; 
    string num = args[1]; 
    string sep = args[2]; 
    string ech = args[3]; 
    string ocrval = String.Empty; 
    bool numeral = false; 

    if (num == "N") 
     numeral = true; 

    //Start TESSNET initialization 
    Tesseract ocr = new tessnet2.Tesseract(); 
    ocr.Init(null, "eng", numeral); 

    //Generate string array to read filenames in the path directory 
    string[] allFiles = Directory.GetFiles(path,"*",SearchOption.TopDirectoryOnly); 

    //Run OCR code 
    foreach (string fn in allFiles) 
    { 
     Bitmap bm = new Bitmap(fn); 
     var result = ocr.DoOCR(bm, Rectangle.Empty); 
     foreach (tessnet2.Word word in result) 
     { 
      ocrval = ocrval + word.Text; 
     } 
     ocrval = ocrval + sep; 
     bm.Dispose(); 
    } 

    //Write result to textfile 
    File.WriteAllText(path+"/result/result.txt", ocrval); 

    //echo output 
    if (ech == "Y") 
    { 
     Console.WriteLine(ocrval); 
     Console.WriteLine("Process Completed. Press any key to close"); 
     Console.ReadLine(); 
    } 


} 

所以這個應用程序需要一些基本的參數作爲參數。 (測試代碼使用了屬性>調試>命令行參數)。文件夾路徑是第一個參數,它告訴應用程序查看存儲所有圖像的文件夾。然後所有的圖像與Tessnet OCR處理,其結果被寫入的文本文件在/path/result/result.txt(所述/結果文件夾是由用戶創建)

現在,在我的主要應用程序中的圖像將被處理,下面的代碼被放置。

首先,位圖需要使用 Bitmap.Save方法保存在同一個工作目錄(workPath)中。

其次,控制檯應用程序是通過用下面的代碼的主應用程序名爲:

Process process = new Process(); 
process.StartInfo.FileName = "C:/temp/toe/Tessnet OCR Engine.exe"; 
process.StartInfo.Arguments = workPath + " N && N"; 

// workPath is the directory where all images are stored 
// N -> Numeral Only, A if all 
// && -> Separator to define each the termination of every image's text 
// N -> No Echo of results Y-> Show results on console and wait for user input. 

process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized; 
process.Start(); 
process.WaitForExit(); 

string res = File.ReadAllText(workPath.Text+"/result/result.txt"); 
string[] result; 
string[] stringSeparators = new string[] { "&&" }; 
result = res.Split(stringSeparators, StringSplitOptions.None); 

最後的result字符串數組保存所有的圖像在workPath目錄中的文本。該代碼需要一些異常處理。通過將第二組代碼放置在計時器滴答事件中來完成每2-3秒處理圖像的任務。