Im в настоящее время работает над созданием программного обеспечения, которое может соответствовать инфракрасным и неинфракрасным изображениям, снятым с фиксированной точки с помощью термографической камеры.
Вариант использования: изображение берется из штатива неподвижной точки с помощью инфракрасной термографической камеры и стандартной камеры. После фотографирования фотограф хочет совместить изображения с каждой камеры. Будут некоторые сценарии, где изображение берется только с одной камерой, так как другой тип изображения не нужен. Да, возможно, что изображения могут быть сопоставлены с использованием временных меток, но конечный пользователь требует, чтобы они соответствовали компьютерному видению.
Я смотрел другие записи соответствия изображений на StackOverflow - они часто фокусировались на использовании сопоставления гистограммы и детекторов функций. Соответствие гистограмм здесь не является вариантом, так как мы не можем сопоставлять цвета между двумя типами изображений. В результате я разработал приложение, которое обнаруживает функцию. Помимо стандартного обнаружения функций, Ive также добавила некоторую логику, в которой говорится, что две ключевые точки не могут быть сопоставлены, если они не находятся в пределах определенного поля друг от друга (ключевая точка в левом углу изображения запроса не может совпадать с ключевой точкой справа изображения кандидата) - этот процесс происходит на третьем этапе кода ниже.
Чтобы дать вам представление о текущем выводе, вот действующее и недопустимое совпадение - отметить, что термографическое изображение находится слева. Моя цель - повысить точность процесса сопоставления.
Допустимое совпадение:
Неверное совпадение:
Вот код:
// for each candidate image specified on the command line, compare it against the query image
Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE); // loading query image
for(int candidateImage = 0; candidateImage < (argc - 2); candidateImage++) {
Mat img2 = imread(argv[candidateImage + 2], CV_LOAD_IMAGE_GRAYSCALE); // loading candidate image
if(img1.empty() || img2.empty())
{
printf("Can't read one of the images\n");
return -1;
}
// detecting keypoints
SiftFeatureDetector detector;
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
// computing descriptors
SiftDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
// matching descriptors
BFMatcher matcher(NORM_L1);
vector< vector<DMatch> > matches_stage1;
matcher.knnMatch(descriptors1, descriptors2, matches_stage1, 2);
// use nndr to eliminate weak matches
float nndrRatio = 0.80f;
vector< DMatch > matches_stage2;
for (size_t i = 0; i < matches_stage1.size(); ++i)
{
if (matches_stage1[i].size() < 2)
continue;
const DMatch &m1 = matches_stage1[i][0];
const DMatch &m2 = matches_stage1[i][3];
if(m1.distance <= nndrRatio * m2.distance)
matches_stage2.push_back(m1);
}
// eliminate points which are too far away from each other
vector<DMatch> matches_stage3;
for(int i = 0; i < matches_stage2.size(); i++) {
Point queryPt = keypoints1.at(matches_stage2.at(i).queryIdx).pt;
Point trainPt = keypoints2.at(matches_stage2.at(i).trainIdx).pt;
// determine the lowest number here
int lowestXAxis;
int greaterXAxis;
if(queryPt.x <= trainPt.x) { lowestXAxis = queryPt.x; greaterXAxis = trainPt.x; }
else { lowestXAxis = trainPt.x; greaterXAxis = queryPt.x; }
int lowestYAxis;
int greaterYAxis;
if(queryPt.y <= trainPt.y) { lowestYAxis = queryPt.y; greaterYAxis = trainPt.y; }
else { lowestYAxis = trainPt.y; greaterYAxis = queryPt.y; }
// determine if these points are acceptable
bool acceptable = true;
if( (lowestXAxis + MARGIN) < greaterXAxis) { acceptable = false; }
if( (lowestYAxis + MARGIN) < greaterYAxis) { acceptable = false; }
if(acceptable == false) { continue; }
//// it acceptable -- provide details, perform input
matches_stage3.push_back(matches_stage2.at(i));
}
// output how many individual matches were found for this training image
cout << "good matches found for candidate image # " << (candidateImage+1) << " = " << matches_stage3.size() << endl;
Я использовал этот код сайта в качестве примера. Проблема Im заключается в том, что обнаружение функции не является надежным, и, похоже, мне не хватает цели соотношения NNDR. Я понимаю, что я нахожу K возможных совпадений для каждой точки в изображении запроса и что у меня есть K = 2. Но я не понимаю цели этой части в примере кода:
vector< DMatch > matches_stage2;
for (size_t i = 0; i < matches_stage1.size(); ++i)
{
if (matches_stage1[i].size() < 2)
continue;
const DMatch &m1 = matches_stage1[i][0];
const DMatch &m2 = matches_stage1[i][1];
if(m1.distance <= nndrRatio * m2.distance)
matches_stage2.push_back(m1);
}
Любые идеи о том, как я могу улучшить это дальше? Любые советы будут оценены как всегда.