• OpenCV学习笔记在单个窗口中显示多个视频子窗口


    转自http://blog.csdn.net/chenyusiyuan/article/details/4642297

    参考OpenCV中文论坛的一个帖子(http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=7996&start=0)实现了在一个窗口显示多个视频子窗口,能够读入单个的视频或摄像头数据,然后在一个窗口中分别显示原始帧图像、反色图像、灰度图像以及Canny边缘检测图像。并在每个子窗口左上角显示系统时间,函数cvShowManyImages是改写的。

    2

    代码如下:

    #include "stdafx.h"
    #include <cv.h>
    #include <cxcore.h>
    #include <highgui.h>
    
    #include <stdio.h>
    #include <stdarg.h>
    #include <time.h>// 隐藏 console 窗口#pragma comment( linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" )// 单窗口显示多幅图像的函数void cvShowMultiImages(char* title, int nArgs, ...) 
    {
    
       // img - Used for getting the arguments    IplImage* img;
    
       // DispImage - the image in which all the input images are to be copied   IplImage* DispImage;
    
       int size;    // size - the size of the images in the windowint ind;        // ind - the index of the image shown in the windowint x, y;    // x,y - the coordinate of top left coner of input imagesint w, h;    // w,h - the width and height of the image
    
       // r - Maximum number of images in a column 
       // c - Maximum number of images in a row int r, c;
    
       // scale - How much we have to resize the imagefloat scale;
       // max - Max value of the width and height of the imageint max;
       // space - the spacing between imagesint space;
    
       // If the number of arguments is lesser than 0 or greater than 12
       // return without displaying if(nArgs <=0) {
          printf("Number of arguments too small..../n");
          return;
       }
       elseif(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 elseif (nArgs ==1) {
          r = c =1;
          size =300;
       }
       elseif (nArgs ==2) {
          r =2; c =1;
          size =300;
       }
       elseif (nArgs ==3|| nArgs ==4) {
          r =2; c =2;
          size =300;
       }
       elseif (nArgs ==5|| nArgs ==6) {
          r =3; c =2;
          size =200;
       }
       elseif (nArgs ==7|| nArgs ==8) {
          r =4; c =2;
          size =200;
       }
       else {
          r =4; c =3;
          size =150;
       }
    
       // Create a new 3 channel image to show all the input images   DispImage = cvCreateImage( cvSize(60+ size*r, 20+ size*c), IPL_DEPTH_8U, 3 );
    
       // Used to get the arguments passed   va_list args;
       va_start(args, nArgs);
    
       // Loop for nArgs number of arguments   space =20;
       for (ind =0, x = space, y = space; ind < nArgs; ind++, x += (space + size)) {
    
          // Get the Pointer to the IplImage      img = va_arg(args, IplImage*);
    
          // Check whether it is NULL or not
          // If it is NULL, release the image, and returnif(img ==0) {
             printf("Invalid arguments");
             cvReleaseImage(&DispImage);
             return;
          }
    
          // Find the width and height of the image      w = img->width;
          h = img->height;
    
          // Find whether height or width is greater in order to resize the image      max = (w > h)? w: h;
    
          // Find the scaling factor to resize the image      scale = (float) ( (float) max / size );
    
          // Used to Align the images
          // i.e. Align the image to next rowif( ind % r ==0&& x!= space) {
             x  = space;
             y += space + size;
          }
    
          // Set the image ROI to display the current image      cvSetImageROI(DispImage, cvRect(x, y, (int)( w/scale ), (int)( h/scale )));
    
          // Resize the input image and copy the it to the Single Big Image      cvResize(img, DispImage);
    
          // Reset the ROI in order to display the next image      cvResetImageROI(DispImage);
       }
    
       // Create a new window, and show the Single Big Image
       //cvNamedWindow( title, 1 );   cvShowImage( title, DispImage);
    
    
       // End the number of arguments   va_end(args);
    
       // Release the Image Memory   cvReleaseImage(&DispImage);
    }
    
    
    int main( int argc, char** argv ) 
    {
       CvCapture* capture;   
       
       if (argc ==1)
       {
          capture = cvCreateCameraCapture( 0 );
       }
       else
       {
          capture = cvCreateFileCapture( argv[1] );      
       }
       
       IplImage* frame;
       
       cvNamedWindow("video",1);
       cvResizeWindow("video",750,750);
       
       CvFont timeFont,timeFont1;
       cvInitFont(&timeFont,  CV_FONT_HERSHEY_COMPLEX, 1.0f,1.0f,0,1,8);
       cvInitFont(&timeFont1, CV_FONT_HERSHEY_COMPLEX, 1.0f,1.0f,0,1,8);
       
       // Initialize new applied memory of 'time1'char timestr[25];
       memset(timestr, 0, 25*sizeof(char));
       
       while (1)
       {
          frame = cvQueryFrame( capture );
          if (!frame) break;
             
          // Get the systme local time info      time_t rawtime; 
          struct tm* timeinfo; 
          //time( &rawtime ); 
          rawtime = time( NULL ); 
          timeinfo = localtime( &rawtime ); 
          char* p = asctime( timeinfo );
          
          // the 25th character of array 'p' is '/n'
          // but it can not be display correctly in the image
          // so we just read out the first 24 character of 'p'for (int i =0; i <24; i++)
          {
             timestr[i] =*p;
             p++;
          }
          p = NULL;
          
          // Bitwise inversion of every element of the current frame      IplImage* frame_not = cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);
          cvNot(frame,frame_not);
          
          // Get the gray scale image of the current frmae
          // and transform the gray image from single channel to three channels      IplImage* frame_gray=cvCreateImage(cvGetSize(frame),frame->depth,1);
          IplImage* frame1=cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);
          cvCvtColor(frame,frame_gray,CV_RGB2GRAY);
          cvCvtColor(frame_gray,frame1,CV_GRAY2BGR);
          
          // Do Canny edge detection
          // and transform the result image from single channel to three channels      IplImage* frame_canny=cvCreateImage(cvGetSize(frame),frame->depth,1);
          IplImage* frame2=cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);
          cvCanny(frame_gray,frame_canny,20,75,3);
          cvCvtColor(frame_canny,frame2,CV_GRAY2BGR);
    
          // Display the local time information in each image      cvPutText( frame,        timestr, cvPoint(5,25), &timeFont,  CV_RGB(255,0,0) );
          cvPutText( frame1,    timestr, cvPoint(5,25), &timeFont,  CV_RGB(255,0,0) );
          cvPutText( frame2,    timestr, cvPoint(5,25), &timeFont1, CV_RGB(255,0,0) );
          cvPutText( frame_not, timestr, cvPoint(5,25), &timeFont1, CV_RGB(255,0,0) );
    
          cvShowMultiImages("video",4,frame,frame_not,frame1,frame2);
    
          
          //cvWaitKey(33);int key = cvWaitKey(33);
          if( key ==27 ) break;
    
          cvReleaseImage(&frame_not);
          cvReleaseImage(&frame1);
          cvReleaseImage(&frame_gray);
          cvReleaseImage(&frame2);
          cvReleaseImage(&frame_canny);   
    
       }
       
       cvDestroyWindow("video");
       cvReleaseCapture(&capture);
    
       return0;
    
    }

    有几点需要注意:
    1、在 while 循环中,处理完的图像应及时释放所占用的内存(cvReleaseImage),否则会不断占用内存空间以致系统当机。
    2、 图像数据的指针若是由 cvCreateImage 返回的,则应由 cvReleaseImage 来释放内存;如果是读取自视频或摄像头的帧图像,则应用 cvReleaseCapture 来释放内存,不必再用 cvReleaseImage() ,在 while 循环中使用 cvReleaseImage( &frame )  会导致生成的程序在执行时出错。
    3、有关va_list、va_start、va_arg、va_end的原理与使用,参见 http://www.cppblog.com/qiujian5628/archive/2008/01/21/41562.html

  • 相关阅读:
    4.9版本的linux内核中实时时钟芯片pt7c4338的驱动源码在哪里
    4.9版本的linux内核中eeprom存储芯片at24c512的驱动源码在哪里
    4.9版本的linux内核中温度传感器adt7461的驱动源码在哪里
    4.9版本linux内核的ina220电流检测芯片源码在哪里
    nxp的layerscape系列芯片中的rcw指定了一些什么信息
    openwrt的编译系统是如何制作根文件系统的
    openwrt的编译系统在哪里对程序进行开机自动启动配置
    makefile中的word函数作用是什么
    jquery 动态增加table行,动态删除table行
    使用jQuery创建可删除添加行的动态表格,超级简单实用的方法
  • 原文地址:https://www.cnblogs.com/gune/p/3083280.html
Copyright © 2020-2023  润新知