2016-06-25 14 views
0

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. enter image description here 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; 
} 

Antwort

0

Ich würde vorschlagen, dass Sie Cascade Classification verwenden, wenn Sie nur darum, herauszufinden, egal, ob es ein Logo ist oder nicht. Die Anpassung an Objektfunktionen reicht nicht aus, um das zu erreichen, was Sie wollen.

Sie müssen positive Bilder sammeln - für Logos - und andere Bilder, die kein Logo enthalten, und lassen Sie den Klassifizierer die Arbeit für Sie erledigen. Natürlich können Sie über den Kaskadenklassifikator lesen, um mehr zu verstehen, wie es funktioniert;)

+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. –

+0

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. –