我遇到了OpenCV SVM的问题,特别是EmguCV的SVM,一个用于C#的OpenCV包装器。
我正在尝试使用SVM分类器查找图像区域。为此,我将图像通道用作3D协调空间中的点。
The SVM example from emguCV显示了一个2维分类器,但由于3个图像通道,我需要一个3维分类器:BGR。
下面的代码不会抛出异常:
var trainData = new Matrix<float>(trainSampleCount, 2);
但是,此代码在方法TrainAuto中引发异常:
var trainData = new Matrix<float>(trainSampleCount, 3);
例外是:
样本量与培训时间不同
有人能告诉我这是什么问题吗?
完整代码:
public Image<Bgr, byte> Process(Image<Bgr, byte> image)
{
const int kFold = 4;
var svm = new SVM();
var p = new SVMParams
{
KernelType = Emgu.CV.ML.MlEnum.SVM_KERNEL_TYPE.LINEAR,
SVMType = Emgu.CV.ML.MlEnum.SVM_TYPE.C_SVC,
C = 1,
TermCrit = new MCvTermCriteria(100, 0.001)
};
RaVec3[] beach = {
new RaVec3(182, 240, 251),
new RaVec3(187, 210, 228),
new RaVec3(187, 210, 228),
new RaVec3(191, 215, 236)
};
RaVec3[] montain = {
new RaVec3(44, 51, 52),
new RaVec3(43, 51, 52),
new RaVec3(84, 88, 69),
new RaVec3(36, 36, 26)
};
RaVec3[] ocean = {
new RaVec3(149,148,101),
new RaVec3(245, 221, 195),
new RaVec3(149,147,101),
new RaVec3(148,145,92)
};
RaVec3[] sky = {
new RaVec3(253,253,240),
new RaVec3(252,246,218),
new RaVec3(243, 253, 254),
new RaVec3(251,246,218)
};
var trainSampleCount = 4 * 4;
//Works with 2-dimmensional space, but throws an exceptions with 3-dimmensional space
var trainData = new Matrix<float>(trainSampleCount, 3);
var trainClasses = new Matrix<float>(trainSampleCount, 1);
var count = 0;
for (var i = 0; i < 4; i++ ) {
trainData[count, 0] = (float)beach[i].X;
trainData[count, 1] = (float)beach[i].Y;
trainData[count, 2] = (float)beach[i].Z;
trainClasses[count, 0] = 0;
count++;
}
for (var i = 0; i < 4; i++) {
trainData[count, 0] = (float)montain[i].X;
trainData[count, 1] = (float)montain[i].Y;
trainData[count, 2] = (float)montain[i].Z;
trainClasses[count, 0] = 1;
count++;
}
for (var i = 0; i < 4; i++) {
trainData[count, 0] = (float)ocean[i].X;
trainData[count, 1] = (float)ocean[i].Y;
trainData[count, 2] = (float)ocean[i].Z;
trainClasses[count, 0] = 2;
count++;
}
for (var i = 0; i < 4; i++) {
trainData[count, 0] = (float)sky[i].X;
trainData[count, 1] = (float)sky[i].Y;
trainData[count, 2] = (float)sky[i].Z;
trainClasses[count, 0] = 3;
count++;
}
//Here, the exception is thrown
svm.TrainAuto(trainData, trainClasses, null, null, p.MCvSVMParams, kFold);
for (var i = 0; i < image.Height; i++)
{
for (var j = 0; j < image.Width; j++)
{
var sample = new Matrix<float>(1, 2);
sample.Data[0, 0] = j;
sample.Data[0, 1] = i;
var response = (int)svm.Predict(sample);
image[i, j] =
response == 0 ? new Bgr(182, 240, 251) :
response == 1 ? new Bgr(44, 51, 52) :
response == 2 ? new Bgr(149, 148, 10) :
new Bgr(253, 253, 240);
}
}
var c = svm.GetSupportVectorCount();
for (var i = 0; i < c; i++)
{
var v = svm.GetSupportVector(i);
var p1 = new PointF(v[0], v[1]);
image.Draw(new CircleF(p1, 4), new Bgr(128, 128, 128), 2);
}
return image;
}