0

一定時間後にクラッシュする 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 がそれを完全にキャッチできず、アプリケーション全体がクラッシュすることに気付きました。

編集:テストアプリの実行中、2ギガのメモリから始まりますが、どんどん増えていきます。147回ループした後、7.7ギガでクラッシュしました。

EDIT EDIT : 各反復後に Dispose の呼び出しに追加され、プログラムは 50 ~ 75 MB のメモリでかなり安定しています。

4

1 に答える 1

1

問題は Dispose であることがわかりました。

オブジェクトの必要がDisposeあります。さらに良いことに、オブジェクトを破棄して再利用しないでください。構成が変更されない限り、オブジェクトを再利用できます。悲しいことに、プリワープは構成に含まれているため、オブジェクトを再利用できない可能性があります。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
            }
于 2015-10-21T19:52:45.430 に答える