I have successfully implemented OpenCV's SIFT class as well as KNN seperatly, however now my task is to classify images using both SIFT features and KNN. being that the SIFT features are not images themselves - and just single points of an image how would I use OpenCV's KNearest() with the extracted SIFT features to classify the images?
these are the individual classes being used SIFT:
std::string pathSIFT = "C:path of images";
cv::Ptr<cv::SiftFeatureDetector> detector =
cv::SiftFeatureDetector::create();
cv::Ptr<cv::SiftDescriptorExtractor> descriptor =
cv::SiftDescriptorExtractor::create();
std::vector<cv::KeyPoint> keypoints;
cv::Mat output;
cv::Mat descriptors;
for (int j = 0; j < images2SIFT.size(); j++) {
detector->detect(images2SIFT.at(j), keypoints);
std::string s = std::to_string(j);
cv::drawKeypoints(images2SIFT.at(j), keypoints, output);
detector->detectAndCompute(images2SIFT.at(j), Mat(), keypoints, descriptors);
// Append the descriptors to the matrix
if (i == 0){
// If this is the first image, create the matrix
descriptors.copyTo(descriptors);
}
else{
// Otherwise, append the descriptors to the matrix
vconcat(descriptors, descriptors, descriptors);
}
if (!std::filesystem::exists(pathSIFT + s + ".jpg")) {
cv::imwrite(pathSIFT + s + ".jpg", output);
}
waitKey(200);
}
KNN algorithm:
Mat samples(data.size(), data[0].rows* data[0].cols, CV_32F);
for (int i = 0; i < samples.rows; i++)
{
Mat rowData = samples.row(i);
data[i].reshape(1, 1).convertTo(rowData, CV_32F);
}
Ptr<KNearest> knn = KNearest::create();
knn->setAlgorithmType(KNearest::Types::BRUTE_FORCE);
knn->train(samples, ROW_SAMPLE, labels);
// Classify new image from directory 2
vector<float> predictions;
for (int i = 0; i < dataToTest.size(); i++) {
Mat img = dataToTest.at(i);
Mat sample;
img.reshape(1, 1).convertTo(sample, CV_32F);
float response = knn->findNearest(sample, 1, noArray());
predictions.push_back(response);
}