VS2015+Qt5.9+ZED Stereo相机视频显示框架

由于ZED提供的SDK获取的都是其自己定义的视频格式SVO,不便于进行开发。按导师要求整了一个可编辑的显示框架。

VS2015使用Qt模块不予赘述,参考资料很多。新建工程建Qt工程即可,双击ui进行界面设计就完事儿了。

主界面如图一:

VS2015+Qt5.9+ZED Stereo相机视频显示框架_第1张图片

在groundBox中添加了两个GraphicsView,为了实现放大缩小功能需要继承QGraphicsView写一个新类。具体内容参考了以下这篇博客:

https://blog.csdn.net/kunyxu/article/details/78864587

按照以上教程新建好类以后,需要将两个GraphicsView控件提升,注意提升使用的头文件名一定要和新建的类一致。

VS2015+Qt5.9+ZED Stereo相机视频显示框架_第2张图片

我在新建MyGraphicsView时在c++的新建类界面选择基类QGraphicsView会提示找不到这个类,但是没关系,继续建,在新建的类中添加头文件即可 #include

由于ZED部分基于OpenCV,Qt控件显示每一帧图像用到QImage类型。因此需要将Mat转为QImage。这部分函数参考了:

https://blog.csdn.net/dong_zhihong/article/details/54583466

只用了博主一个函数

QImage cvMat2QImage(const cv::Mat& mat)  
{  
    // 8-bits unsigned, NO. OF CHANNELS = 1  
    if(mat.type() == CV_8UC1)  
    {  
        QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);  
        // Set the color table (used to translate colour indexes to qRgb values)  
        image.setColorCount(256);  
        for(int i = 0; i < 256; i++)  
        {  
            image.setColor(i, qRgb(i, i, i));  
        }  
        // Copy input Mat  
        uchar *pSrc = mat.data;  
        for(int row = 0; row < mat.rows; row ++)  
        {  
            uchar *pDest = image.scanLine(row);  
            memcpy(pDest, pSrc, mat.cols);  
            pSrc += mat.step;  
        }  
        return image;  
    }  
    // 8-bits unsigned, NO. OF CHANNELS = 3  
    else if(mat.type() == CV_8UC3)  
    {  
        // Copy input Mat  
        const uchar *pSrc = (const uchar*)mat.data;  
        // Create QImage with same dimensions as input Mat  
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);  
        return image.rgbSwapped();  
    }  
    else if(mat.type() == CV_8UC4)  
    {  
        qDebug() << "CV_8UC4";  
        // Copy input Mat  
        const uchar *pSrc = (const uchar*)mat.data;  
        // Create QImage with same dimensions as input Mat  
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);  
        return image.copy();  
    }  
    else  
    {  
        qDebug() << "ERROR: Mat could not be converted to QImage.";  
        return QImage();  
    }  
}  

附上主窗口程序:

ZED_Video.h

#pragma once

#include 
#include "ui_ZED_Video.h"

#include 
#include 
#include 
#include  

#include "QTimer"

class ZED_Video : public QMainWindow
{
	Q_OBJECT

public:
	ZED_Video(QWidget *parent = Q_NULLPTR);

private slots:
	void on_btnOpen_clicked();
	void on_btnStop_clicked();

	void GetFrameFromCamera();

public:
	//ZED
	sl::Camera zed;
	std::string svo_input_path;
	sl::InitParameters initParameters;

	cv::Mat L_img_cv;
	cv::Mat R_img_cv;

	sl::Resolution image_size;
	int width;
	int height;

public:
	
	QImage cvMat2QImage(const cv::Mat& mat);

private:
	Ui::ZED_VideoClass ui;

	int svo_position = 0;
	//static bool exit_app;
	bool VideoOpen;
	QTimer *timer;
};

ZED_Video.cpp

#include "ZED_Video.h"
#include 
#include 
#include 
#include "utils.hpp"
#include 
#include 
#include 

ZED_Video::ZED_Video(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	timer = new QTimer(this);
	VideoOpen = false;

	initParameters.camera_resolution = sl::RESOLUTION_HD1080;
	initParameters.camera_fps = 60;
	initParameters.sdk_verbose = false;

	connect(timer, SIGNAL(timeout()), this, SLOT(GetFrameFromCamera()));
	connect(ui.btnOpen, SIGNAL(clicked()), this, SLOT(on_btnOpen_clicked()));
	connect(ui.btnStop, SIGNAL(clicked()), this, SLOT(on_btnStop_clicked()));//打开摄像头
}

void ZED_Video::on_btnOpen_clicked()
{
	//if (!VideoOpen)
	//{
	//	QString curPath = QDir::homePath();//获取系统当前目录
	//	QString dlgTitle = QString::fromLocal8Bit("选择视频文件"); //对话框标题
	//	QString filter = QString::fromLocal8Bit("svo文件(*.svo);;所有文件(*.*)"); //文件过滤器,wmv文件(*.wmv);;mp4文件(*.mp4);;所有文件(*.*)
	//	QString aFile = QFileDialog::getOpenFileName(this, dlgTitle, curPath, filter);

	//	if (aFile.isEmpty())
	//		return;

	//	svo_input_path = aFile.toStdString();
	//	initParameters.svo_input_filename.set(svo_input_path.c_str());
	//	initParameters.coordinate_units = sl::UNIT_MILLIMETER;

	//	// Open the SVO file specified as a parameter
	//	sl::ERROR_CODE err = zed.open(initParameters);
	//	if (err != sl::SUCCESS) {
	//		//std::cout << toString(err) << std::endl;
	//		sl::String err_str = toString(err);
	//		QMessageBox::information(NULL, "Error", err_str.c_str(), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
	//		zed.close();
	//		return; // Quit if an error occurred
	//	}

	//	VideoOpen = true;

	//}
	//// Get image size
	//image_size = zed.getResolution();
	//width = image_size.width;
	//height = image_size.height;
	////width_sbs = image_size.width * 2;

	//QString videoPath = QString::fromStdString(svo_input_path);
	////ui.LabCurMedia->setText(videoPath);

	////获得每一帧图像并显示
	//GetFrameFromCamera();

	if (VideoOpen)
	{
		QMessageBox::information(NULL, "Error", "Camera is on", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
		return;
	}

	//timer->killTimer;

	sl::ERROR_CODE err = zed.open(initParameters);
	if (err != sl::SUCCESS)
	{
		QMessageBox::information(NULL, "Error", "Camera failed!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
		zed.close();
		return;
	}

	//获取图像大小
	width = (int)zed.getResolution().width;
	height = (int)zed.getResolution().height;
	//获取标定参数
	sl::CalibrationParameters calibration_params = zed.getCameraInformation().calibration_parameters;
	
	timer->start(15);
	VideoOpen = true;
	//GetFrameFromCamera();
}
void ZED_Video::on_btnStop_clicked()
{
	timer->stop();//关闭定时器
	zed.close();
	VideoOpen = false;
	return;
}

void ZED_Video::GetFrameFromCamera()
{
	//sl::Mat left_image(width, height, sl::MAT_TYPE_8U_C4);
	//cv::Mat left_image_ocv = slMat2cvMat(left_image);

	//sl::Mat  right_image(width, height, sl::MAT_TYPE_8U_C4);
	//cv::Mat right_image_ocv = slMat2cvMat(right_image);

	////sl::Mat  depth_image(width, height, sl::MAT_TYPE_32F_C1);
	////cv::Mat depth_image_ocv = slMat2cvMat(depth_image);

	//sl::RuntimeParameters rt_param;
	//rt_param.sensing_mode = sl::SENSING_MODE_FILL;

	//int nb_frames = zed.getSVONumberOfFrames();
	//QImage Qt_imgL;
	//QImage Qt_imgR;

	////SetCtrlHandler();
	//while (!exit_app)
	//{
	//	if (zed.grab() == sl::SUCCESS)
	//	{
	//		svo_position = zed.getSVOPosition();

	//		// Retrieve SVO images,get L & R img
	//		zed.retrieveImage(left_image, sl::VIEW_LEFT);
	//		zed.retrieveImage(right_image, sl::VIEW_RIGHT);

	//		//cv::imshow("View", left_image_ocv);
	//		//cv::waitKey(2);

	//		//深拷贝?
	//		L_img_cv = left_image_ocv.clone();
	//		R_img_cv = right_image_ocv.clone();

	//		//cv::imshow("View", L_img_cv);
	//		//cv::waitKey(2);
	//		Qt_imgL = cvMat2QImage(&L_img_cv);
	//		Qt_imgR = cvMat2QImage(&R_img_cv);

	//		ui.graphicsView_L->getResult(Qt_imgL);
	//		std::ostringstream filename1;
	//		//filename1 << std::setw(6) << svo_position << ".jpg";

	//		//std::string fn = filename1.str();
	//		//QString imgfn = QString::fromStdString(fn);
	//		//Qt_imgL.save(imgfn, "JPG");
	//		//ui.graphicsView_L->fitInView(Qt_imgL);
	//		ui.graphicsView_R->getResult(Qt_imgR);
	//		//timer->start(15);

	//	}

	//	if (svo_position >= (nb_frames - 1))
	//	{ // End of SVO
	//		qDebug() << "\nSVO end has been reached. Exiting now.\n";
	//		exit_app = true;
	//	}
	//}


	sl::Mat left_image(width, height, sl::MAT_TYPE_8U_C4);
	cv::Mat left_image_ocv = slMat2cvMat(left_image);

	sl::Mat  right_image(width, height, sl::MAT_TYPE_8U_C4);
	cv::Mat right_image_ocv = slMat2cvMat(right_image);

	QImage Qt_imgL;
	QImage Qt_imgR;

	if (zed.grab() == sl::SUCCESS)
	{
		svo_position = zed.getSVOPosition();

		// Retrieve SVO images,get L & R img
		zed.retrieveImage(left_image, sl::VIEW_LEFT);
		zed.retrieveImage(right_image, sl::VIEW_RIGHT);

		L_img_cv = left_image_ocv.clone();
		R_img_cv = right_image_ocv.clone();

		Qt_imgL = cvMat2QImage(L_img_cv);
		Qt_imgR = cvMat2QImage(R_img_cv);

		ui.graphicsView_L->getResult(Qt_imgL);
		ui.graphicsView_R->getResult(Qt_imgR);

		//cv::imshow("View", L_img_cv);
		//cv::waitKey(2);

	}



}

QImage ZED_Video::cvMat2QImage(const cv::Mat& mat)
{
	// 8-bits unsigned, NO. OF CHANNELS = 1  
	if (mat.type() == CV_8UC1)
	{
		QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
		// Set the color table (used to translate colour indexes to qRgb values)  
		image.setColorCount(256);
		for (int i = 0; i < 256; i++)
		{
			image.setColor(i, qRgb(i, i, i));
		}
		// Copy input Mat  
		uchar *pSrc = mat.data;
		for (int row = 0; row < mat.rows; row++)
		{
			uchar *pDest = image.scanLine(row);
			memcpy(pDest, pSrc, mat.cols);
			pSrc += mat.step;
		}
		return image;
	}
	// 8-bits unsigned, NO. OF CHANNELS = 3  
	else if (mat.type() == CV_8UC3)
	{
		// Copy input Mat  
		const uchar *pSrc = (const uchar*)mat.data;
		// Create QImage with same dimensions as input Mat  
		QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
		return image.rgbSwapped();
	}
	else if (mat.type() == CV_8UC4)
	{
		//qDebug() << "CV_8UC4";
		// Copy input Mat  
		const uchar *pSrc = (const uchar*)mat.data;
		// Create QImage with same dimensions as input Mat  
		QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
		return image.copy();
	}
	else
	{
		qDebug() << "ERROR: Mat could not be converted to QImage.";
		return QImage();
	}
}

运行测试:

你可能感兴趣的:(CV)