我已经分别成功实现了 OpenCV 的 SIFT 类和 KNN,但是现在我的任务是使用 SIFT 特征和 KNN 对图像进行分类。因为 SIFT 特征本身不是图像 - 而只是图像的单个点 我如何使用 OpenCV 的 KNearest() 和提取的 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算法:
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);
}