计算机视觉
图像处理

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

参考Opencv中文论坛的一个帖子,实现了在一个窗口显示多个视频子窗口,能够读入单个的视频或摄像头数据,然后在一个窗口中分别显示原始帧图像、反色图像、灰度图像以及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 )
{
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的原理与使用,参见 http://www.cppblog.com/qiujian5628/archive/2008/01/21/41562.html

转载注明来源:CV视觉网 » OpenCV学习笔记(5)在单个窗口中显示多个视频子窗口

分享到:更多 ()
扫描二维码,给作者 打赏
pay_weixinpay_weixin

请选择你看完该文章的感受:

0不错 0超赞 0无聊 0扯淡 0不解 0路过

评论 4

评论前必须登录!