当前位置:AIGC资讯 > 数据采集 > 正文

QT封装相机的多线程采集(回调采集)

重点是思想和框架

把图像采集和图像处理放在线程中
  其中图像处理作为call_back 

/* 
 CameraController.cpp  片段
*/ 

//图像处理的callback 用函数作为参数
/*在CameraController 构造函数中  call_back_ 设置为   
   call_back_ = [](cv::Mat m) {
    std::cout << "no call back function\n";
  };
*/
void CameraController::RegisterCaptureCallback(std::function<void (cv::Mat)> call_back)
{
  call_back_ = call_back;

}


//循环采集图像图像
void CameraController::AcquireImages()
{
 /*
...... 
此处省略一些相机配置 和采集的命令 我们使用的是FILR工业相机,不是USB的,没用使用OPENCV的 vidiocap
*/
  //这里就是while(1)的作用
  for (unsigned int imageCnt = 0; imageCnt != k_numImages; imageCnt++) {
    //result_image  这是采集到图像  
      
        ImagePtr result_image = helper->camera->GetNextImage(timeout);
     ///转换了格式
        ImagePtr image = result_image->Convert(PixelFormat_BGR8, HQ_LINEAR);

     ///执行callback  图像处理的东西
        call_back_(cv::Mat(static_cast<int>(result_image->GetHeight()),
                          static_cast<int>(result_image->GetWidth()),
                          CV_8UC3,
                          image->GetData()).clone());
       }
     /*
    ...... 
    此处省略一些相机命令
*/
}
这是给外部的接口  内容是 把循环采集放在线程中
void CameraController::StartAcquisition()
{
  stop_acquisition_flag = false;
  /// 在helper 中的定义 std::thread* acquisition_thread = nullptr;
  helper->acquisition_thread = new std::thread(&CameraController::AcquireImages, this);
}

应用 CameraController     CameraPanel 是相机的UI界面

/*CameraPanel.cpp 片段*/

// 构造函数
CameraPanel::CameraPanel(QWidget *parent)
    : QWidget(parent),
      ui(new Ui::CameraPanel),
      image_viewer(new ImageViewer),
      is_camera_opened(false),
      gd(GlobalData::GetInstance()),
      auto_focus_worker(new QObject),
      auto_focus_thread(new QThread)
{
  ///省略一些代码 重点关注相机部分
  ui->setupUi(this);
  timer = new QTimer(this);

  //注册回调  采集完做哪些处理
  //用lambda 表达式作为参数
  gd->camera->RegisterCaptureCallback([this](cv::Mat mat) {
    static int index = 0;

    
    //图片产生太快 无法及时消费时 就不向list里面放入新图片
    if (image_show_list_.size() < 3) {
      image_show_list_.push_back(mat);
      
      //发送信号
      emit GetImage();
    }

    frame_rate_of_acquisition++;
    index++;
    if (index >= MAXINT32) {
      index = 0;
    }
  });

  //采集回调信号的槽函数
  connect(this, &CameraPanel::GetImage, this, [this]() {
    if (image_show_list_.empty()) {
      return;
    }
    cv::Mat mat = image_show_list_.front();
    image_show_list_.pop_front();
    /* 转化格式 在UI的Label 显示图像*/
    QImage image;
    image = QImage(reinterpret_cast<unsigned char*>(mat.data),
                   mat.cols,
                   mat.rows,
                   static_cast<int>(mat.step),
                   QImage::Format_RGB888);
    image_viewer->SetImage(image);

    frame_rate_of_display++;
  });

  //打印帧率
  connect(timer, &QTimer::timeout, this, [this]() {
    ui->label_image_frame_rate->setText(QString::number(frame_rate_of_display));

    frame_rate_of_display = 0;
    frame_rate_of_acquisition = 0;
  });

///........
}

///开始采集的按钮
void CameraPanel::on_push_button_camera_switch_clicked()
{
  if (!gd->camera->IsOpen()) {
    return;
  }
  if (is_camera_opened) {
    gd->camera->StopAcquisition();
    ui->pbAutoFocus->setEnabled(false);
    ui->push_button_camera_switch->setText(QString::fromLocal8Bit("打开"));
    is_camera_opened = false;
  } else {
    ///开始采集
    gd->camera->StartAcquisition();
    ui->pbAutoFocus->setEnabled(true);
    ui->push_button_camera_switch->setText(QString::fromLocal8Bit("关闭"));
    is_camera_opened = true;
  }
}

更新时间 2023-11-08