Tessnet耗尽了所有内存

时间:2017-08-14 05:47:26

标签: c# multithreading memory ocr

我正在尝试使用Tessnet库创建一个实时OCR应用程序。这个想法是在Bitmap数组中存储5个图像并对它们执行OCR(每2秒)。代码运行正常,但它似乎占用了大量内存。应用程序运行30分钟(当它耗尽大约2GB内存时),然后抛出Out of Memory异常。有什么想法解决这个问题?感谢

这是我的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 个答案:

答案 0 :(得分: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();
    }


}

所以这个应用程序将一些基本参数作为参数。 (要测试使用了属性&gt; Debug&gt;命令行参数的代码)。文件夹路径是第一个参数,它告诉应用程序查看存储所有图像的文件夹。然后使用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秒处理图像的任务是通过将第二组代码放入计时器刻度事件中来完成的。