Pregunta

Tengo un conjunto de imágenes y desea hacer una cruz de coincidencia entre todos y mostrar los resultados mediante trackbars usando OpenCV 2.4.6 (ROS Hydro paquete).La parte coincidente se realiza mediante un vector de vectores de vectores de cv::DMatch-objetos:

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

Porque se omite la coincidencia de una imagen con el mismo (sin punto de hacerlo) y debido a una consulta de la imagen puede no coincidir con el resto de cada conjunto de emparejado de tren imágenes para una consulta de la imagen puede tener un tamaño diferente del resto.Tenga en cuenta que la forma en que se implementa la derecha yo en realidad coinciden con un par de imágenes dos veces, que por supuesto no es el óptimo (especialmente dado que he usado un BruteForce comparador con una verificación cruzada de encendido, lo que básicamente significa que me coincida con un par de imágenes 4 veces!) pero por ahora eso es todo.Con el fin de evitar sobre-la-marcha de dibujo de pares de imágenes que me han llenado de un vector de vectores de cv::Mat-objetos.Cada cv::Mat representa la actual imagen de consulta y algunos igualada imagen de un tren (yo rellenar el uso de cv::drawMatches()):

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

Nota:En el ejemplo de arriba cv::Mat[0,3] representa cv::Mat que almacena el producto de cv::drawMatches() la utilización de la imagen[0] y de la imagen[3].

Aquí están las GUI de configuración:

  • Ventana principal:aquí me muestre la imagen de consulta.El uso de una barra de seguimiento - vamos a llamar a TRACK_QUERY - I iterar a través de cada imagen en mi set.
  • Ventana secundaria:aquí puedo visualizar el par (consulta,tren), donde la combinación entre la posición de TRACK_QUERY del regulador y la posición del control deslizante de otro trackbar en esta ventana vamos a llamar TRACK_TRAIN - me permite recorrer todos los cv::Mat-partido-imágenes para la consulta actual de la imagen.

El problema aquí viene del hecho de que cada consulta puede tener un número variable de emparejado de tren imágenes.Mi TRACK_TRAIN debe ser capaz de ajustar el número de igualadas tren imágenes, que es el número de elementos en cada uno de cv::Mat-vector de la consulta actual de la imagen.Lamentablemente hasta ahora no he podido encontrar una manera de hacer eso.El cv::createTrackbar() requiere un recuento de los parámetros, que por lo que veo se establece el límite de la barra de seguimiento del regulador y no ser alteradas posteriormente.¿Me corrija si estoy equivocado, ya que esto es exactamente lo que me molesta.Una posible solución (menos elegante y la participación de diversos mecanismos de control para evitar que se fuera-de-rango de errores) es tomar el tamaño de la más grande serie de pareados de tren de imágenes y el uso como el límite para mi TRACK_TRAIN.Me gustaría evitar hacerlo si es posible.Otra posible solución consiste en la creación de una barra de seguimiento por consulta de la imagen con el valor apropiado de la gama y de intercambiar en mi secundaria ventanas de acuerdo a la consulta seleccionada de la imagen.Por ahora esta parece ser la manera más fácil de ir, pero supone una gran sobrecarga de trackbars por no mencionar el hecho de que yo no he escuchado de OpenCV permite ocultar los controles de GUI.Aquí son dos ejemplo que puede aclarar las cosas un poco más:

Ejemplo 1: En la ventana principal seleccione la imagen 2 con TRACK_QUERY.Para esta imagen me las he arreglado para que coincida con otras 5 imágenes de mi set.Digamos que esos son la imagen 4, 10, 17, 18 y 20.La ventana secundaria se actualiza automáticamente y me muestra la coincidencia entre la imagen 2 e imagen 4 (primero en el subconjunto de emparejado de tren imágenes).TRACK_TRAIN tiene que ir de 0 a 4.Mueve el control deslizante en ambas direcciones me permite ir a través de la imagen 4, 10, 17, 18 y 20 de actualización cada vez que la ventana secundaria.

Ejemplo 2: En la ventana principal seleccione la imagen 7 uso de la TRACK_QUERY.Para esta imagen me las he arreglado para que coincida con 3 otras imágenes de mi set.Digamos que esos son los de la imagen 0, 1, 11 y 19.La ventana secundaria se actualiza automáticamente y me muestra la coincidencia entre la imagen 2 e imagen 0 (primero en el subconjunto de emparejado de tren imágenes).TRACK_TRAIN tiene que ir de 0 a 2.Mueve el control deslizante en ambas direcciones me permite ir a través de la imagen 0, 1, 1 y 19 de la actualización cada vez que la ventana secundaria.

Si usted tiene alguna pregunta no dude en preguntar y yo voy a responder a ellos tan bien como puedo.Gracias de antemano!

PS:Lamentablemente, la forma en que el paquete de ROS se tiene el mínimo de lo que OpenCV puede ofrecer.No Qt integración, no OpenMP, no OpenGL, etc.

¿Fue útil?

Solución

Después de hacer algunas investigaciones más estoy bastante seguro de que esto actualmente no es posible.Por eso he puesto en marcha la primera proposición que me dio en mi pregunta, utilice el partido-vector con el mayor número de partidos en la misma para determinar el tamaño máximo de la barra de seguimiento y, a continuación, utilizar algunos de comprobación para evitar que se fuera-de-rango de excepciones.A continuación hay una más o menos detallada descripción de cómo funciona todo.Desde la coincidencia de procedimiento en mi código implica algunas comprobaciones adicionales que no se refiera al problema en cuestión, voy a omitir aquí.Tenga en cuenta que en un determinado conjunto de imágenes que desea igualar me refiero a una imagen como objeto-imagen cuando la imagen (ejemplo:de la tarjeta) es actualmente asociado a una escena de la imagen (ejemplo:un conjunto de tarjetas) - nivel superior de los partidos-vector (ver más abajo) y es igual a la del índice en processedImages (ver más abajo).Me parece que el tren/consulta de notación en OpenCV, algo confuso.Esta escena/object notation, es tomado de http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html.Usted puede cambiar o intercambiar la notación para su gusto, pero asegúrese de que usted la cambie por todas partes en consecuencia de lo contrario usted puede terminar con unos resultados extraños.

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

La parte difícil es la barra de seguimiento en la segunda ventana responsable de acceso a la coincidencia de imágenes a nuestra imagen seleccionada actualmente en las "Imágenes" de la ventana.Como he explicado más arriba puse el trackbar "los Partidos:" en las "Coincidencias para la imagen actual" de la ventana para tener un rango de 0 a (sceneWithMaxMatches-1).Sin embargo, no todas las imágenes tienen la misma cantidad de partidos con el resto en el conjunto de imágenes (se aplica por diez si usted ha hecho algunos filtros adicionales para garantizar la fiabilidad de los partidos, por ejemplo, mediante la explotación de las propiedades de la homografía, prueba de razón, min/max distancia de verificación, etc.).Porque yo era incapaz de encontrar una manera de ajustar dinámicamente la barra de seguimiento de la gama necesitaba una validación del índice.De lo contrario, para algunas de las imágenes y de sus partidos de la aplicación va a lanzar una gama de excepción.Esto es debido al simple hecho de que para algunos partidos intentamos acceder a un partido de vector con un índice mayor de lo que es del tamaño de menos de 1, ya cv::getTrackbarPos() va todo el camino a (sceneWithMaxMatches - 1).Si la barra de seguimiento de la posición está fuera del intervalo para el vector seleccionado con los partidos, yo simplemente establecer el matchDraw-imagen en "Partidos de imagen actual" a la última en el vector.Aquí tengo que aprovechar el hecho de que la indexación no puede ir por debajo de cero, así como la barra de seguimiento de la posición de modo que no hay necesidad de comprobar esto, pero solo lo que viene después de la posición inicial 0.Si este no es su caso, asegúrese de revisar el límite inferior, y no sólo la parte superior.

Espero que esto ayude!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top