Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9472853
  • 博文数量: 1751
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 20101
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1751)

文章存档

2024年(27)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: Android平台

2016-09-22 09:54:42

http://blog.csdn.net/axingxingzp/article/details/13508267

实现了在一个窗口显示多个视频子窗口,能够读入单个的视频或摄像头数据,然后在一个窗口中分别显示原始帧图像、反色图像、灰度图像以及Canny边缘检测图像。并在每个子窗口左上角显示系统时间,函数cvShowManyImages是改写的。

2

代码如下:

#include "stdafx.h" #include 
#include 
#include 

#include 
#include 
#include  // 隐藏 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 window  int ind; // ind - the index of the image shown in the window  int x, y; // x,y - the coordinate of top left coner of input images  int 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 image  float scale; // max - Max value of the width and height of the image  int max; // space - the spacing between images  int 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;
   } 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 = 300;
   } else if (nArgs == 2) {
      r = 2; c = 1;
      size = 300;
   } else if (nArgs == 3 || nArgs == 4) {
      r = 2; c = 2;
      size = 300;
   } else if (nArgs == 5 || nArgs == 6) {
      r = 3; c = 2;
      size = 200;
   } else if (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 return  if(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 row  if( 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 ) //见博文 
	

int main(int argc,char* argv[])详解与main函数带参在VS中调试方法

{ 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); return 0; }

有几点需要注意: 
1、在 while 循环中,处理完的图像应及时释放所占用的内存(cvReleaseImage),否则会不断占用内存空间以致系统当机。 
2、图像数据的指针若是由 cvCreateImage 返回的,则应由 cvReleaseImage 来释放内存;如果是读取自视频或摄像头的帧图像,则应用 cvReleaseCapture 来释放内存,不必再用 cvReleaseImage() ,在 while 循环中使用 cvReleaseImage( &frame )  会导致生成的程序在执行时出错。

3,有关va_list、va_start、va_arg、va_end有详述见博客相关博文

阅读(2501) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~