2017-08-14 94 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秒处理图像的任务。