2011-02-23 25 views

Respuesta

14

usted puede encontrar la respuesta en el OpenCV Wiki:

https://github.com/opencv/opencv/wiki/DisplayManyImages

:-)

+0

Gran respuesta. Probado y funciona muy bien. Gracias en otro momento. –

+3

Enlace roto. Aquí hay uno nuevo: http://code.opencv.org/projects/opencv/wiki/DisplayManyImages –

+1

Está usando la API C, que actualmente es realmente vieja. – Stefan

7

La respuesta depende de qué interfaz que está utilizando (C o C++). Flujo de trabajo general es

  • crear una imagen (cv::Mat para C++, IplImage* para C) lo suficientemente grande como para acomodar su imagen compuesta
  • Copie sus imágenes en la imagen grande
    • C++: Utilice el constructor Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange) llegar a cv::Mat apuntando a una subimagen de su ventana original, luego use el método copyTo para copiar su imagen pequeña en la grande
    • C: establezca un ROI en la imagen grande y copie su imagen pequeña en él
  • Mostrar su imagen grande
+0

Ok. Gracias por la idea El ROI es muy importante en OpenCV. –

-2

La interfaz gráfica de usuario incluido con OpenCV es bastante limitada, si es que tiene que hacer nada complicado, que realmente debe utilizar un marco GUI tales como QT o VC++ en ventanas

+0

Trabajo con MAC. Pero ahora solo quiero trabajar con el framework OpenCV. Sé que en el futuro necesitaré usar un marco externo para tener más opciones. Gracias por tu respuesta. –

17

Implementé esto muy recientemente. Así que pensé en compartirlo. Utiliza la API C++. El código es autoexplicativo (con suerte).

/** 
    * @brief makeCanvas Makes composite image from the given images 
    * @param vecMat Vector of Images. 
    * @param windowHeight The height of the new composite image to be formed. 
    * @param nRows Number of rows of images. (Number of columns will be calculated 
    *    depending on the value of total number of images). 
    * @return new composite image. 
    */ 
    cv::Mat makeCanvas(std::vector<cv::Mat>& vecMat, int windowHeight, int nRows) { 
      int N = vecMat.size(); 
      nRows = nRows > N ? N : nRows; 
      int edgeThickness = 10; 
      int imagesPerRow = ceil(double(N)/nRows); 
      int resizeHeight = floor(2.0 * ((floor(double(windowHeight - edgeThickness)/nRows))/2.0)) - edgeThickness; 
      int maxRowLength = 0; 

      std::vector<int> resizeWidth; 
      for (int i = 0; i < N;) { 
        int thisRowLen = 0; 
        for (int k = 0; k < imagesPerRow; k++) { 
          double aspectRatio = double(vecMat[i].cols)/vecMat[i].rows; 
          int temp = int(ceil(resizeHeight * aspectRatio)); 
          resizeWidth.push_back(temp); 
          thisRowLen += temp; 
          if (++i == N) break; 
        } 
        if ((thisRowLen + edgeThickness * (imagesPerRow + 1)) > maxRowLength) { 
          maxRowLength = thisRowLen + edgeThickness * (imagesPerRow + 1); 
        } 
      } 
      int windowWidth = maxRowLength; 
      cv::Mat canvasImage(windowHeight, windowWidth, CV_8UC3, Scalar(0, 0, 0)); 

      for (int k = 0, i = 0; i < nRows; i++) { 
        int y = i * resizeHeight + (i + 1) * edgeThickness; 
        int x_end = edgeThickness; 
        for (int j = 0; j < imagesPerRow && k < N; k++, j++) { 
          int x = x_end; 
          cv::Rect roi(x, y, resizeWidth[k], resizeHeight); 
          cv::Size s = canvasImage(roi).size(); 
          // change the number of channels to three 
          cv::Mat target_ROI(s, CV_8UC3); 
          if (vecMat[k].channels() != canvasImage.channels()) { 
           if (vecMat[k].channels() == 1) { 
            cv::cvtColor(vecMat[k], target_ROI, CV_GRAY2BGR); 
           } 
          } else {    
           vecMat[k].copyTo(target_ROI); 
          } 
          cv::resize(target_ROI, target_ROI, s); 
          if (target_ROI.type() != canvasImage.type()) { 
           target_ROI.convertTo(target_ROI, canvasImage.type()); 
          } 
          target_ROI.copyTo(canvasImage(roi)); 
          x_end += resizeWidth[k] + edgeThickness; 
        } 
      } 
      return canvasImage; 
    } 

Aquí es resultado de ejemplo. Composite image made of multiple images

+0

¿cómo podemos cambiarla para mostrar imágenes en escala de grises? porque lo intenté y funciona solo para imágenes en color. – Maystro

+1

@Maystro: He modificado el código para admitir imágenes en escala de grises y en color. – vinvinod

+1

Esta es la mejor solución, supongo. De todos modos, tuve que modificarlo un poco porque olvidó copiar los datos de vecMat [k] en target_ROI Mat en caso de imágenes en color. –

5

o simplemente utilizar:

Mat a, Mat b, Mat dst // a,b loaded 

cv::hconcat(a, b, dst) // horizontal 
cv::vconcat(a, b, dst) // vertical 

DST Mat -> | a | b |

o lo hacen con vectores:

std::vector<cv::Mat> matrices = { 
      a, b 
    }; 
hconcat(matrices, dst); 
Cuestiones relacionadas