OpenALPR 崩溃 - 试图读取或写入受保护的内存
OpenALPR crash - Attempted to read or write protected memory
我有一个 C# 程序在经过一段时间后崩溃。我已经追踪到 OpenALPR,现在已经在测试程序中复制了这个问题。
我基本上要求在 while 循环中从图像中获取图版。经过一系列迭代后它失败了。迭代后失败:179、221、516、429、295、150
程序输出:
...
Iter (219) No Plates Found in image 71197e9d829d4d429e74a71c983380dc_09032015
134103267.jpg
Config file location provided via API
LBP Time: 0.005ms.
Total Time to process image: 1.916ms.
Iter (220) No Plates Found in image 71197e9d829d4d429e74a71c983380dc_09032015
134103267.jpg
Config file location provided via API
LBP Time: 0.003ms.
Total Time to process image: 4.071ms.
Iter (221) No Plates Found in image 71197e9d829d4d429e74a71c983380dc_09032015
134103267.jpg
Config file location provided via API
失败信息:
Unhandled Exception:
Unhandled Exception: System.AccessViolationException: Attempted to read or write
protected memory. This is often an indication that other memory is corrupt.
at openalprnet.AlprNet.Dispose(Boolean )
System.AccessViolationException: Attempted to read or write protected memory. Th
is is often an indication that other memory is corrupt.
at alpr.Alpr.{ctor}(Alpr* , basic_string<char\,std::char_traits<char>\,std::a
llocator<char> >* , basic_string<char\,std::char_traits<char>\,std::allocator<ch
ar> >* , basic_string<char\,std::char_traits<char>\,std::allocator<char> >* )
at openalprnet.AlprNet..ctor(String country, String configFile, String runtim
eDir)
at AlprTest.Program.Main(String[] args) in C:\Users\foo\Desktop\c#LPR\A
lprTest\Program.cs:line 25
有一次,我还收到了另一条错误消息的一部分(不确定是否相关):Unable to load regex: @###@@
。虽然上面的错误指向 CTOR,但在我的正常应用程序中,它在识别调用期间失败了。我也在 openalprnet.AlprNet.Dispose(Boolean)
中看到(不确定这些堆栈跟踪有多准确)它是从 alpr.Alpr.{ctor}(...
调用的
我的测试程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using openalprnet;
namespace AlprTest
{
class Program
{
static void Main(string[] args)
{
string chipPath = "71197e9d829d4d429e74a71c983380dc_09032015134103267.jpg";
string confPath = Path.GetFullPath(".\openalpr.conf");
string runtimeDirPath = Path.GetFullPath(".\runtime_data");
int i = 0;
while (true)
{
++i;
try
{
// Look at target velocity and pick a conf file to use.
//
AlprNet alpr = new AlprNet("us", confPath, runtimeDirPath);
if (!alpr.isLoaded())
{
return;
}
// Optionally apply pattern matching for a particular region
alpr.DefaultRegion = "va"; // was md
alpr.DetectRegion = true;
AlprResultsNet results = alpr.recognize(chipPath);
if (results.plates.Count < 1)
{
Console.WriteLine(" Iter ({1}) No Plates Found in image {0}", chipPath, i);
}
else
{
int j = 0;
foreach (var result in results.plates)
{
Console.WriteLine("Plate {0}: {1} result(s)", ++j, result.topNPlates.Count);
Console.WriteLine(" Processing Time: {0} msec(s)", result.processing_time_ms);
foreach (var plate in result.topNPlates)
{
Console.WriteLine(" - {0}\t Confidence: {1}\tMatches Template: {2}", plate.characters,
plate.overall_confidence, plate.matches_template);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in LPR processing. Ex={0}", ex);
return;
}
}
}
}
}
该程序依赖于 openalpr 发行版和相应的 opencv dll。 openalpr-net.dll, liblept170.dll, opencv_core248.dll, opencv_features2d248.dll, opencv_ffmpeg248.dll, opencv_flann248.dll, opencv_highgui248.dll, opencv_imgproc248.dll, opencv_objdetect248.dll, opencv_video248.dll
。它还使用了一个 runtime_data 目录(我只是从示例应用程序中复制的),其中似乎包含训练数据等。
很明显,我使用的是 C#。我正在使用 Visual Studio 2010 和 .NET 4.0
我假设我使用的 OpenALPR 有误,事实上,它没有任何问题。这似乎是一个非常基本的功能。除了修复它之外……为什么这会使我的程序崩溃,我该如何捕捉并恢复?你注意到我的 try-catch 完全没有捕捉到它,它导致整个应用程序崩溃。
编辑:
虽然 运行 测试应用程序,它从大约 2gig 的内存开始,但它一直在增长、增长和增长。它在 147 个循环后以 7.7 gig 崩溃。
编辑编辑:
在每次迭代后添加到对 Dispose 的调用中,现在程序在 50-75 兆内存上相当稳定。
原来是 Dispose 的问题。
需要Dispose
的对象。更好的是,不要丢弃该对象并重新使用它。只要配置不变,您就可以重用该对象。遗憾的是,prewarp 在配置中,因此您可能无法重用该对象。在对象离开范围之前调用 Dispose
。
try
{
// Look at target velocity and pick a conf file to use.
//
AlprNet alpr = new AlprNet("us", confPath, runtimeDirPath);
if (!alpr.isLoaded())
{
return;
}
// Optionally apply pattern matching for a particular region
alpr.DefaultRegion = "va"; // was md
alpr.DetectRegion = true;
AlprResultsNet results = alpr.recognize(chipPath);
...
alpr.Dispose(); // Dispose of the object so it can clean up
}
我有一个 C# 程序在经过一段时间后崩溃。我已经追踪到 OpenALPR,现在已经在测试程序中复制了这个问题。
我基本上要求在 while 循环中从图像中获取图版。经过一系列迭代后它失败了。迭代后失败:179、221、516、429、295、150
程序输出:
...
Iter (219) No Plates Found in image 71197e9d829d4d429e74a71c983380dc_09032015
134103267.jpg
Config file location provided via API
LBP Time: 0.005ms.
Total Time to process image: 1.916ms.
Iter (220) No Plates Found in image 71197e9d829d4d429e74a71c983380dc_09032015
134103267.jpg
Config file location provided via API
LBP Time: 0.003ms.
Total Time to process image: 4.071ms.
Iter (221) No Plates Found in image 71197e9d829d4d429e74a71c983380dc_09032015
134103267.jpg
Config file location provided via API
失败信息:
Unhandled Exception:
Unhandled Exception: System.AccessViolationException: Attempted to read or write
protected memory. This is often an indication that other memory is corrupt.
at openalprnet.AlprNet.Dispose(Boolean )
System.AccessViolationException: Attempted to read or write protected memory. Th
is is often an indication that other memory is corrupt.
at alpr.Alpr.{ctor}(Alpr* , basic_string<char\,std::char_traits<char>\,std::a
llocator<char> >* , basic_string<char\,std::char_traits<char>\,std::allocator<ch
ar> >* , basic_string<char\,std::char_traits<char>\,std::allocator<char> >* )
at openalprnet.AlprNet..ctor(String country, String configFile, String runtim
eDir)
at AlprTest.Program.Main(String[] args) in C:\Users\foo\Desktop\c#LPR\A
lprTest\Program.cs:line 25
有一次,我还收到了另一条错误消息的一部分(不确定是否相关):Unable to load regex: @###@@
。虽然上面的错误指向 CTOR,但在我的正常应用程序中,它在识别调用期间失败了。我也在 openalprnet.AlprNet.Dispose(Boolean)
中看到(不确定这些堆栈跟踪有多准确)它是从 alpr.Alpr.{ctor}(...
我的测试程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using openalprnet;
namespace AlprTest
{
class Program
{
static void Main(string[] args)
{
string chipPath = "71197e9d829d4d429e74a71c983380dc_09032015134103267.jpg";
string confPath = Path.GetFullPath(".\openalpr.conf");
string runtimeDirPath = Path.GetFullPath(".\runtime_data");
int i = 0;
while (true)
{
++i;
try
{
// Look at target velocity and pick a conf file to use.
//
AlprNet alpr = new AlprNet("us", confPath, runtimeDirPath);
if (!alpr.isLoaded())
{
return;
}
// Optionally apply pattern matching for a particular region
alpr.DefaultRegion = "va"; // was md
alpr.DetectRegion = true;
AlprResultsNet results = alpr.recognize(chipPath);
if (results.plates.Count < 1)
{
Console.WriteLine(" Iter ({1}) No Plates Found in image {0}", chipPath, i);
}
else
{
int j = 0;
foreach (var result in results.plates)
{
Console.WriteLine("Plate {0}: {1} result(s)", ++j, result.topNPlates.Count);
Console.WriteLine(" Processing Time: {0} msec(s)", result.processing_time_ms);
foreach (var plate in result.topNPlates)
{
Console.WriteLine(" - {0}\t Confidence: {1}\tMatches Template: {2}", plate.characters,
plate.overall_confidence, plate.matches_template);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in LPR processing. Ex={0}", ex);
return;
}
}
}
}
}
该程序依赖于 openalpr 发行版和相应的 opencv dll。 openalpr-net.dll, liblept170.dll, opencv_core248.dll, opencv_features2d248.dll, opencv_ffmpeg248.dll, opencv_flann248.dll, opencv_highgui248.dll, opencv_imgproc248.dll, opencv_objdetect248.dll, opencv_video248.dll
。它还使用了一个 runtime_data 目录(我只是从示例应用程序中复制的),其中似乎包含训练数据等。
很明显,我使用的是 C#。我正在使用 Visual Studio 2010 和 .NET 4.0
我假设我使用的 OpenALPR 有误,事实上,它没有任何问题。这似乎是一个非常基本的功能。除了修复它之外……为什么这会使我的程序崩溃,我该如何捕捉并恢复?你注意到我的 try-catch 完全没有捕捉到它,它导致整个应用程序崩溃。
编辑: 虽然 运行 测试应用程序,它从大约 2gig 的内存开始,但它一直在增长、增长和增长。它在 147 个循环后以 7.7 gig 崩溃。
编辑编辑: 在每次迭代后添加到对 Dispose 的调用中,现在程序在 50-75 兆内存上相当稳定。
原来是 Dispose 的问题。
需要Dispose
的对象。更好的是,不要丢弃该对象并重新使用它。只要配置不变,您就可以重用该对象。遗憾的是,prewarp 在配置中,因此您可能无法重用该对象。在对象离开范围之前调用 Dispose
。
try
{
// Look at target velocity and pick a conf file to use.
//
AlprNet alpr = new AlprNet("us", confPath, runtimeDirPath);
if (!alpr.isLoaded())
{
return;
}
// Optionally apply pattern matching for a particular region
alpr.DefaultRegion = "va"; // was md
alpr.DetectRegion = true;
AlprResultsNet results = alpr.recognize(chipPath);
...
alpr.Dispose(); // Dispose of the object so it can clean up
}