Ich versuche, ein C++ Programm zu schreiben, für bestimmte Bilder (Logo) in Bildern zu sehen, und ich habe Code verwendet, um von hier: http://docs.opencv.org/2.4/doc/tutorials/features2d/feature_homography/feature_homography.htmlFinden Logo in Bild
Also, ich habe zwei Bilder - eines ist ein Logo, und das andere enthält es (oder nicht). Logos können gedreht oder skaliert oder teilweise abgedeckt werden. Aber jetzt versuche ich, für jeden Fall ein zufriedenstellendes Ergebnis zu erzielen, aber den Vergleich zweier identischer Bilder. Bis jetzt waren meine Ergebnisse nichts weniger als schrecklich. Ich habe ein BMW Logo und ein Bild, das das Logo und einige abstrakte Zeichnung enthält. Matching scheint hoffnungslos zufällig zu sein. Ich würde mich über alle Ideen/Vorschläge freuen, wie diese Arbeit besser gemacht werden kann. Der Code Ich bin mit:
#include <stdio.h>
#include <iostream>
#include <stdio.h>
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/xfeatures2d.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d.hpp>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
int main(){
Mat img_object = imread("bmw_logo.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat img_scene = imread("bmw_search.jpg", CV_LOAD_IMAGE_GRAYSCALE);
resize(img_object, img_object, Size(img_object.cols/2, img_object.rows/2));
resize(img_scene, img_scene, Size(img_scene.cols/2, img_scene.rows/2));
if (!img_object.data || !img_scene.data){
std::cout << " --(!) Error reading images " << std::endl; return -1;
}
//-- Step 1: Detect the keypoints using SURF Detector
int minHessian = 400;
Ptr<SURF> detector = SURF::create(minHessian);
std::vector<KeyPoint> keypoints_object, keypoints_scene;
detector->detect(img_object, keypoints_object);
detector->detect(img_scene, keypoints_scene);
//-- Step 2: Calculate descriptors (feature vectors)
Ptr<SURF> extractor = SURF::create(minHessian);
Mat descriptors_object, descriptors_scene;
extractor->compute(img_object, keypoints_object, descriptors_object);
extractor->compute(img_scene, keypoints_scene, descriptors_scene);
//-- Step 3: Matching descriptor vectors using FLANN matcher
FlannBasedMatcher matcher;
std::vector<DMatch> matches;
matcher.match(descriptors_object, descriptors_scene, matches);
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for (int i = 0; i < descriptors_object.rows; i++){
double dist = matches[i].distance;
if (dist < min_dist) min_dist = dist;
if (dist > max_dist) max_dist = dist;
}
printf("-- Max dist : %f \n", max_dist);
printf("-- Min dist : %f \n", min_dist);
//-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist)
std::vector<DMatch> good_matches;
for (int i = 0; i < descriptors_object.rows; i++) {
if (matches[i].distance < 3 * min_dist) {
good_matches.push_back(matches[i]);
}
}
Mat img_matches;
drawMatches(img_object, keypoints_object, img_scene, keypoints_scene,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
//-- Localize the object
std::vector<Point2f> obj;
std::vector<Point2f> scene;
for (int i = 0; i < good_matches.size(); i++) {
//-- Get the keypoints from the good matches
obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
}
Mat H = findHomography(obj, scene, CV_RANSAC);
//-- Get the corners from the image_1 (the object to be "detected")
std::vector<Point2f> obj_corners(4);
obj_corners[0] = cvPoint(0, 0); obj_corners[1] = cvPoint(img_object.cols, 0);
obj_corners[2] = cvPoint(img_object.cols, img_object.rows); obj_corners[3] = cvPoint(0, img_object.rows);
std::vector<Point2f> scene_corners(4);
perspectiveTransform(obj_corners, scene_corners, H);
//-- Draw lines between the corners (the mapped object in the scene - image_2)
line(img_matches, scene_corners[0] + Point2f(img_object.cols, 0), scene_corners[1] + Point2f(img_object.cols, 0), Scalar(0, 255, 0), 4);
line(img_matches, scene_corners[1] + Point2f(img_object.cols, 0), scene_corners[2] + Point2f(img_object.cols, 0), Scalar(0, 255, 0), 4);
line(img_matches, scene_corners[2] + Point2f(img_object.cols, 0), scene_corners[3] + Point2f(img_object.cols, 0), Scalar(0, 255, 0), 4);
line(img_matches, scene_corners[3] + Point2f(img_object.cols, 0), scene_corners[0] + Point2f(img_object.cols, 0), Scalar(0, 255, 0), 4);
//-- Show detected matches
imshow("Good Matches & Object detection", img_matches);
waitKey(0);
return 0;
}
Vielen Dank, ich werde darüber lesen. Das Tutorial, zu dem ich einen Link gepostet habe, hat ein Bild mit den Ergebnissen des Bildvergleichs, und es schien ziemlich gut zu funktionieren, es hat mich dazu gebracht zu denken, dass dies genau das ist, was ich brauche. –
Sie sind willkommen ,. Intern wird der Klassifikator auch Bildfunktionen verwenden, aber es gibt eine Menge Probleme, wie zum Beispiel zukünftige Änderungen. Deshalb müssen Sie einen Datensatz von Logo-Bildern vorbereiten, die unterschiedliche Größen und potenzielle Logos enthalten . Währenddessen kümmert sich der Klassifikator um den Abgleich für Sie. –