背景:
在项目中要使用到工业摄像头,还有一个位移台。我们设计的功能复杂又相互嵌套,每个功能模块要访问摄像头的类。这时该怎么设计呢?
1 .在每个功能中都初始化一个相机的控制类吗,这样的话,相机被反复初始化,反复 打开,这显然是不行的。因为相机打开以后,第二次就打不开了,因为相机已经被占用,不能再打开,就要关闭再打开,可是关闭以后,第一个功能模块就用不了了,要解决这个问题就要每个功能函数 都要有重复的打开关闭的操作,程序很傻。
2. 相机初始化一次,功能模块获取他,不再初始化。 用 extern 修饰 可以跨文件访问 但是这样不利于封装,文件关联性比较强。
为了更好的封装,我们用类的静态指针来共享设备控制接口
GLOBALDATA_H
class GlobalData
{
public:
static GlobalData* GetInstance();
GlobalData();
~GlobalData();
DahengController* camera;
TriaxialController* platform;
private:
static GlobalData* global_data_;
};
static GlobalData* GetInstance(); 是一个静态方法
static GlobalData* global_data_; 是一个私有静态指针
上面的get方法获取获取下面的静态指针,我们使用静态指针来共享各个设备控制接口
cpp
#include "globaldata.h"
GlobalData* GlobalData::global_data_ = nullptr;
GlobalData* GlobalData::GetInstance()
{
if (global_data_ == nullptr)
global_data_ = new GlobalData();
return global_data_;
}
GlobalData::GlobalData() {
camera = nullptr;
platform = nullptr;
}
main
void InitSystem() {
GlobalData* gd = GlobalData::GetInstance();
QTextCodec *codec = QTextCodec::codecForName("GBK");
//初始化摄像头库
gd->camera = new DahengController();
gd->camera->Init();
if (!gd->camera->IsOpen()) {
QMessageBox ::
critical(NULL, codec->toUnicode("错误!!!!!"), codec->toUnicode("相机设备打不开"), QMessageBox::Yes , QMessageBox::Yes);
//std::exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
InitSystem();
MainWindow window;
window.resize(QGuiApplication::primaryScreen()->size());
window. show();
return a.exec();
}
某个相机功能模块(片段)
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);
auto_focus_worker->moveToThread(auto_focus_thread);
gd->mapping_area = &mapping_rect;
gd->image_viewer = image_viewer;
ui->horizontalLayout_image_viewer->addWidget(image_viewer);
//注册回调
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();
}
//只有上一次检查对焦执行结束后才开始下一次
if (!auto_focus_thread->isRunning() && is_auto_focus) {
mat = mat(cv::Rect(mat.cols/2 - 250, mat.rows/2 - 250, 500, 500));
image_auto_focus_list_.push_back(mat);
auto_focus_thread->start();
}
frame_rate_of_acquisition++;
index++;
if (index >= MAXINT32) {
index = 0;
}
});
}
我们在相机的某个功能对应的类中定义一个
GlobalData* gd;初始化为 GlobalData::GetInstance() 就可以共享一个 camera 了