Witam,
Próbuję stworzyć slownik na podstawie punktów kluczowych SIFT jednak przy funkcji bowTrainer.Cluster(), otrzymuję ciekawy wyjątek:
An unhandled exception of type 'System.AccessViolationException' occurred in Emgu.CV.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Dodam że korzystam z biblioteki Emgu2.9.0Beta.2.9.0 cała aplikacja jest ustawiona na wersję x64, czy to może powodować ten wyątek? Z tego co wiem to emgu powinno działać pod wersją 64bitową, może jest jakis inny problem w moim kodzie?
model = new Image<Bgr, byte>(imageData.Path);
modelGray = model.Convert<Gray, Byte>();
modelKeyPoints = detector.DetectKeyPointsRaw(modelGray, null);
modelDescriptors = detector.ComputeDescriptorsRaw(modelGray, null, modelKeyPoints);
Podejrzewam, że problem tkwi w tych linijkach, wykonuja one operacje na zdjęciach pobranych bezpośrednio ze ścieżek, po zakomentowaniu tego fragmentu i stworzeniu osobnej macierzy ze stalymi liczbami nie ma problemu.
Niestety przy recznym kopiowaniu wartości z matrycy modelDescriptors do nowej matrycy i osobnym rezerwowaniu pamięci dalej jest ten sam problem.
Main testowy:
static void Main()
{
const string pathImage = @"E:\IISI\testSIFT\";
const int dictionarySize = 10;
const int nFeatures = 0;
const int nOctaveLayers = 3;
const double contrastThreshold = 0.04;
const double edgeThreshold = 10;
const double sigma = 1.6;
var files = new DirectoryInfo(pathImage).GetFiles().Select(x => x.FullName).ToArray();
var bof = new BOF(files);
bof.ComputeDictionary(dictionarySize, nFeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma);
bof.ComputeDescriptors();
Console.ReadKey();
}
Klasa BOW:
public class BOF
{
public ImageData[] ImagesData { get; private set; }
public float[][] Dictionary { get; private set; }
public BOF(IList<string> trainFiles)
{
ImagesData = new ImageData[trainFiles.Count];
for (var i = 0; i < trainFiles.Count; i++)
ImagesData[i] = new ImageData
{
Path = trainFiles[i],
IsTrain = true
};
}
private float[][] GetArrayFromMatrix(Matrix<Single> matrix)
{
var array = new float[matrix.Data.Length][];
for (var i = 0; i < array.Length; i++)
array[i] = new float[matrix.Cols];
for (var i = 0; i < matrix.Rows; i++)
for (var j = 0; j < matrix.Cols; j++)
array[i][j] = matrix.Data[i, j];
return array;
}
public void ComputeDictionary(int dictionarySize, int nFeatures, int nOctaveLayers, double contrastThreshold, double edgeThreshold, double sigma)
{
var detector = new SIFTDetector(nFeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma);
var termCriteria = new MCvTermCriteria(100, 0.001);
var bowTrainer = new BOWKMeansTrainer(dictionarySize, termCriteria, 1, KMeansInitType.PPCenters);
Image<Bgr, byte> model;
Image<Gray, Byte> modelGray;
VectorOfKeyPoint modelKeyPoints;
Matrix<Single> modelDescriptors;
foreach (var imageData in ImagesData)
{
model = new Image<Bgr, byte>(imageData.Path);
modelGray = model.Convert<Gray, Byte>();
modelKeyPoints = detector.DetectKeyPointsRaw(modelGray, null);
modelDescriptors = detector.ComputeDescriptorsRaw(modelGray, null, modelKeyPoints);
imageData.Keypoints = GetArrayFromMatrix(modelDescriptors);
bowTrainer.Add(modelDescriptors);
}
var dictionary = bowTrainer.Cluster();
Dictionary = GetArrayFromMatrix(dictionary);
}
}