SURF 및 Naive Bayesian을 사용하여 분류 자 / 예측자를 만들려고합니다. 나는 Dance, Csurka의 "Keypoints 가방으로 시각적 분류"라는 기술을 거의 따르고 있습니다 ... 나는 SIFT 대신 SURF를 사용하고 있습니다.내 SURF/KMeans classifier에 문제가 있습니다
내 결과는 꽤 끔찍하며 내 오류가 어디에 있는지 잘 모르겠습니다. CalTec 세트에서 20 개의 자동차 샘플 (햄)과 20 개의 오토바이 샘플 (스팸)을 사용하고 있습니다. 나는 내가 어휘를 만드는 방식에 있다고 생각한다. 내가 볼 수있는 것은 EMGU/OpenCV kmeans2 분류기가 동일한 SURF 디스크립터 입력에서 다른 결과를 반환한다는 것입니다. 그것은 나를 의심스럽게 만든다. 지금까지 제 코드가 있습니다.
public Matrix<float> Extract<TColor, TDepth>(Image<TColor, TDepth> image)
where TColor : struct, Emgu.CV.IColor
where TDepth : new()
{
ImageFeature[] modelDescriptors;
using (var imgGray = image.Convert<Gray, byte>())
{
var modelKeyPoints = surfCPU.DetectKeyPoints(imgGray, null);
//the surf descriptor is a size 64 vector describing the intensity pattern surrounding
//the corresponding modelKeyPoint
modelDescriptors = surfCPU.ComputeDescriptors(imgGray, null, modelKeyPoints);
}
var samples = new Matrix<float>(modelDescriptors.Length, DESCRIPTOR_COUNT);//SURF Descriptors have 64 samples
for (int k = 0; k < modelDescriptors.Length; k++)
{
for (int i = 0; i < modelDescriptors[k].Descriptor.Length; i++)
{
samples.Data[k, i] = modelDescriptors[k].Descriptor[i];
}
}
//group descriptors into clusters using K-means to form the feature vectors
//create "vocabulary" based on square-error partitioning K-means
var centers = new Matrix<float>(CLUSTER_COUNT, samples.Cols, 1);
var term = new MCvTermCriteria();
var labelVector = new Matrix<int>(modelDescriptors.Length, 1);
var cluster = CvInvoke.cvKMeans2(samples, CLUSTER_COUNT, labelVector, term, 3, IntPtr.Zero, 0, centers, IntPtr.Zero);
//this is the quantized feature vector as described in Dance, Csurska Bag of Keypoints (2004)
var keyPoints = new Matrix<float>(1, CLUSTER_COUNT);
//quantize the vector into a feature vector
//making a histogram of the result counts
for (int i = 0; i < labelVector.Rows; i++)
{
var value = labelVector.Data[i, 0];
keyPoints.Data[0, value]++;
}
//normalize the histogram since it will have different amounts of points
keyPoints = keyPoints/keyPoints.Norm;
return keyPoints;
}
출력이 NormalBayesClassifier로 입력됩니다. 이것이 내가 그것을 훈련시키는 방법이다.
Parallel.For(0, hamCount, i =>
{
using (var img = new Image<Gray, byte>(_hams[i].FullName))
{
var features = _extractor.Extract(img);
features.CopyTo(trainingData.GetRow(i));
trainingClass.Data[i, 0] = 1;
}
});
Parallel.For(0, spamCount, j =>
{
using (var img = new Image<Gray, byte>(_spams[j].FullName))
{
var features = img.ClassifyFeatures(_extractor);
features.CopyTo(trainingData.GetRow(j));
trainingClass.Data[j + hamCount, 0] = 0;
}
});
using (var classifier = new NormalBayesClassifier())
{
if (classifier.Train(trainingData, trainingClass, null, null, false))
{
classifier.Save(_statModelFilePath);
}
}
나는 훈련 샘플의 모든 ... 햄과 스팸은 1 (경기를) 반환 NormalBayesClassifier을 사용하여 예측 호출 할 때.
도움을 주시면 감사하겠습니다.
편집. 한 가지 다른 참고 사항은 5 ~ 500 개의 CLUSTER_COUNT를 모두 동일한 결과로 선택했다는 것입니다.