opencv 一个窗口中显示多个视频子窗口

转自:http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=7996&start=0

在一个窗口中显示多个视频,并在每个子窗口左上角显示系统时间,函数cvShowManyImages是改写的
代码: 
#include <cv.h>
#include <highgui.h>

#include <stdio.h>
#include <stdarg.h>
#include <time.h>


void cvShowManyImages(char* title, int nArgs, ...) 
{

   // img - Used for getting the arguments 
   IplImage *img;

   // DispImage - the image in which input images are to be copied
   IplImage *DispImage;

   int size;
   int i;
   int m, n;
   int x, y;

   // w - Maximum number of images in a row 
   // h - Maximum number of images in a column 
   int 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) {
      w = h = 1;
      size = 300;
   }
   else if (nArgs == 2) {
      w = 2; h = 1;
      size = 300;
   }
   else if (nArgs == 3 || nArgs == 4) {
      w = 2; h = 2;
      size = 300;
   }
   else if (nArgs == 5 || nArgs == 6) {
      w = 3; h = 2;
      size = 200;
   }
   else if (nArgs == 7 || nArgs == 8) {
      w = 4; h = 2;
      size = 200;
   }
   else {
      w = 4; h = 3;
      size = 150;
   }

   // Create a new 3 channel image
   DispImage = cvCreateImage( cvSize(100 + size*w, 60 + size*h), 8, 3 );

   // Used to get the arguments passed
   va_list args;
   va_start(args, nArgs);

   // Loop for nArgs number of arguments
   for (i = 0, m = 20, n = 20; i < nArgs; i++, m += (20 + 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
      x = img->width;
      y = img->height;

      // Find whether height or width is greater in order to resize the image
      max = (x > y)? x: y;

      // Find the scaling factor to resize the image
      scale = (float) ( (float) max / size );

      // Used to Align the images
      if( i % w == 0 && m!= 20) {
         m = 20;
         n+= 20 + 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
   //cvNamedWindow( title, 1 );
   cvShowImage( title, DispImage);

   /*cvWaitKey(0);*/
   //cvDestroyWindow(title);

   // End the number of arguments
   va_end(args);

   // Release the Image Memory
   cvReleaseImage(&DispImage);
}
int main(int argc,char **argv) 
{
   CvCapture *capture;
   int i=0;
   if (argc>=2)
   {
      capture=cvCreateFileCapture(argv[1]);
   }
   else
   {
      printf("No video file input!/n");
      return -1;
   }
   IplImage *frame;
   cvNamedWindow("video",1);
   cvResizeWindow("video",700,660);
   CvFont timeFont,timeFont1;
   cvInitFont(&timeFont,CV_FONT_HERSHEY_COMPLEX,0.5f,0.5f,0,1,8);
   cvInitFont(&timeFont1,CV_FONT_HERSHEY_COMPLEX,0.5f,0.5f,0,1,8);
   char time1[25];
    memset(time1,0,25*sizeof(char));
   while (1)
   {
      frame=cvQueryFrame( capture );
      if (!frame)
      {
         break;
      }
      IplImage *frame_not=cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);
      cvNot(frame,frame_not);

      time_t rawtime; 
      struct tm * timeinfo; 
      time ( &rawtime ); 
      timeinfo = localtime ( &rawtime ); 
      
   
      char *p=asctime(timeinfo);
  //数组p的第25个字符为'/n',在图像上显示时为乱码,这里取其前24个字符显示在图像上
      
      for (i=0;i<24;i++)
      {
         time1[i]=*p;
         p++;
      }
      p=NULL;
      
       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);

      cvPutText(frame,time1,cvPoint(0,15),&timeFont,CV_RGB(255,0,0));
      cvPutText(frame1,time1,cvPoint(0,15),&timeFont,CV_RGB(255,0,0));
      cvPutText(frame2,time1,cvPoint(0,15),&timeFont1,CV_RGB(255,0,0));
      cvPutText(frame_not,time1,cvPoint(0,15),&timeFont1,CV_RGB(255,0,0));

      cvShowManyImages("video",4,frame,frame_not,frame1,frame2);
      cvWaitKey(33);

      cvReleaseImage(&frame_not);
      cvReleaseImage(&frame1);
      cvReleaseImage(&frame_gray);
      cvReleaseImage(&frame2);
      cvReleaseImage(&frame_canny);
   


      
   }
               cvDestroyWindow("video");
               cvReleaseCapture(&capture);

   return 0;

}


好的,这是一个OpenCV和Qt的示例代码,其包括两个线程,一个用于显示图像,一个用于保存图像。 首先,我们需要在Qt创建一个新的窗口类,用于显示图像。在这个示例,我们将创建一个继承自QLabel的自定义标签类。 ```c++ class ImageLabel : public QLabel { public: ImageLabel(QWidget* parent = nullptr) : QLabel(parent) {} void setImage(cv::Mat image) { // Convert OpenCV Mat to QImage QImage qimage(image.data, image.cols, image.rows, image.step, QImage::Format_RGB888); // Display the image on the label setPixmap(QPixmap::fromImage(qimage)); } }; ``` 接下来,我们需要定义用于显示图像的线程和用于保存图像的线程。这两个线程都需要继承自QThread,并实现run()函数。 ```c++ class ImageDisplayThread : public QThread { public: ImageDisplayThread(cv::Mat image, ImageLabel* label) : m_image(image), m_label(label) {} void run() override { // Display the image on the label m_label->setImage(m_image); } private: cv::Mat m_image; ImageLabel* m_label; }; class ImageSaveThread : public QThread { public: ImageSaveThread(cv::Mat image, QString filename) : m_image(image), m_filename(filename) {} void run() override { // Save the image to file cv::imwrite(m_filename.toStdString(), m_image); } private: cv::Mat m_image; QString m_filename; }; ``` 现在,我们可以在主线程调用这些线程,将图像传递给它们并启动它们。 ```c++ // Load the image from file cv::Mat image = cv::imread("image.jpg"); // Create a new window and display the image ImageLabel* label = new ImageLabel(); label->show(); label->setImage(image); // Create a filename for the saved image QString filename = "saved_image.jpg"; // Create the display thread and save thread ImageDisplayThread* displayThread = new ImageDisplayThread(image, label); ImageSaveThread* saveThread = new ImageSaveThread(image, filename); // Start the display and save threads displayThread->start(); saveThread->start(); ``` 这个示例演示了如何在Qt使用OpenCV来管理多个线程,以便显示和保存图像。请注意,这只是一个简单的示例,实际应用可能需要更复杂的线程管理和图像处理技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值