2

emgu cv を使用して c# でマハラノビス距離を計算しようとしています。それぞれサイズが 100x100 の 3 つの画像があります。ステップは、最初に共分散行列を計算し、次に逆共分散行列を計算し、最後に別の新しい画像でマハラノビス距離を計算します。

しかし、逆共分散行列を計算すると、プログラムは SEHException をスローします。サイズが 3x3 の画像のみを使用すると、プログラムは完全に実行されます。最初は、共分散行列が大きすぎる (10000x10000) と思われるため、逆演算は失敗します。しかし、メモリの問題である場合は、OutOfMemoryException (CMIIW) をスローする必要があります。

SEHException の HResult は 0x80004005 または HRESULT E_FAIL であり、これは不特定の失敗です。これを修正する方法がわかりません。または、マハラノビス距離を安全に計算する別の方法があるでしょうか?

これは私の完全なコードです

    MySqlConnection SqlCon;
MySqlCommand SqlCmd;
MySqlDataReader SqlDataReader;
string ConString = "SERVER=localhost;" +
                    "USER=root;";
string CmdString;
string DBString = "TrainingDB";

Image<Gray, Byte>[] TrainingImage100 = new Image<Gray, byte>[3];
Image<Gray, float> covarImage = new Image<Gray, float>(10000, 10000);
Image<Gray, float> invCovarImage = new Image<Gray, float>(10000, 10000);
Image<Gray, float> averageImage = new Image<Gray, float>(100, 100);

SqlCon = new MySqlConnection(ConString);
try
{
    SqlCon.Open();

    CmdString = "USE `" + DBString + "`";
    SqlCmd = new MySqlCommand(CmdString, SqlCon);
    SqlCmd.ExecuteNonQuery();

    CmdString = "SELECT `face_image` FROM `face100_table` WHERE `person_id` = 1 LIMIT 1";
    SqlCmd = new MySqlCommand(CmdString, SqlCon);
    SqlDataReader = SqlCmd.ExecuteReader();
    while (SqlDataReader.Read())
    {
        byte[] blob = (byte[])SqlDataReader["face_image"];
        MemoryStream ms = new MemoryStream(blob);
        Bitmap bmp = new Bitmap(ms);
        Image<Gray, Byte> tempFrame = new Image<Gray, byte>(bmp);
        TrainingImage100[0] = tempFrame;
        ms.Close();
    }
    SqlDataReader.Close();

    CmdString = "SELECT `face_image` FROM `face100_table` WHERE `person_id` = 2 LIMIT 1";
    SqlCmd = new MySqlCommand(CmdString, SqlCon);
    SqlDataReader = SqlCmd.ExecuteReader();
    while (SqlDataReader.Read())
    {
        byte[] blob = (byte[])SqlDataReader["face_image"];
        MemoryStream ms = new MemoryStream(blob);
        Bitmap bmp = new Bitmap(ms);
        Image<Gray, Byte> tempFrame = new Image<Gray, byte>(bmp);
        TrainingImage100[1] = tempFrame;
        ms.Close();
    }
    SqlDataReader.Close();

    CmdString = "SELECT `face_image` FROM `face100_table` WHERE `person_id` = 3 LIMIT 1";
    SqlCmd = new MySqlCommand(CmdString, SqlCon);
    SqlDataReader = SqlCmd.ExecuteReader();
    while (SqlDataReader.Read())
    {
        byte[] blob = (byte[])SqlDataReader["face_image"];
        MemoryStream ms = new MemoryStream(blob);
        Bitmap bmp = new Bitmap(ms);
        Image<Gray, Byte> tempFrame = new Image<Gray, byte>(bmp);
        TrainingImage100[2] = tempFrame;
        ms.Close();
    }
    SqlDataReader.Close();
}
catch (Exception excpt)
{
    MessageBox.Show("load - " + excpt.Message);
}
SqlCon.Close();

IntPtr[] inObjs = Array.ConvertAll<Image<Gray, byte>, IntPtr>(TrainingImage100, delegate(Image<Gray, byte> img) { return img.Ptr; });

CvInvoke.cvCalcCovarMatrix(inObjs, 3, covarImage, averageImage, COVAR_METHOD.CV_COVAR_NORMAL);
Console.WriteLine(covarImage.Size);
Console.WriteLine(averageImage.Size);

CvInvoke.cvInvert(covarImage, invCovarImage, SOLVE_METHOD.CV_SVD_SYM);
Console.WriteLine(invCovarImage.Size);

method へのエラーポイントCvInvoke.cvInvert()。追加情報については、Visual Studio 2010 と emgu cv バージョン 2.3.0 を使用しています。

4

0 に答える 0