2011-02-23 100 views

回答

14

你可以找到OpenCV的維基答案:

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

:-)

+0

很棒的回答。測試和工作非常好。再次感謝。 – 2011-05-16 15:26:19

+3

鏈接斷開。這是一個新的:http://code.opencv.org/projects/opencv/wiki/DisplayManyImages – 2013-10-29 00:21:29

+1

它使用的C API,這是現在真的老派。 – Stefan 2015-10-01 19:09:16

7

答案取決於你使用的是(C或C++)的接口。一般工作流程

  • (對於C++,IplImage*對於C cv::Mat)大到足以容納你的合成圖象
  • 您的圖像複製到大圖像
    • C++創建的圖像:使用Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)構造函數來獲得一個cv::Mat指向您的原始窗口的子圖像,然後使用copyTo方法將您的小圖像複製到大圖像
    • C:在大圖像中設置ROI並將您的小圖像複製到其中
  • 顯示你的大圖像包含的OpenCV
+0

確定。感謝這個想法。 ROI在OpenCV中非常重要。 – 2011-02-23 16:04:30

-2

圖形用戶界面是相當有限的,如果你需要做複雜的事情,你真的應該使用GUI框架,比如Windows上QT或VC++

+0

我使用MAC。但是現在我只想使用OpenCV框架。我知道將來需要使用外部框架來獲得更多選擇。感謝您的回答。 – 2011-02-23 16:03:03

17

我最近實現了這個功能。所以想到分享它。 它使用C++ API。代碼是不言自明的(希望)。

/** 
    * @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; 
    } 

以下是輸出示例。 Composite image made of multiple images

+0

我們如何改變它來顯示灰度圖像?因爲我試過了,它只適用於彩色圖像。 – Maystro 2015-01-14 15:59:00

+1

@Maystro:我修改了代碼以支持灰度和彩色圖像。 – vinvinod 2015-02-19 10:57:31

+1

這是我猜的最佳解決方案。無論如何,我不得不修改它,因爲你忘了在彩色圖像的情況下將vecMat [k]數據複製到target_ROI Mat中。 – 2015-12-13 09:45:00

5

或者只是使用:

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

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

墊DST - > | a | b |

或矢量做到這一點:

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