wake-up-neo.net

Mehrere (2,3,4,…) Bilder in demselben Fenster in OpenCV anzeigen

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

17

Die Antwort finden Sie im OpenCV-Wiki:

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

:-)

14
Vinzius

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. Composite image made of multiple images

18
vinvinod

Die Antwort hängt von der verwendeten Schnittstelle ab (C oder C++). Allgemeiner Workflow ist

  • Erstellen Sie ein Bild (cv::Mat für C++, IplImage* für C), das groß genug ist, um Ihr zusammengesetztes Bild aufzunehmen
  • Kopieren Sie Ihre Bilder in das große Bild
    • C++: Verwenden Sie den Mat::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 kopieren
    • C: Legen Sie einen ROI im großen Bild fest und kopieren Sie Ihr kleines Bild hinein
  • Zeigen Sie Ihr großes Bild an
7
etarion

Oder 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);
5
Antonín Vrba

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 
0
Allaye