我想在同一個窗口中顯示2個,3個或更多圖像。在OpenCV的同一窗口中顯示多個(2,3,4,...)圖像
我的問題是如何把第二個,第三個圖像放在主圖像的右側(上方,左側或上方)。
我想用OpenCV創建類似這樣的東西。
---------------
| | |
| | |
---------------
| | |
| | |
---------------
在此先感謝 豪爾赫
我想在同一個窗口中顯示2個,3個或更多圖像。在OpenCV的同一窗口中顯示多個(2,3,4,...)圖像
我的問題是如何把第二個,第三個圖像放在主圖像的右側(上方,左側或上方)。
我想用OpenCV創建類似這樣的東西。
---------------
| | |
| | |
---------------
| | |
| | |
---------------
在此先感謝 豪爾赫
答案取決於你使用的是(C或C++)的接口。一般工作流程
IplImage*
對於C cv::Mat
)大到足以容納你的合成圖象Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
構造函數來獲得一個cv::Mat
指向您的原始窗口的子圖像,然後使用copyTo
方法將您的小圖像複製到大圖像確定。感謝這個想法。 ROI在OpenCV中非常重要。 – 2011-02-23 16:04:30
圖形用戶界面是相當有限的,如果你需要做複雜的事情,你真的應該使用GUI框架,比如Windows上QT或VC++
我使用MAC。但是現在我只想使用OpenCV框架。我知道將來需要使用外部框架來獲得更多選擇。感謝您的回答。 – 2011-02-23 16:03:03
我最近實現了這個功能。所以想到分享它。 它使用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;
}
以下是輸出示例。
或者只是使用:
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);
很棒的回答。測試和工作非常好。再次感謝。 – 2011-05-16 15:26:19
鏈接斷開。這是一個新的:http://code.opencv.org/projects/opencv/wiki/DisplayManyImages – 2013-10-29 00:21:29
它使用的C API,這是現在真的老派。 – Stefan 2015-10-01 19:09:16