Sto provando a creare un programma C++ in cui ci sono molte immagini in un elenco rispetto a un'immagine di input. Ho capito tutto e il programma sta creando le partite DMatch
.OpenCV: confronto di più immagini utilizzando ORB
Ora sto cercando di determinare quale della lista di immagini che viene confrontata con l'immagine sorgente è la migliore corrispondenza. Ho provato per la prima volta a fare questo semplicemente confrontando quante partite ci sono tra le immagini, ma il problema è che quando un'immagine generata ha molti punti chiave; inoltre tendono ad avere molte partite, almeno nel mio programma.
Quindi, come è possibile determinare quale matrice di immagini corrisponde alla migliore immagine sorgente? Sto usando questo ciclo per determinare le partite, ma in realtà non funziona:
vector< vector<DMatch> > filteredMatches;
vector<int> goodIds;
Ptr<DescriptorMatcher> matcher(new BFMatcher(NORM_HAMMING, false));
printf("bad matches: ");
for(size_t i = 0; i < images.size();i++){
vector<DMatch> matches, good_matches;
matcher->clear();
matcher->match(images[i], tex_des, matches);
if(matches.size() < 8){
printf("F%d,", (int)i + 1);
continue;
}
double min_dist = 100;
for(size_t j = 0; j < matches.size(); j++){
double dist = matches[j].distance;
if(dist < min_dist)
min_dist = dist;
}
if(min_dist > 50.0){
printf("D%d,", (int)i + 1);
continue;
}
double good_dist = min_dist * 3;
for(size_t j = 0; j < matches.size(); j++){
if(matches[j].distance < good_dist)
good_matches.push_back(matches[j]);
}
size_t size = good_matches.size();
if(size < 8){
printf("M%d,", (int)i + 1);
continue;
}
vector<Point2f> srcPoints(size);
vector<Point2f> dstPoints(size);
for(size_t j = 0; j < size; j++){
srcPoints[j] = destination[good_matches[j].trainIdx].pt;
dstPoints[j] = keyPoints[i][good_matches[j].queryIdx].pt;
}
vector<unsigned char> inliersMask(srcPoints.size());
Mat H = findHomography(srcPoints, dstPoints, CV_FM_RANSAC, 3.0, inliersMask);
vector<DMatch> inliers;
for(size_t j = 0; j < inliersMask.size(); j++){
if(inliersMask[j]){
inliers.push_back(good_matches[j]);
}
}
if(inliers.size() < 4){
printf("S%d,", (int)i + 1);
continue;
}
filteredMatches.push_back(inliers);
goodIds.push_back((int)i);
H.release();
}
printf(" good matches: ");
int best = -1;
int amount = 0;
for(size_t i = 0; i < filteredMatches.size(); i++){
int size = (int)filteredMatches.at(i).size();
if(size < 8) continue;
printf("%d,", goodIds[i] + 1);
if(amount < size){
amount = size;
best = i;
}
}
if(best >= 0) printf(" best match on image: %d, keypoints: %d, ", goodIds[best] + 1, amount);
Se qualcuno mi può indicare le funzioni o la logica devo usare sarei molto grato!
Qual è il problema nel dire "La partita con il maggior numero di inlier è la mia migliore partita"? –
Anche questa è stata la prima cosa che ho pensato, ma quando l'ho provato non ho ottenuto risultati accurati. – tversteeg
OK, quindi le immagini (anche quelle false) sono abbastanza simili credo. Com'è la precisione se prendi la distanza media di tutte le partite o di tutti gli inlier? Puoi pubblicare immagini di esempio in cui ciò non riesce? –