我正在将此代码从C ++转换为C#
Mat alpha, svidx;
double rho = svm->getDecisionFunction(0, alpha, svidx);
在C#中的EmguCV中找不到getDecisionFunction
的等效项。
答案 0 :(得分:0)
我认为getDecisionFunction
中的EmguCV
没有显式功能。我什至没有找到获取rho
,alpha
和svidx
所需值的直接方法。由于@deon cagadoes,我发现的唯一解决方案是使用OpenCV
OpenCV SVM的开源重写函数。但是,我无法直接获取所有数据,因此必须将SVM
的值写入文件,然后从该文件中获取所有我需要的东西。
private void TrainandLoad()
{
double rho;
Mat sv, alpha, svidx;
SVM svm;
svm.Train(train_data, Emgu.CV.ML.MlEnum.DataLayoutType.RowSample, labels);
svm.Save(TRAINED_SVM);
sv = svm.GetSupportVectors();
alpha = new Mat();
svidx = new Mat();
rho = GetDecisionFunction(0, alpha, svidx);
}
private double GetDecisionFunction(int i, IOutputArray alpha, IOutputArray svidx)
{
int j, nl, idf, class_count, sv_total, df_size, df_index_size, count;
string svmType, rem;
Mat tmp;
DecisionFunc df;
int[] sv_count;
string[] lines;
DecisionFunc[] dfs;
int[][] svind;
double[][] alph;
lines = File.ReadAllLines(TRAINED_SVM);
nl = 0;
svmType = "";
while (nl < lines.Length)
{
if (lines[nl].IndexOf("svmType") != -1)
{
svmType = lines[nl].Substring(lines[nl].IndexOf("svmType") + 9);
nl++;
break;
}
nl++;
}
if (svmType == "C_SVC" || svmType == "NU_SVC")
{
class_count = 2;
while (nl < lines.Length)
{
if (lines[nl].IndexOf("class_count") != -1)
{
class_count = Convert.ToInt32(lines[nl].Substring(lines[nl].IndexOf("class_count") + 13));
nl++;
break;
}
nl++;
}
df_size = class_count * (class_count - 1) / 2;
}
else
{
if (svmType == "ONE_CLASS")
class_count = 1;
else
class_count = 0;
df_size = 1;
}
sv_total = 1;
while (nl < lines.Length)
{
if (lines[nl].IndexOf("sv_total") != -1)
{
sv_total = Convert.ToInt32(lines[nl].Substring(lines[nl].IndexOf("sv_total") + 10));
nl++;
break;
}
nl++;
}
Debug.Assert(i <= 0 && i < df_size);
while (nl < lines.Length)
{
if (lines[nl].IndexOf("decision_functions") != -1)
{
nl++;
break;
}
nl++;
}
sv_count = new int[df_size];
dfs = new DecisionFunc[df_size];
svind = new int[df_size][];
alph = new double[df_size][];
idf = dfs[0].ofs = df_index_size = 0;
while (nl < lines.Length && idf < df_size)
{
if (lines[nl].IndexOf("sv_count") != -1)
sv_count[idf] = Convert.ToInt32(lines[nl].Substring(lines[nl].IndexOf("sv_count") + 10));
else if (lines[nl].IndexOf("rho") != -1)
dfs[idf].rho = Convert.ToDouble(lines[nl].Substring(lines[nl].IndexOf("rho") + 5));
else if (lines[nl].IndexOf("alpha") != -1)
{
alph[idf] = new double[sv_count[idf]];
rem = lines[nl].Substring(lines[nl].IndexOf("alpha") + 9);
for (j = 0; j < sv_count[idf]; j++)
{
while (rem[0] == ' ')
rem = rem.Substring(1);
alph[idf][j] = Convert.ToDouble(rem.Substring(0, rem.IndexOf(' ')));
rem = rem.Substring(rem.IndexOf(' '));
}
if (idf != 0)
dfs[idf].ofs = dfs[idf - 1].ofs + sv_count[idf];
df_index_size += sv_count[idf];
if (class_count < 2)
idf++;
}
else if (lines[nl].IndexOf("index") != -1)
{
svind[idf] = new int[sv_count[idf]];
rem = lines[nl].Substring(lines[nl].IndexOf("index") + 9);
for (j = 0; j < sv_count[idf]; j++)
{
while (rem[0] == ' ')
rem = rem.Substring(1);
svind[idf][j] = Convert.ToInt32(rem.Substring(0, rem.IndexOf(' ')));
rem = rem.Substring(rem.IndexOf(' '));
}
idf++;
}
nl++;
}
df = dfs[i];
//Get SV Count
count = (i < df_size - 1 ? dfs[i + 1].ofs : df_index_size) - dfs[i].ofs;
if (class_count < 2)
{
svind[0] = new int[sv_total];
for (j = 0; j < sv_total; j++)
svind[0][j] = j;
}
tmp = new Mat(1, count, DepthType.Cv64F, 1);
tmp.SetTo<double>(alph[i]);
tmp.CopyTo(alpha);
tmp.Dispose();
tmp = new Mat(1, count, DepthType.Cv32S, 1);
tmp.SetTo<int>(svind[i]);
tmp.CopyTo(svidx);
tmp.Dispose();
return df.rho;
}
我希望我做得正确,我希望有人可以根据我的试验为这个问题提供一个痛苦的解决方案。