前一段时间看了yang_xian521写了一篇用opencv在一个窗口中显示多幅图像的博文,感觉非常不错。以前在很长一段时间内,都只是用Matlab显示多幅图像。遗憾的是,opencv没有集成这样的功能。今天我将该作者的博文转载过来,供大家共同学习。转载地址为:http://blog.csdn.net/yang_xian521/article/details/7915396
作者主要写了一个显示多幅图像的函数,但该函数最多只能显示12幅图像。
开发环境为VC6.0、OpenCv1.0源代码如下:
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdarg.h> //输入可变参数个数
#include <time.h>
#include <iostream>
//显示多幅图像
void cvShowManyImages(char* title, int nArgs, ...)
{
IplImage *img; // img - Used for getting the arguments
IplImage *DispImage; // DispImage - the image in which input images are to be copied
int size;
int i;
int m, n;
int x, y;
int w, h; //w: 每行最多的窗口个数, h: 每列最多的窗口个数
// scale - How much we have to resize the image
float scale;
int max;
// 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)// 显示1幅图像,每行每列只有一幅图像
{
w = h = 1;
size = 400;
}
else if (nArgs == 2)//显示2幅图像, 每行两幅图像,每列1幅图像,即1行2列
{
w = 2; h = 1;
size = 400;
}
else if (nArgs == 3 || nArgs == 4) //显示3或4副图像,2X2列
{
w = 2; h = 2;
size = 350;
}
else if (nArgs == 5 || nArgs == 6) //显示5或6幅图像,3X2列
{
w = 3; h = 2;
size = 200;
}
else if (nArgs == 7 || nArgs == 8) //显示7或8幅图像,4X2列
{
w = 4; h = 2;
size = 200;
}
else // 大于8幅,小于13幅图像时,4X3列
{
w = 4; h = 3;
size = 150;
}
// 创建一个3通道的图像
DispImage = cvCreateImage( cvSize( 60 + size*w, 60 + size*h), 8, 3 ); //cvSize( 100+ size*w, 60 + size*h)
// Used to get the arguments passed
va_list args;
va_start(args, nArgs);
// Loop for nArgs number of arguments
for (i = 0, m = 10, n = 10; i < nArgs; i++, m += (10 + size))
{
// Get the Pointer to the IplImage
img = va_arg(args, IplImage*);
if(img == 0)
{
printf("Invalid arguments");
cvReleaseImage(&DispImage);
return;
}
// Find the width and height of the image
x = img->width;
y = img->height;
// Find whether height or width is greater in order to resize the image
max = (x > y)? x: y;
// 图像的尺度
scale = (float) ( (float) max / size );
// Used to Align the images
if( i % w == 0 && m!= 10)
{
m = 10;
n = size-100;
//n+= size;
}
// Set the image ROI to display the current image
cvSetImageROI(DispImage, cvRect(m, n, (int)( x/scale ), (int)( y/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
cvShowImage( title, DispImage);
// End the number of arguments
va_end(args);
// Release the Image Memory
cvReleaseImage(&DispImage);
}
int main(int argc,char **argv)
{
int i=0;
IplImage *frame=cvLoadImage("4444.jpg");
cvNamedWindow("video",1);
cvResizeWindow("video",2000,1000);
IplImage *frame_not=cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);
cvNot(frame,frame_not); //图像取反
IplImage *frame_gray=cvCreateImage(cvGetSize(frame),frame->depth,1);
IplImage *frame1=cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);
IplImage *frame_canny=cvCreateImage(cvGetSize(frame),frame->depth,1);
IplImage *frame2=cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);
cvCvtColor(frame,frame_gray,CV_RGB2GRAY);
cvCvtColor(frame_gray,frame1,CV_GRAY2BGR);
cvCanny(frame_gray,frame_canny,20,75,3);
cvCvtColor(frame_canny,frame2,CV_GRAY2BGR);
cvShowManyImages("video",4,frame,frame_not,frame1,frame2);
cvWaitKey(0);
cvReleaseImage(&frame_not);
cvReleaseImage(&frame1);
cvReleaseImage(&frame_gray);
cvReleaseImage(&frame2);
cvReleaseImage(&frame_canny);
cvDestroyWindow("video");
return 0;
}
显示结果为:
注意:
这里用到了输入可变参数个数的函数,其中头文件#include <stdarg.h> 可以使得输入参数的个数可变。