/** * @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, cvScalar(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); } } 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; }
static 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.at(i).cols) / vecMat.at(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; Rect roi(x, y, resizeWidth.at(k), resizeHeight); cv::Mat target_ROI = canvasImage(roi); resize(vecMat.at(k), target_ROI, target_ROI.size()); x_end += resizeWidth.at(k) + edgeThickness; } } return canvasImage; }