作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
开发环境
操作系统:Windows 10 1903 18362.778
相机型号:MV-CA020-10GM
相机软件:MVS_SDK_V3_2_0_VC90_Runtime_190626,MVS_STD_3.1.0_181229
软件版本:Qt 5.12.8, vs2017 Community
通信方式:GigE - 千兆以太网通信协议
驱动与SDK
开发包和驱动下载地址
提取码:2hhn
安装驱动和开发包完成之后,可以找到以下目录:
- D:\Program Files (x86)\MVS\Development
- Documentations - 使用手册、示例程序说明等等
- Includes - 头文件
- Libraries - 库文件(包括 xxx.lib,xxx.a)
- Samples - 示例程序源代码
海康威视相机介绍
海康威视相机的文档特别清晰,特别是示例代码非常详细,可以非常快速的上手并使用。安装了海康威视相机驱动也可以使用巴斯勒的相机,博主感觉海康威视相机像是对巴斯勒相机做了包装和拓展,博主查看了源代码,其中 GenICam 这一块的代码和巴斯勒是完全相同的。。。
函数定义中把每个函数的使用都介绍的很清楚,这里就不多做介绍了。
我的代码
实现功能:相机图像的实时显示,并且可以在需要的时候获取当前帧数据,用于分析或者保存;
首先需要在pro中配置头文件和库文件
INCLUDEPATH += $$PWD/MV_Camera_Control/include/ \
contains(DEFINES, WIN64) {
LIBS += -L$$PWD/MV_Camera_Control/lib/win64/ -lMvCameraControl
} else {
LIBS += -L$$PWD/MV_Camera_Control/lib/Win32/ -lMvCameraControl
}
自定义相机基类 Camera
#ifndef CAMERA_H
#define CAMERA_H
#include <QObject>
#include <QImage>
#include <QTimer>
#include <QMutex>
#include <opencv2/opencv.hpp>
class Camera : public QObject
{
Q_OBJECT
public:
enum CameraType {
Basler = 1, // 巴斯勒相机
IC_Imaging, // 映美精相机
MV, // 海康威视相机
Virtual // 虚拟相机
};
explicit Camera(CameraType type = Basler) : m_type(type) {}
virtual void initCamera() = 0; // 初始化相机
virtual void destroyCamera() = 0; // 销毁相机
virtual void openCamera() = 0; // 打开相机
virtual void closeCamera() = 0; // 关闭相机
virtual void startWork() = 0; // 开始工作
virtual void stopWork() = 0; // 停止工作
virtual cv::Mat takeAPic() = 0; // 获取当前图像
void start() { m_timer.start(); }
void stop() { m_timer.stop(); }
void setInterval(int time) { m_timer.setInterval(time); }
CameraType getCameraType() { return m_type; }
signals:
void updateImage(QImage image);
protected:
CameraType m_type;
QMutex m_mutex;
QTimer m_timer;
};
#endif // CAMERA_H
自定义 BMVCamerControl 相机控制类
#ifndef BMVCAMERCONTROL_H
#define BMVCAMERCONTROL_H
#include "../camera.h"
#include "MvCameraControl.h"
class BMVCamerControl : public Camera
{
public:
enum BMVCamerProperty {
Width, // 图片宽度
Height, // 图片高度
ExposureTime, // 曝光时间
Brightness, // 亮度
FrameRate, // 帧率
Gain, // 增益
PixelFormat, // 像素格式
TriggerMode // 触发模式
};
explicit BMVCamerControl(Camera::CameraType type = Camera::CameraType::MV);
virtual void initCamera() override;
virtual void destroyCamera() override;
virtual void openCamera() override;
virtual void closeCamera() override;
virtual void startWork() override;
virtual void stopWork() override;
virtual cv::Mat takeAPic() override;
QString getCameraProperty(BMVCamerControl::BMVCamerProperty type); // 获取相机参数
void setCameraProperty(BMVCamerControl::BMVCamerProperty type, double value = 0.0); // 设置相机参数
public slots:
void updateFrame();
private:
void *m_devHandle;
unsigned char* m_data;
const int m_size = 1280 * 1024 * 3;
MV_FRAME_OUT_INFO_EX m_frame_info;
};
#endif // BMVCAMERCONTROL_H
#include "bmvcamercontrol.h"
#include "globalfun.h"
BMVCamerControl::BMVCamerControl(Camera::CameraType type) : Camera(type)
{
m_timer.setInterval(GlobalValue::cam_itl);
connect(&m_timer, &QTimer::timeout, this, &BMVCamerControl::updateFrame);
}
void BMVCamerControl::initCamera()
{
m_devHandle = nullptr;
m_data = new unsigned char[m_size];
}
void BMVCamerControl::destroyCamera()
{
try {
stopWork();
closeCamera();
if ( m_devHandle ) {
MV_CC_DestroyHandle(m_devHandle); // 销毁设备句柄
m_devHandle = nullptr;
delete[] m_data;
}
} catch (...) {
qDebug() << "destroyCamera erroer !";
}
}
void BMVCamerControl::openCamera()
{
try {
MV_CC_DEVICE_INFO_LIST pstDevList;
int ret = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &pstDevList);
if ( ret == MV_OK ) {
if ( pstDevList.nDeviceNum == 0 ) {
qDebug() << "No device found !";
} else {
MV_CC_CreateHandle(&m_devHandle, pstDevList.pDeviceInfo[0]); // 创建设备句柄
MV_CC_OpenDevice(m_devHandle); // 打开设备
// 探测网络最佳包大小(只对GigE相机有效)
int nPacketSize = MV_CC_GetOptimalPacketSize(m_devHandle);
MV_CC_SetIntValue(m_devHandle, "GevSCPSPacketSize", nPacketSize);
MV_CC_SetPixelFormat(m_devHandle, PixelType_Gvsp_Mono8); // 设置像素格式
}
}
} catch (...) {
qDebug() << "openCamera erroer !";
}
}
void BMVCamerControl::closeCamera()
{
try {
MV_CC_CloseDevice(m_devHandle); // 关闭相机
} catch (...) {
qDebug() << "closeCamera erroer !";
}
}
void BMVCamerControl::startWork()
{
// 判断相机是否处于连接状态
if ( !MV_CC_IsDeviceConnected(m_devHandle) ) {
return;
}
try {
MV_CC_StartGrabbing(m_devHandle); // 开始取流
m_timer.start();
} catch (...) {
qDebug() << "startWork erroer !";
}
}
void BMVCamerControl::stopWork()
{
try {
if ( MV_CC_IsDeviceConnected(m_devHandle) ) {
MV_CC_StopGrabbing(m_devHandle); // 停止取流
m_timer.stop();
}
} catch (...) {
qDebug() << "stopWork erroer !";
}
}
cv::Mat BMVCamerControl::takeAPic()
{
// 判断相机是否处于连接状态
if ( !MV_CC_IsDeviceConnected(m_devHandle) ) {
return cv::Mat();
}
QMutexLocker locker(&m_mutex);
try {
int nRet = MV_CC_GetOneFrameTimeout(m_devHandle, m_data, m_size, &m_frame_info, 1000);
if ( nRet == MV_OK ) {
QImage image(static_cast<uchar*>(m_data),
m_frame_info.nWidth,
m_frame_info.nHeight,
QImage::Format_Grayscale8);
QImage retImage = image.convertToFormat(QImage::Format_RGB888);
cv::Mat mat = GlobalFun::convertQImageToMat(retImage);
return mat.clone();
} else {
return cv::Mat();
}
} catch (...) {
qDebug() << "takeAPic erroer !";
return cv::Mat();
}
}
QString BMVCamerControl::getCameraProperty(BMVCamerControl::BMVCamerProperty type)
{
// 判断相机是否处于连接状态
if ( !MV_CC_IsDeviceConnected(m_devHandle) ) {
return "";
}
QString ret = "";
MVCC_INTVALUE int_value;
MVCC_FLOATVALUE float_value;
MVCC_ENUMVALUE enum_value;
try {
switch (type) {
case Width: {
MV_CC_GetWidth(m_devHandle, &int_value);
ret = QString::number(int_value.nCurValue);
} break;
case Height: {
MV_CC_GetHeight(m_devHandle, &int_value);
ret = QString::number(int_value.nCurValue);
} break;
case ExposureTime: {
MV_CC_GetExposureTime(m_devHandle, &float_value);
ret = QString::number(float_value.fCurValue);
} break;
case Brightness: {
MV_CC_GetBrightness(m_devHandle, &int_value);
ret = QString::number(int_value.nCurValue);
} break;
case FrameRate: {
MV_CC_GetFrameRate(m_devHandle, &float_value);
ret = QString::number(float_value.fCurValue);
} break;
case Gain: {
MV_CC_GetGain(m_devHandle, &float_value);
ret = QString::number(float_value.fCurValue);
} break;
case PixelFormat: {
MV_CC_GetPixelFormat(m_devHandle, &enum_value);
ret = QString::number(enum_value.nCurValue);
} break;
case TriggerMode: {
MV_CC_GetTriggerMode(m_devHandle, &enum_value);
ret = QString::number(enum_value.nCurValue);
} break;
default: ret = ""; break;
}
} catch (...) {
qDebug() << "getCameraProperty erroer !";
}
return ret;
}
void BMVCamerControl::setCameraProperty(BMVCamerControl::BMVCamerProperty type, double value)
{
// 判断相机是否处于连接状态
if ( !MV_CC_IsDeviceConnected(m_devHandle) ) {
return;
}
try {
switch (type) {
case Width: {
MV_CC_SetWidth(m_devHandle, value);
} break;
case Height: {
MV_CC_SetHeight(m_devHandle, value);
} break;
case ExposureTime: {
MV_CC_SetExposureTime(m_devHandle, value);
} break;
case Brightness: {
MV_CC_SetBrightness(m_devHandle, value);
} break;
case FrameRate: {
MV_CC_SetFrameRate(m_devHandle, value);
} break;
case Gain: {
MV_CC_SetGain(m_devHandle, value);
} break;
case PixelFormat: {
MV_CC_SetPixelFormat(m_devHandle, value);
} break;
case TriggerMode: {
MV_CC_SetTriggerMode(m_devHandle, value);
} break;
default: break;
}
} catch (...) {
qDebug() << "setCameraProperty erroer !";
}
}
void BMVCamerControl::updateFrame()
{
QMutexLocker locker(&m_mutex);
try {
int nRet = MV_CC_GetOneFrameTimeout(m_devHandle, m_data, m_size, &m_frame_info, 1000);
if ( nRet == MV_OK ) {
QImage image(static_cast<uchar*>(m_data),
m_frame_info.nWidth,
m_frame_info.nHeight,
QImage::Format_Grayscale8);
emit updateImage(image.convertToFormat(QImage::Format_RGB888));
}
} catch (...) {
qDebug() << "updateFrame erroer !";
}
}
其他请参考
- Qt调用工业相机之巴斯勒相机
- Qt调用工业相机之映美精相机