سؤال

لدي مجموعة من الصور وتريد أن تجعل الصليب مطابقة بين جميع وعرض النتائج باستخدام trackbars باستخدام بنسف 2.4.6 (روس هيدرو حزمة).الجزء مطابقة يتم استخدام ناقلات ناقلات ناقلات السيرة الذاتية::DMatch الكائنات:

image[0] --- image[3] -------- image[8] ------ ...
   |             |                 |
   |         cv::DMatch-vect   cv::DMatch-vect
   |
image[1] --- ...
   |
image[2] --- ...
   |
  ...
   |
image[N] --- ...

لأننا حذف مطابقة الصورة مع نفسها (أي نقطة في فعل ذلك) ولأن استعلام صورة قد لا تكون مطابقة مع بقية كل مجموعة من يقابل القطار الصور استعلام صورة قد يكون لها حجم مختلف من بقية.علما أن الطريقة التي نفذت حق أنا فعلا تطابق زوج من الصور مرتين ، والتي بالطبع ليس الأمثل (وخاصة منذ كنت BruteForce المنظر مع التحقق من تشغيل ، وهو ما يعني أساسا أن لا تطابق زوج من الصور 4 مرات!) ولكن الآن هذا هو.من أجل تجنب على ذبابة الرسم من مطابقة أزواج من الصور لدي بالسكان ناقلات ناقلات السيرة الذاتية::حصيرة الكائنات.كل السيرة الذاتية::حصيرة يمثل الاستعلام الحالي صورة بعض يقابل صورة القطار (أنا أتساءل السيرة الذاتية::drawMatches()):

image[0] --- cv::Mat[0,3] ---- cv::Mat[0,8] ---- ...
   |
image[1] --- ...
   |
image[2] --- ...
   |
  ...
   |
image[N] --- ...

ملاحظة:في المثال أعلاه السيرة الذاتية::حصيرة[0,3] تقف على السيرة الذاتية::حصيرة الذي يخزن المنتج من السيرة الذاتية::drawMatches() باستخدام صورة[0] صورة[3].

هنا هي واجهة الإعدادات:

  • النافذة الرئيسية:أنا هنا عرض الاستعلام الحالي صورة.باستخدام trackbar - دعنا نسميها TRACK_QUERY - أنا من خلال تكرار كل صورة في مجموعة بي.
  • الثانوية النافذة:أنا هنا عرض زوج متطابق (الاستعلام القطار) ، حيث الجمع بين موقف TRACK_QUERY المنزلق و موقف المنزلق آخر trackbar في هذا الإطار - دعنا نسميها TRACK_TRAIN - يسمح لي تكرار خلال كافة السيرة الذاتية::حصيرة-مباراة-صور الاستعلام الحالي صورة.

القضية هنا يأتي من حقيقة أن كل استعلام يمكن أن يكون عدد متغير من مطابقة القطار الصور.بلدي TRACK_TRAIN ينبغي أن تكون قادرة على ضبط عدد من يقابل القطار الصور ، وهذا هو عدد العناصر في كل السيرة الذاتية::حصيرة-ناقلات الحالي الاستعلام الصورة.للأسف حتى الآن لم أتمكن من العثور على طريقة للقيام بذلك.السيرة الذاتية::createTrackbar() يتطلب الاعتماد-المعلمة التي ما أرى يحدد الحد من trackbar المنزلق ، لا يمكن تغييرها في وقت لاحق.صحح لي إذا كنت مخطئا لأن هذا هو بالضبط ما يزعجني.حل ممكن (أقل أناقة و التي تنطوي على العديد من الشيكات إلى تجنب الخروج من النطاق erros) هو أن تأخذ حجم أكبر مجموعة من يقابل القطار الصور و استخدامه بمثابة تحد بالنسبة لي TRACK_TRAIN.وأود أن تجنب القيام بذلك إذا كان ذلك ممكنا.حل آخر ممكن ينطوي على خلق trackbar في الاستعلام صورة مع القيمة المناسبة مجموعة مبادلة كل في الثانوية windows وفقا اختيار الاستعلام الصورة.الآن هذا يبدو أن يكون أكثر سهولة طريقة للذهاب ولكن يشكل كبير في النفقات العامة من trackbars ناهيك عن أن حقيقة لم أسمع من بنسف مما يسمح لك لإخفاء عناصر تحكم واجهة المستخدم الرسومية.هنا نوعان من الأمثلة التي يمكن توضيح الأمور أكثر قليلا:

مثال 1: في النافذة الرئيسية تحديد صورة 2 باستخدام TRACK_QUERY.هذه الصورة لقد تمكنت من المباراة 5 صور أخرى من مجموعة بي.دعونا نقول تلك هي صورة 4, 10, 17, 18 و 20.الثانوية نافذة التحديثات تلقائيا ويظهر لي المباراة بين صورة 2 صورة 4 (الأولى في فرعية من مطابقة القطار الصور).TRACK_TRAIN أن يذهب من 0 إلى 4.تحريك المنزلق في كلا الاتجاهين يسمح لي أن تذهب من خلال صورة 4, 10, 17, 18 و 20 تحديث في كل مرة الثانوي النافذة.

مثال 2: في النافذة الرئيسية تحديد صورة 7 باستخدام TRACK_QUERY.هذه الصورة لقد تمكنت من المباراة 3 صور أخرى من مجموعة بي.دعونا نقول تلك هي صورة 0, 1, 11 و 19.الثانوية نافذة التحديثات تلقائيا ويظهر لي المباراة بين صورة 2 صورة 0 (الأولى في فرعية من مطابقة القطار الصور).TRACK_TRAIN أن يذهب من 0 إلى 2.تحريك المنزلق في كلا الاتجاهين يسمح لي أن تذهب من خلال صورة 0, 1, 1 و 19 تحديث في كل مرة الثانوي النافذة.

إذا كان لديك أي أسئلة لا تتردد في السؤال و سوف الإجابة عليها بقدر ما أستطيع.شكرا مقدما!

PS:للأسف الطريقة روس حزمة لديها الحد الأدنى من ما بنسف يمكن أن تقدم.لا Qt التكامل لا OpenMP لا OpenGL.... الخ

هل كانت مفيدة؟

المحلول

بعد إجراء المزيد من البحوث أنا متأكد من أن هذا هو حاليا غير ممكن.هذا هو السبب في أنني نفذت الطرح الأول الذي أعطى في سؤالي - استخدام المباراة ناقلات مع أكبر عدد من المباريات في ذلك تحديد الحد الأقصى لحجم trackbar ثم استخدام بعض التدقيق لتجنب الخروج من نطاق الاستثناءات.أدناه هناك أكثر أو أقل وصف مفصل كيف يعمل كل شيء.منذ مطابقة الإجراء في قانون بلدي ينطوي على بعض الفحوصات الإضافية التي لا تتعلق المشكلة في متناول اليد ، أنا سوف تخطي هنا.علما أنه في مجموعة معينة من الصور نريد أن المباراة أود أن أشير إلى صورة وجوه-الصورة عند تلك الصورة (على سبيل المثال:بطاقة) حاليا مطابقة المشهد-الصورة (على سبيل المثال:مجموعة من البطاقات) - أعلى مستوى من المباريات-ناقلات (انظر أدناه) يساوي المؤشر في processedImages (انظر أدناه).أجد القطار/الاستعلام التدوين في بنسف مربكا بعض الشيء.هذا المشهد/تدوين كائن من http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html.يمكنك تغيير أو تبديل التدوين ترضيك ولكن تأكد من تغييره في كل مكان لذلك وإلا قد ينتهي بك الأمر مع بعض نتائج غريبة.

// stores all the images that we want to cross-match
std::vector<cv::Mat> processedImages;
// stores keypoints for each image in processedImages
std::vector<std::vector<cv::Keypoint> > keypoints;
// stores descriptors for each image in processedImages 
std::vector<cv::Mat> descriptors;

// fill processedImages here (read images from files, convert to grayscale, undistort, resize etc.), extract keypoints, compute descriptors
// ...

// I use brute force matching since I also used ORB, which has binary descriptors and HAMMING_NORM is the way to go
cv::BFmatcher matcher;
// matches contains the match-vectors for each image matched to all other images in our set
// top level index matches.at(X) is equal to the image index in processedImages
// middle level index matches.at(X).at(Y) gives the match-vector for the Xth image and some other Yth from the set that is successfully matched to X
std::vector<std::vector<std::vector<cv::DMatch> > > matches;
// contains images that store visually all matched pairs
std::vector<std::vector<cv::Mat> > matchesDraw;

// fill all the vectors above with data here, don't forget about matchesDraw
// stores the highest count of matches for all pairs - I used simple exclusion by simply comparing the size() of the current std::vector<cv::DMatch> vector with the previous value of this variable
long int sceneWithMaxMatches = 0;
// ...

// after all is ready do some additional checking here in order to make sure the data is usable in our GUI. A trackbar for example requires AT LEAST 2 for its range since a range (0;0) doesn't make any sense
if(sceneWithMaxMatches < 2)
  return -1;

// in this window show the image gallery (scene-images); the user can scroll through all image using a trackbar
cv::namedWindow("Images", CV_GUI_EXPANDED | CV_WINDOW_AUTOSIZE);
// just a dummy to store the state of the trackbar 
int imagesTrackbarState = 0;
// create the first trackbar that the user uses to scroll through the scene-images
// IMPORTANT: use processedImages.size() - 1 since indexing in vectors is the same as in arrays - it starts from 0 and not reducing it by 1 will throw an out-of-range exception
cv::createTrackbar("Images:", "Images", &imagesTrackbarState, processedImages.size() - 1, on_imagesTrackbarCallback, NULL);
// in this window we show the matched object-images relative to the selected image in the "Images" window
cv::namedWindow("Matches for current image", CV_WINDOW_AUTOSIZE);
// yet another dummy to store the state of the trackbar in this new window
int imageMatchesTrackbarState = 0;
// IMPORTANT: again since sceneWithMaxMatches stores the SIZE of a vector we need to reduce it by 1 in order to be able to use it for the indexing later on
cv::createTrackbar("Matches:", "Matches for current image", &imageMatchesTrackbarState, sceneWithMaxMatches - 1, on_imageMatchesTrackbarCallback, NULL);

while(true)
{
  char key = cv::waitKey(20);
  if(key == 27)
    break;

  // from here on the magic begins
  // show the image gallery; use the position of the "Images:" trackbar to call the image at that position
  cv::imshow("Images", processedImages.at(cv::getTrackbarPos("Images:", "Images")));

  // store the index of the current scene-image by calling the position of the trackbar in the "Images:" window
  int currentSceneIndex = cv::getTrackbarPos("Images:", "Images");
  // we have to make sure that the match of the currently selected scene-image actually has something in it
  if(matches.at(currentSceneIndex).size())
  {
    // store the index of the current object-image that we have matched to the current scene-image in the "Images:" window
    int currentObjectIndex = cv::getTrackbarPos("Matches:", "Matches for current image");
    cv::imshow(
            "Matches for current image",
            matchesDraw.at(currentSceneIndex).at(currentObjectIndex < matchesDraw.at(currentSceneIndex).size() ? // is the current object index within the range of the matches for the current object and current scene
            currentObjectIndex : // yes, return the correct index
            matchesDraw.at(currentSceneIndex).size() - 1));  // if outside the range show the last matched pair!
  }
}

// do something else
// ...

الجزء صعبة هو trackbar في النافذة الثانية المسؤولة عن الوصول إلى مطابقة الصور لدينا حاليا الصورة المختارة في "الصور" نافذة.كما شرحت أعلاه أنا وضعت trackbar "المباريات:" في "مباريات الصورة الحالية" نافذة على مجموعة من 0 إلى (sceneWithMaxMatches-1).ومع ذلك ليست كل الصور من نفس عدد المباريات مع بقية في صورة مجموعة (ينطبق عشرة أضعاف إذا كنت قد فعلت بعض تصفية إضافية لضمان موثوقية مباريات على سبيل المثال من خلال استغلال خصائص homography ، ونسبة اختبار مين/ماكس المسافة الاختيار.... الخ).لأنني كنت غير قادر على العثور على طريقة ضبط حيوي trackbar مجموعة أنا في حاجة إلى التحقق من مؤشر.وإلا بعض الصور مبارياته التطبيق سوف رمي خارج نطاق استثناء.هذا ويرجع ذلك إلى حقيقة بسيطة وهي أن بعض المباريات ونحن نحاول الوصول إلى المباراة ناقلات مع فهرس أكبر من حجمه ناقص 1 لأن السيرة الذاتية::getTrackbarPos() يذهب كل في طريقة إلى (sceneWithMaxMatches - 1).إذا كان trackbar موقف يخرج من النطاق المحدد حاليا ناقلات مع المباريات, أنا ببساطة تعيين matchDraw-الصورة في "مباريات الصورة الحالية" إلى آخر في ناقلات.أنا هنا من استغلال حقيقة أن الفهرسة لا يمكن أن تذهب تحت الصفر وكذلك trackbar موقف حتى لا يكون هناك لا تحتاج إلى التحقق من هذا ولكن فقط ما يأتي بعد الموقف المبدئي 0.إذا كان هذا ليس هو الحال الخاص بك تأكد من تحقق الحد الأدنى أيضا وليس فقط الجزء العلوي.

ويساعد هذا الأمل!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top