zoukankan      html  css  js  c++  java
  • [OpenCV笔记]0.OpenCV中显示多张图像

    摘要

    本文主要介绍OpenCV中同时显示多张IplImage图像的方法(C++形式的多图显示需要修改,用vector<Mat>可能比较方便),有点类似MATLAB中的subplot,只是暂时还没有subplot那么完善,这种方法主要思想和用到的技术为:

    • 主要思想:将多张小图组合成一张大图来显示
    • 组合方式:按照图片的数量,将大图分割成特定的行列数,每一个小块放一张子图
    • 输入方式:使用 中的 type va_list ,就可定义形参数目不确定的函数了。

    1. va_list

    • va_start Initialize a variable argument list (macro ) 初始化可变参数列
    • va_arg Retrieve next argument (macro ) 读取下一个参数
    • va_end End using variable argument list (macro ) 结束可变参数列的使用

      下面是va_list的一个应用例子:
    void PrintFloats (int n, ...)
    {
      int i;
      double val;
      printf ("Printing floats:");
      va_list vl;
      va_start(vl,n);
      for (i=0;i<n;i++)
      {
        val=va_arg(vl,double);
        printf (" [%.2f]",val);
      }
      va_end(vl);
      printf ("
    ");
    }

    2. cvShowMultiImages

    程序需要的头文件:

    #include <stdio.h>  // printf
    #include <stdarg.h> // va_list, va_start, va_arg, va_end 
    #include "cv.h" 
    #include "opencv2/highgui/highgui_c.h"

    主体程序:

    void cvShowMultiImages(char* title,int nChannels, int nArgs, ...) 
    {
        IplImage* img;      // img - Used for getting the arguments  
        IplImage* DispImage;// DispImage - the image in which all the input images are to be copied
        int size_r,size_c;  // size - the size of the images in the window
        int ind;            // ind - the index of the image shown in the window
        int x_c, y_r;       // x_c,y_r - the coordinate of top left coner of input images
        int w, h;           // w,h - the width and height of the image
        int r, c;           // r - row , c - col 
        int space_r,space_c;// space - the spacing between images
        if(nArgs <= 0) {    // If argc < 0 or argc > 12 , return without displaying 
            printf("Number of arguments too small..../n");
            return;
        }
        else if(nArgs > 12) {
            printf("Number of arguments too large..../n");
            return;
        }
        // Determine the size of the image, 
        // and the number of rows/cols 
        // from number of arguments 
        else if (nArgs == 1) {
            r = c = 1;
            size_r = 480; size_c = 640 ; 
        }
        else if (nArgs == 2) { // x_c = size_row y_r=size_col
            r = 1; c = 2;
            // size_r = 705; size_c = 350 ; // specail set for show the full story of lena
            size_r = 405; size_c = 540 ; 
        }
        else if ( nArgs == 3 || nArgs == 4) {
            r = 2; c = 2;
            size_r = 405; size_c =540 ; 
        }
        else if (nArgs == 5 || nArgs == 6) {
            r = 2; c = 3;
            size_r = 360; size_c = 480;
        }
        else if (nArgs == 7 || nArgs == 8) {
            r = 2; c = 4;
            size_r = 200; size_c = 240;
        }
        else {
            r = 3; c = 4;
            size_r = 150; size_c = 200; 
        }
        // Create a new 3 channel image to show all the input images 
        // cvSize(width,height)=(col,row)=(y_r,x_c) 
        DispImage = cvCreateImage( cvSize(30 + size_c*c,40 + size_r*r), IPL_DEPTH_8U, nChannels );
        // Used to get the arguments passed
        va_list args;
        va_start(args, nArgs); // stdarg.h
        // Loop for nArgs number of arguments
        space_r = 40/(r+1);
        space_c = 30/(c+1);
        for (ind = 0, x_c = space_c, y_r = space_r; ind < nArgs; ind++, x_c += (space_c + size_c)) {
            // Get the Pointer to the IplImage
            img = va_arg(args, IplImage*);  // stdarg.h
            if(img == 0) {// If img == NULL, release the image, and return
                printf("Invalid arguments");
                cvReleaseImage(&DispImage);
                return;
            }
            // Find the width and height of the image
            w = img->width;
            h = img->height;
            // Used to Align the images
            // i.e. Align the image to next row e.g.r=1,c=2, this row is end , we have ind%c==0 ,
            // then we move to the next row,even the next row can't through the cond  ind < nArgs
            if( ind % c == 0 && x_c!= space_c) {
                x_c  = space_c;
                y_r += space_r + size_r;
            }
            cvSetImageROI(DispImage, cvRect(x_c, y_r, size_c, size_r)); // Set the image ROI to display the current image
            cvResize(img, DispImage);   // Resize the input image and copy the it to the Single Big Image
            cvResetImageROI(DispImage); // Reset the ROI in order to display the next image
        }
        cvNamedWindow( title, 1 );      // Create a new window, and show the Single Big Image
        cvShowImage( title, DispImage);
        cvWaitKey(0);
        va_end(args);                   // End the number of arguments
        cvReleaseImage(&DispImage);     // Release the Image Memory
    }

    3. 程序调用方式与结果显示

    应用时,请注意所有输入的图像都应该为同一个通道数:1或者3

    cvShowMultiImages("Lena1",3,2,src1,edges1Color);

    cvShowMultiImages("Lena2",3,2,src2,edges2Color);

    显示结果为:

    好吧,其实me更想展示的是 ———— The Complete Story of Lena :

    reference

    1. va_list - C++ Reference
    2. opencv中文论坛
  • 相关阅读:
    js的break与continue
    mongodb报错UserNotFound: Could not find user xxx@xxx
    2.mongodb基本命令
    centos导入mongodb数据库
    linux全局安装express
    centos查看软件及配置软件环境变量
    centos查看版本号
    Spring-boot+Mybatis+Maven+MySql搭建实例
    Spring Boot 静态资源处理
    使用Spring Boot开发WEB页面
  • 原文地址:https://www.cnblogs.com/ouxiaogu/p/3379819.html
Copyright © 2011-2022 走看看