我正在尝试使用 emgu cv 在 c# 中计算马氏距离。我有 3 张图像,每张尺寸为 100x100。步骤是,首先计算协方差矩阵,然后计算逆协方差矩阵,最后计算与另一个新图像的马氏距离。
但是当我计算逆协方差矩阵时,程序会抛出 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);
错误指向方法CvInvoke.cvInvert()
。对于其他信息,我正在使用 Visual Studio 2010 和 emgu cv 2.3.0 版。