Show multiple (2,3,4,…) images in the same window in OpenCV

后端 未结 6 1871
臣服心动
臣服心动 2020-12-13 07:11

I want to show 2, 3 or more images in the same window.

My problem is how to put the second, third image just on the right side (above, left or upper) the main image.

6条回答
  •  余生分开走
    2020-12-13 07:52

    I implemented this very recently. So thought of sharing it. It uses C++ API. The code is self-explanatory (hopefully).

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

    Here is sample output. Composite image made of multiple images

提交回复
热议问题