문제

I 일련의 이미지가 있고 OpenCV 2.4.6 (ROS Hydro Package)을 사용하여 트랙 바를 사용하여 결과를 모두 표시하고 결과를 표시하고 싶습니다. 일치하는 부분은 CV :: Dmatch-객체의 벡터 벡터의 벡터 벡터를 사용하여 수행됩니다.

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

자체가있는 이미지와 일치하는 것을 생략하고 쿼리 이미지가 모든 나머지와 일치하지 않을 수 있으므로 쿼리 이미지에 대한 일치하는 트레인 이미지 세트는 나머지와 다른 크기를 가질 수 있습니다. 옳은 방식은 실제로 이미지 한 쌍을 두 번 일치시킵니다. 물론 최적이 아닌 (특히 내가 교차 수표가 켜져있는 Bruteforce Matcher를 사용한 이후로 Bruteforce Matcher를 사용한 것으로, 기본적으로 4 번의 이미지와 일치하는 것을 의미합니다! ) 그러나 지금은 그것이 지금입니다. 일치하는 이미지의 일치하는 쌍의 플라이 드로잉을 피하기 위해 CV :: Mat-Objects의 벡터 벡터의 벡터를 채웠습니다. 각 CV :: 매트는 현재 쿼리 이미지와 일부 일치 트레인 이미지를 나타냅니다 (CV :: DrawMatches ()을 사용하여이를 채우십시오) :

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

참고 : CV :: MAT 위의 예에서는 CV :: DrawMatches () 이미지를 사용하여 CV :: DrawMatches ()의 제품을 저장합니다 [0] 및 이미지 [ 3].

다음은 GUI 설정입니다.

  • 기본 창 : 여기에서는 현재 쿼리 이미지를 표시합니다. 트랙바를 사용하여 IT Track_Query를 호출하자 - 내 세트의 각 이미지를 반복합니다.
  • 2 차 창 : track_query의 슬라이더의 위치 와이 창에서 다른 트랙 바의 슬라이더의 위치 간의 조합이있는 일치 된 쌍 (쿼리, 기차)을 표시합니다. Track_train을 호출 해 봅시다. 현재 쿼리 이미지의 모든 CV :: Mat-Match-Images.

여기서이 문제는 각 쿼리가 일치하는 열차 이미지의 가변 수를 가질 수 있다는 사실에서 비롯됩니다. 내 TRACK_TRAIN은 현재 쿼리 이미지의 각 CV :: 매트 픽스에있는 요소 수입니다 (이는 일치하는 기차 이미지의 수를 조정할 수 있어야합니다. 슬프게도 지금까지 나는 그것을 할 수있는 방법을 찾을 수 없었습니다. CV :: CreateTrackBar ()는 Count-Parameter가 필요합니다.이 표시된 것은 트랙 바의 슬라이더의 한계를 설정하고 을 나중에 변경할 수 없습니다. 이것이 정확히 나를 괴롭히는 일이므로 틀렸다면 내가 틀렸다면 나를 바로 잡아라. 가능한 솔루션 (덜 우아하고 레인지 오류를 피하기위한 다양한 검사가 적어 짐)은 일치하는 열차 이미지의 가장 큰 세트의 크기를 가져 와서 TRACK_TRAIN의 한계로 사용하는 것입니다. 가능한 경우 그렇게하지 않으려고합니다. 또 다른 가능한 솔루션은 선택한 쿼리 이미지에 따라 적절한 값 범위를 사용하여 쿼리 이미지 당 트랙바를 작성하고 각 쿼리 이미지에 따라 각 보조 창에서 스왑합니다. 지금은 이것이 더 쉬운 방법 인 것 같지만 Trackbars의 큰 오버 헤드가있는 것처럼 보입니다. OpenCV에서 GUI 컨트롤을 숨길 수있게 해줍니다. 다음은 일을 조금 더 명확히 할 수있는 두 가지 예입니다.

예제 1 : 메인 윈도우에서 track_query를 사용하여 이미지 2를 선택합니다. 이 이미지의 경우 i 세트에서 5 개의 다른 이미지와 일치하도록 관리했습니다. 그것들은 이미지 4, 10, 17, 18 및 20입니다. 보조 창이 자동으로 업데이트되고 이미지 2와 이미지 4 사이의 일치를 보여줍니다 (일치하는 열차 이미지의 하위 집합에서 먼저). TRACK_TRAIN은 0에서 4까지 가야합니다. 두 방향으로 슬라이더를 움직여야합니다. 2 차 창에서 매번 이미지 4, 10, 17, 18 및 20을 갱신 할 수 있습니다.

예제 2 : 기본 창에서는 track_query를 사용하여 이미지 7을 선택합니다. 이 이미지의 경우 3 개의 다른 이미지와 일치 할 수있었습니다. 그것들은 image 0, 1, 11 및 19입니다. 보조 창이 자동으로 업데이트되고 이미지 2와 이미지 0 (첫 번째 일치 열차 이미지의 하위 집합) 사이의 일치를 보여줍니다. TRACK_TRAIN은 0에서 2까지 이동해야합니다. 두 방향으로 슬라이더를 이동하면 보조 창이 매번 이미지 0, 1, 1 및 19를 업데이트 할 수 있습니다.

질문이 있으시면 언제든지 묻고 싶습니다.뿐만 아니라 대답 할 것입니다. 미리 감사드립니다!

추신 : 슬프게도 ROS 패키지가 가장 최소한의 opencv가 제공 할 수있는 방법입니다. Qt 통합, OpenMP 없음, OpenGL이 없음.

도움이 되었습니까?

해결책

더 많은 연구를 수행 한 후에 나는 현재이 제품이 불가능하다고 확신합니다. 그래서 제가 제가 제가 준 첫 번째 명제를 구현 한 이유입니다. 일치 벡터가 가장 많은 일치를 사용하여 트랙 바의 최대 크기를 결정한 다음 범위가 아닌 예외를 피하기 위해 몇 가지 확인을 사용하십시오. 아래에서는 어떻게 작동하는지 더 많거나 자세한 설명이 있습니다. 내 코드의 일치 절차는 문제가 해결되지 않는 추가 수표가 필요하기 때문에 여기에서 건너 뛸 것입니다. 주어진 이미지 세트에서 일치시키려는 이미지 (예 : 카드)가 현재 장면 이미지 (예 : 카드 세트)와 일치하는 경우 이미지를 객체 이미지로 참조합니다 (예 : 카드 세트) - 최상위 레벨 매치 벡터 (아래 참조)와 processImages의 인덱스와 동일합니다 (아래 참조). OpenCV에서 열차 / 쿼리 표기법을 찾습니다. 이 장면 / 개체 표기법은 http://docs.opencv.org에서 가져온 것입니다. / adoc/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
// ...
.

까다로운 부분은 "이미지"창에서 현재 선택된 이미지에 일치하는 이미지에 액세스하는 두 번째 창의 트랙 바입니다. 위에서 설명한 것처럼 "현재 이미지의 일치 항목"창에서 트랙 바 "일치 항목"창에서 "ScenewithMaxMatches-1)에서 범위를 갖습니다. 그러나 모든 이미지가 이미지 세트의 나머지 부분과 동일한 양의 일치하는 양 (예를 들어 homography, 비율 테스트, 최소 거리 확인 등의 속성을 활용하여 신뢰할 수있는 일치를 보장하는 추가 필터링을 수행 한 경우 10 배로 적용) .). 트랙 바의 범위를 동적으로 조정할 수있는 방법을 찾을 수 없었기 때문에 색인의 유효성 검사가 필요했습니다. 그렇지 않으면 일부 이미지와 일치 항목의 경우 응용 프로그램이 범위가 아닌 예외를 던졌습니다. 이는 CV :: GetTrackBarpos ()가 (ScenewithMaxMatches - 1)가되기 때문에 CV :: GetTrackBarpos ()가이기 때문에 일부 일치 항목이 일치하는 일치 항목을 사용하여 일치 벡터보다 큰 색인으로 액세스하려고합니다. 트랙 바의 위치가 현재 선택된 벡터가 일치하는 것의 범위를 벗어나는 경우, "현재 이미지에 대한 일치"에서 벡터의 마지막으로 벡터에서 matchDraw 이미지를 설정합니다. 여기에서 인덱싱이 트랙 바 위치뿐만 아니라 트랙 바 위치뿐만 아니라이를 확인할 필요가 없지만 초기 위치 0 이후에 오는 것이 필요하지 않지만이 문제가 아닌 경우 하단을 확인하십시오. 뿐만 아니라 어퍼뿐만 아니라

이 도움이되기를 바랍니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top