2011-05-30 10 views
6

Matching with nothing in the top right cornerOpenCV 2.2 सर्फ फ़ीचर मिलान समस्याओं

मैं OpenCV डेमो आवेदन "matching_to_many_images.cpp" वेब कैमरा (दाएं) से एक फ्रेम करने के लिए एक छवि (बाएं) क्वेरी करने के लिए संशोधित किया है। पहली छवि के ऊपरी दाएं कोने में क्या गलत हो गया है?

हमें लगता है कि यह हमारे पास एक और समस्या से संबंधित है। हम एक खाली डेटाबेस के साथ शुरू और हम केवल अद्वितीय (विशेषताएं है कि हमारे डेटाबेस में सुविधाओं से मेल नहीं)

हम प्रयोग कर रहे हैं जोड़ने, लेकिन केवल तीन सुविधाओं को जोड़ने के बाद, हम सभी नई सुविधाओं पर एक मैच मिल ....: SurfFeatureDetector सर्फफेचर डिटेक्टर (400,3,4); सर्फडिस्क्रिप्टर एक्स्ट्रेक्टर सर्फडिस्क्रिप्टर एक्स्ट्रेक्टर; FlannBasedMatcher flannDescriptorMatcher;

पूरा कोड पाया जा सकता है पर: http://www.copypastecode.com/71973/

+0

100% सही होने के लिए, यह सही छवि का शीर्ष-बाएं कोने है। हमें इन स्पष्ट रूप से झूठे मैचों, किसी भी विचार से गुजरने का एक तरीका चाहिए? इन बिंदुओं को मैचों के रूप में क्यों पता चला है? – Orka

+0

आपको मेरे उत्तर को सही के रूप में चिह्नित करना चाहिए। वास्तविक एक भ्रामक है। –

उत्तर

10

मैं इस सीमा keypoints के साथ क्या करना है लगता है। डिटेक्टर कुंजीपॉइंट्स का पता लगाता है, लेकिन एसयूआरएफ डिस्क्रिप्टर के लिए लगातार मूल्यों को वापस करने के लिए इसे पिक्सेल डेटा की आवश्यकता होती है, जो इसके चारों ओर पिक्सेल के ब्लॉक में होती है, जो सीमा पिक्सल में उपलब्ध नहीं है। कुंजीपॉइंट्स के बाद सीमा बिंदुओं को हटाने के लिए आप निम्न स्निपेट का उपयोग कर सकते हैं लेकिन वर्णनकर्ताओं की गणना के पहले। मैं 20 या उससे अधिक के सीमा आकार का उपयोग करने का सुझाव देता हूं।

removeBorderKeypoints(vector<cv::KeyPoint>& keypoints, const cv::Size imageSize, const boost::int32_t borderSize) 
{ 
    if(borderSize > 0) 
    { 
     keypoints.erase(remove_if(keypoints.begin(), keypoints.end(), 
           RoiPredicatePic((float)borderSize, (float)borderSize, 
              (float)(imageSize.width - borderSize), 
              (float)(imageSize.height - borderSize))), 
        keypoints.end()); 
    } 
} 

कहाँ RoiPredicatePic के रूप में कार्यान्वित किया जाता है:

struct RoiPredicatePic 
{ 
    RoiPredicatePic(float _minX, float _minY, float _maxX, float _maxY) 
    : minX(_minX), minY(_minY), maxX(_maxX), maxY(_maxY) 
    {} 

    bool operator()(const cv::KeyPoint& keyPt) const 
    { 
     cv::Point2f pt = keyPt.pt; 
     return (pt.x < minX) || (pt.x >= maxX) || (pt.y < minY) || (pt.y >= maxY); 
    } 

    float minX, minY, maxX, maxY; 
}; 

इसके अलावा, लगभग निकटतम पड़ोसी अनुक्रमण सबसे अच्छा तरीका है छवियों के जोड़े के बीच सुविधाओं से मिलान करने के लिए नहीं है। मैं आपको अन्य सरल मैचर्स को आजमाने का सुझाव दूंगा।

+0

साफ, अच्छा बिंदु! हमारे "उत्पादन" कोड में हमने इसके बजाय ब्रूट फोर्स मैचर का उपयोग करने के लिए स्विच किया है। मैं इन बिंदुओं को अपने कोड स्निपेट के साथ गाइड के रूप में सॉर्ट करने में देखूंगा! – Orka

+0

इस समस्या को हल किया गया जो हमने पहले किया था, और सवाल का जवाब दिया।अफसोस की बात यह है कि यह हमारे डेटाबेस-मिलान की समस्याओं का कारण नहीं था .. डीबगिंग के लिए अच्छी तरह से वापस! आपके उत्तर के लिए धन्यवाद! – Maidenone

4

आपका दृष्टिकोण निर्दोष काम कर रहा है लेकिन यह गलत तरीके से ड्रॉमैच फ़ंक्शन को कॉल करने के कारण गलत परिणाम दिखाता है।

drawMatches(image2, image2Keypoints, image1, image1Keypoints, matches, result); 

सही कॉल किया जाना चाहिए::

drawMatches(image1, image1Keypoints, image2, image2Keypoints, matches, result); 
3

मैं एक ही समस्या का सामना करना पड़ा

आपका गलत कॉल कुछ इस तरह था। हैरानी की बात है कि समाधान के पास सीमा बिंदु या केएनएन मैचर के साथ कुछ लेना देना नहीं है। मैचों की बड़ी संख्या से "अच्छे मैचों" को फ़िल्टर करने के लिए बस एक अलग मिलान रणनीति की जरूरत है।

2 एनएन खोज का प्रयोग करें, और निम्न condition-

अगर दूरी (1 मैच) < 0.6 * दूरी (2 मैच) 1 मैच के लिए एक "अच्छा मैच" है।

उपरोक्त स्थिति को पूरा नहीं करते हैं और केवल "अच्छे मैचों" के लिए ड्रॉमैच को कॉल करने वाले सभी मैचों को फ़िल्टर करें। देखा!