Ich möchte 2, 3 oder mehr Bilder im selben Fenster anzeigen.
Mein Problem ist, wie ich das zweite, dritte Bild auf der rechten Seite (über, links oder oben) des Hauptbildes platzieren kann.
Ich möchte etwas mit OpenCV erstellen.
---------------
| | |
| | |
---------------
| | |
| | |
---------------
Vielen Dank im Voraus Jorge
Ich habe dies vor kurzem umgesetzt. Also haben Sie daran gedacht, es weiterzugeben. Es verwendet die C++ - API. Der Code ist (hoffentlich) selbsterklärend.
/**
* @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;
}
Hier ist eine Beispielausgabe.
Die Antwort hängt von der verwendeten Schnittstelle ab (C oder C++). Allgemeiner Workflow ist
cv::Mat
für C++, IplImage*
für C), das groß genug ist, um Ihr zusammengesetztes Bild aufzunehmenMat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
-Konstruktor, um einen cv::Mat
zu erhalten, der auf ein Teilbild Ihres ursprünglichen Fensters zeigt, und anschließend die copyTo
-Methode, um Ihr kleines Bild in das große zu kopierenOder benutzen Sie einfach:
Mat a, Mat b, Mat dst // a,b loaded
cv::hconcat(a, b, dst) // horizontal
cv::vconcat(a, b, dst) // vertical
Mat dst -> | a | b |
oder mache es mit vector:
std::vector<cv::Mat> matrices = {
a, b
};
hconcat(matrices, dst);
Versuchen Sie diesen Code (siehe meine Kommentare):
Mat img = imread("lena.JPG");
CV::Mat chann[3], all; // creating
split(img, chann); // split an image into their color channel and n keep them inside
a 3 element array called chann
imshow("ppl", img);
hconcat(chann, 3, all); // joining the images together in a horizontal manner, the
array, number of array, and the destination
imshow("B :: G :: R",all); // this just the little help i could provide