昊虹君 发表于 2022-11-6 19:18

OpenCV下实现单窗口显示多幅图像(C++源码)

OpenCV下实现单窗口显示多幅图像(C++源码)

有时我们要在一个窗口中显示多幅图像,以利于我们对比结果。

为了实现这个效果中,在OpenCV中,我们可以在一幅白色背景大图上把各幅图像绘制上去,这其中关键是要计算出各幅图绘制在大图中的哪个区域,并对图像按显示区大小进行相应的缩放处理。

下面的代码可实现在同一窗口中不超过12幅图像的显示,图像比例没有要求。

代码会将每幅图像的宽和高限制在300、200、150三个像素值上,并且保持原图比例,宽和高哪个数值更大,就将哪个的像素值设为300、200、150。
具体来评:
当图像数量为1至4幅时,宽和高限制在300像素;
当图像数量为5至8幅时,宽和高限制在200像素;
当图像数量为9至12幅时,宽和高限制在150像素;

举个例子来说,当图像的宽和高被限制在300像素时,若一幅图像的宽为300像素,高为600像素,则显示到单窗口图像中时,该幅图像会被缩放到宽为100,高为300的图像。

代码如下:
代码中用到的图像百度网盘下载链接:https://pan.baidu.com/s/1NuIpi61-8e9EzPnyFeIvqA?pwd=ezry

//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术

//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询

//OpenCV版本 OpenCV3.0

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;


/*******************同时显示多张图片*************************
*_winName 为显示窗口的名字字符串;
*_img 为要显示的图片的集合;
*最多同时显示12张图片
*************************************************************/
void imshowMulti(const std::string& _winName, const std::vector<Mat>& _imgs)
{
        int nImg = (int)_imgs.size();

        Mat dispImg;
        int size;
        int x, y;
        // w - Maximum number of images in a row
        // h - Maximum number of images in a column
        int w, h;
        // scale - How much we have to resize the image
        float scale;
        int max;
        if (nImg <= 0)
        {
                printf("Number of arguments too small....\n");
                return;
        }
        else if (nImg > 12)
        {
                printf("Number of arguments too large....\n");
                return;
        }

        switch (nImg)
        {
        case 1:
                w = h = 1;
                size = 300;
                break;
        case 2:
                w = 2; h = 1;
                size = 300;
                break;
        case 3:
        case 4:
                w = 2; h = 2;
                size = 300;
                break;
        case 5:
        case 6:
                w = 3; h = 2;
                size = 200;
                break;
        case 7:
        case 8:
                w = 4; h = 2;
                size = 200;
                break;
        default:
                w = 4; h = 3;
                size = 150;
                break;
        }
        dispImg.create(Size(100 + size*w, 60 + size*h), CV_8UC3);
        for (int i = 0, m = 20, n = 20; i<nImg; i++, m += (20 + size))//m和n是绘图的超始点
        {
                x = _imgs.cols;
                y = _imgs.rows;
                max = (x > y) ? x : y;
                scale = (float)((float)max / size);
                if (i%w == 0 && m != 20)
                {
                        m = 20;
                        n += 20 + size;
                }
                Mat imgROI = dispImg(Rect(m, n, (int)(x / scale), (int)(y / scale)));
                resize(_imgs, imgROI, Size((int)(x / scale), (int)(y / scale)));
        }
        namedWindow(_winName);
        imshow(_winName, dispImg);
}

void main()
{
        vector<Mat> img;
        Mat img1 = imread("F:/material/images/flower/01-200_400.jpg");
        Mat img2 = imread("F:/material/images/flower/02-300_300.jpg");
        Mat img3 = imread("F:/material/images/flower/03-360_360.jpg");
        img.push_back(img1);
        img.push_back(img2);
        img.push_back(img3);

        imshowMulti("result", img);

        waitKey(0);

}

运行结果如下:
http://pic1.hhai.cc/pic1/2022/2022-11/001/003.png
页: [1]
查看完整版本: OpenCV下实现单窗口显示多幅图像(C++源码)