Tessnet 用完所有内存

Tessnet using up all memory

我正在尝试使用 Tessnet 库制作实时 OCR 应用程序。这个想法是将 5 张图像存储在一个位图数组中,并对它们执行 OCR(每 2 秒一次)。代码运行没问题,但似乎占用了很多内存。该应用程序运行了大约 30 分钟(当它用完大约 2GB 内存时),然后抛出内存不足异常。有解决这个问题的想法吗?谢谢

这是我的 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;            
}

在WEB上搜索后,我发现有很多关于使用Tessnet时由于Tessaract中的代码而导致内存泄漏的报告。在某些情况下,人们将 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();
    }


}

所以这个应用程序以一些基本参数作为参数。 (要测试代码,请使用 Properties > Debug > Command Line Arguments )。文件夹路径是第一个参数,它告诉应用程序查看存储所有图像的文件夹。然后用 Tessnet OCR 处理所有图像,并将结果写入 /path/result/result.txt 中的文本文件(/result文件夹由用户创建)

现在在我要处理图像的主应用程序中,放置以下代码。

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

其次,主应用程序使用以下代码调用控制台应用程序:

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 秒处理一次图像的任务是通过将第二组代码放在计时器滴答事件中来完成的。