大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全家桶1年46,售后保障稳定
本文接上次的博客海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一),上个博客中并未用到QT,本文介绍项目内容及源码,供大家参考。
由于我的项目中是用海康相机作为拍照的一个中介,重点是在目标识别方向,请阅读源码时自动忽略。
如果对目标识别感兴趣,可以参考我的YOLO系列
https://blog.csdn.net/qq_45445740/category_9794819.html
目录
1.说明
1.1 环境配置
关于我在VS中的软件版本及相关的环境配置,请移步
海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一)(里面有详细的软硬件介绍)
1.2 背景说明
简单介绍下我的项目需求:
通过相机对物体拍照,后进行目标识别,并返回识别目标的准确位置。这里相机采用海康威视工业相机,人机交互界面选择QT。
界面功能介绍:搜索当前相机的信号,相机可进行图像的连续采集或触发式采集。
2.源码
MvCamera.h
/************************************************************************/
/* 以C++接口为基础,对常用函数进行二次封装,方便用户使用 */
/************************************************************************/
#ifndef _MV_CAMERA_H_
#define _MV_CAMERA_H_
#include "MvCameraControl.h"
#include <string.h>
#ifndef MV_NULL
#define MV_NULL 0
#endif
#include"opencv2/opencv.hpp"
#include"opencv2/imgproc/types_c.h"
using namespace cv;
class CMvCamera
{
public:
CMvCamera();
~CMvCamera();
// ch:获取SDK版本号 | en:Get SDK Version
static int GetSDKVersion();
// ch:枚举设备 | en:Enumerate Device
static int EnumDevices(unsigned int nTLayerType, MV_CC_DEVICE_INFO_LIST* pstDevList);
// ch:判断设备是否可达 | en:Is the device accessible
static bool IsDeviceAccessible(MV_CC_DEVICE_INFO* pstDevInfo, unsigned int nAccessMode);
// ch:打开设备 | en:Open Device
int Open(MV_CC_DEVICE_INFO* pstDeviceInfo);
// ch:关闭设备 | en:Close Device
int Close();
// ch:判断相机是否处于连接状态 | en:Is The Device Connected
bool IsDeviceConnected();
// ch:注册图像数据回调 | en:Register Image Data CallBack
int RegisterImageCallBack(void(__stdcall* cbOutput)(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), void* pUser);
// ch:开启抓图 | en:Start Grabbing
int StartGrabbing();
// ch:停止抓图 | en:Stop Grabbing
int StopGrabbing();
// ch:主动获取一帧图像数据 | en:Get one frame initiatively
int GetImageBuffer(MV_FRAME_OUT* pFrame, int nMsec);
// ch:释放图像缓存 | en:Free image buffer
int FreeImageBuffer(MV_FRAME_OUT* pFrame);
// ch:主动获取一帧图像数据 | en:Get one frame initiatively
int GetOneFrameTimeout(unsigned char* pData, unsigned int* pnDataLen, unsigned int nDataSize, MV_FRAME_OUT_INFO_EX* pFrameInfo, int nMsec);
// ch:显示一帧图像 | en:Display one frame image
int DisplayOneFrame(MV_DISPLAY_FRAME_INFO* pDisplayInfo);
// ch:设置SDK内部图像缓存节点个数 | en:Set the number of the internal image cache nodes in SDK
int SetImageNodeNum(unsigned int nNum);
// ch:获取设备信息 | en:Get device information
int GetDeviceInfo(MV_CC_DEVICE_INFO* pstDevInfo);
// ch:获取GEV相机的统计信息 | en:Get detect info of GEV camera
int GetGevAllMatchInfo(MV_MATCH_INFO_NET_DETECT* pMatchInfoNetDetect);
// ch:获取U3V相机的统计信息 | en:Get detect info of U3V camera
int GetU3VAllMatchInfo(MV_MATCH_INFO_USB_DETECT* pMatchInfoUSBDetect);
// ch:获取和设置Int型参数,如 Width和Height,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Int type parameters, such as Width and Height, for details please refer to MvCameraNode.xlsx file under SDK installation directory
//int GetIntValue(IN const char* strKey, OUT MVCC_INTVALUE_EX* pIntValue);
int GetIntValue(IN const char* strKey, OUT unsigned int* pnValue);
int SetIntValue(IN const char* strKey, IN int64_t nValue);
// ch:获取和设置Enum型参数,如 PixelFormat,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Enum type parameters, such as PixelFormat, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int GetEnumValue(IN const char* strKey, OUT MVCC_ENUMVALUE* pEnumValue);
int SetEnumValue(IN const char* strKey, IN unsigned int nValue);
int SetEnumValueByString(IN const char* strKey, IN const char* sValue);
// ch:获取和设置Float型参数,如 ExposureTime和Gain,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Float type parameters, such as ExposureTime and Gain, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int GetFloatValue(IN const char* strKey, OUT MVCC_FLOATVALUE* pFloatValue);
int SetFloatValue(IN const char* strKey, IN float fValue);
// ch:获取和设置Bool型参数,如 ReverseX,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Bool type parameters, such as ReverseX, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int GetBoolValue(IN const char* strKey, OUT bool* pbValue);
int SetBoolValue(IN const char* strKey, IN bool bValue);
// ch:获取和设置String型参数,如 DeviceUserID,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件UserSetSave
// en:Get String type parameters, such as DeviceUserID, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int GetStringValue(IN const char* strKey, MVCC_STRINGVALUE* pStringValue);
int SetStringValue(IN const char* strKey, IN const char* strValue);
// ch:执行一次Command型命令,如 UserSetSave,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Execute Command once, such as UserSetSave, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CommandExecute(IN const char* strKey);
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
int GetOptimalPacketSize(unsigned int* pOptimalPacketSize);
// ch:注册消息异常回调 | en:Register Message Exception CallBack
int RegisterExceptionCallBack(void(__stdcall* cbException)(unsigned int nMsgType, void* pUser), void* pUser);
// ch:注册单个事件回调 | en:Register Event CallBack
int RegisterEventCallBack(const char* pEventName, void(__stdcall* cbEvent)(MV_EVENT_OUT_INFO* pEventInfo, void* pUser), void* pUser);
// ch:强制IP | en:Force IP
int ForceIp(unsigned int nIP, unsigned int nSubNetMask, unsigned int nDefaultGateWay);
// ch:配置IP方式 | en:IP configuration method
int SetIpConfig(unsigned int nType);
// ch:设置网络传输模式 | en:Set Net Transfer Mode
int SetNetTransMode(unsigned int nType);
// ch:像素格式转换 | en:Pixel format conversion
int ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM* pstCvtParam);
// ch:保存图片 | en:save image
int SaveImage(MV_SAVE_IMAGE_PARAM_EX* pstParam);
// ch:保存图片为文件 | en:Save the image as a file
int SaveImageToFile(MV_SAVE_IMG_TO_FILE_PARAM* pstParam);
//设置是否为触发模式
int setTriggerMode(unsigned int TriggerModeNum);
//设置触发源
int setTriggerSource(unsigned int TriggerSourceNum);
//软触发
int softTrigger();
//读取buffer
int ReadBuffer(cv::Mat& image);
public:
void* m_hDevHandle;
unsigned int m_nTLayerType;
public:
unsigned char* m_pBufForSaveImage; // 用于保存图像的缓存
unsigned int m_nBufSizeForSaveImage;
unsigned char* m_pBufForDriver; // 用于从驱动获取图像的缓存
unsigned int m_nBufSizeForDriver;
};
#endif//_MV_CAMERA_H_
#pragma once
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include "QThread"
#include "MvCamera.h"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
using namespace std;
using namespace cv;
class MyThread :public QThread
{
Q_OBJECT
public:
MyThread();
~MyThread();
void run();
void getCameraPtr(CMvCamera* camera);
void getImagePtr(Mat* image);
void getCameraIndex(int index);
signals:
void mess();
void Display(const Mat* image, int index);
private:
CMvCamera* cameraPtr = NULL;
cv::Mat* imagePtr = NULL;
int cameraIndex = NULL;
int TriggerMode;
};
#endif // MYTHREAD_H
#pragma once
PcbDetectv3.h
#pragma once
#include <QtWidgets/QWidget>
#include <QMessageBox>
#include <QCloseEvent>
#include <QSettings>
#include <QDebug>
#include<opencv2\opencv.hpp>
#include<opencv2\dnn.hpp>
#include<fstream>
#include<iostream>
#include "MvCamera.h"
#include "mythread.h"
#include "ui_PcbDetectv3.h"
using namespace std;
using namespace cv;
using namespace cv::dnn;
#define MAX_DEVICE_NUM 2
class PcbDetectv3 : public QWidget
{
Q_OBJECT
public:
PcbDetectv3(QWidget *parent = Q_NULLPTR);
//~PcbDetectv3();
private:
Ui::PcbDetectv3Class ui;
public:
CMvCamera* m_pcMyCamera[MAX_DEVICE_NUM]; // 相机指针对象
MV_CC_DEVICE_INFO_LIST m_stDevList; // 设备信息列表结构体变量,用来存储设备列表
cv::Mat* myImage_L = new cv::Mat(); //用于保存左相机图像的图像指针对象
cv::Mat* myImage_R = new cv::Mat(); //用于保存右相机有图像的图像指针对象
int devices_num;//设备数量
/*ch:按下控件操作 | en:Control operation*/
/* 槽函数声明*/
private slots:
void OnBnClickedEnumButton(); // ch:按下查找设备按钮:枚举
void OnBnClickedOpenButton(); // ch:打开设备 | en:Open device
void OnBnClickedCloseButton(); // ch:关闭设备 | en:Close Devices
void Img_display(); // ch:Qlable 显示图像
void display_myImage_L(const Mat* imagePrt, int cameraIndex);
void display_myImage_R(const Mat* imagePrt, int cameraIndex);
/*ch:图像采集 | en:Image Acquisition*/
void OnBnClickedContinusModeRadio(); // ch:连续模式 | en:Continus Mode
void OnBnClickedTriggerModeRadio(); // ch:触发模式 | en:Trigger Mode
void OnBnClickedStartGrabbingButton(); // ch:开始采集 | en:Start Grabbing
void OnBnClickedStopGrabbingButton(); // ch:结束采集 | en:Stop Grabbing
void OnBnClickedSoftwareOnceButton(); // ch:软触发一次 | en:Software Trigger Execute Once
/*ch:图像保存 | en:Image Save*/
void OnBnClickedSaveBmpButton(); // ch:保存bmp | en:Save bmp
void OnBnClickedSaveJpgButton(); // ch:保存jpg | en:Save jpg
/*使用权重进行读取识别*/
void StartRecognize();
private:
void OpenDevices(); // ch:打开设备 | en:Open device
void CloseDevices(); // ch:关闭设备 | en:Close Device
public:
//MyThread* myThread; //线程对象
MyThread* myThread_LeftCamera = NULL; //左相机线程对象
MyThread* myThread_RightCamera = NULL; //右相机线程对象
//槽函数
private slots:
/*ch:设置、获取参数操作 | en:Set and get parameters operation*/
void SetTriggerMode(int m_nTriggerMode); // ch:设置触发模式 | en:Set Trigger Mode
int GetTriggerMode();
//void SetExposureTime(); // ch:设置曝光时间 | en:Set Exposure Time
int GetExposureTime();
//void SetGain(); // ch:设置增益 | en:Set Gain
int GetGain();
//void SetFrameRate(); // ch:设置帧率 | en:Set Frame Rate
int GetFrameRate();
/*ch:图片保存 | en:Save Image*/
void SaveImage(); // ch:保存图片 | en:Save Image
/*ch:自定义变量 | en:User Defined Variable*/
public:
/*ch:状态 | en:Status*/
bool m_bOpenDevice; // ch:是否打开设备 | en:Whether to open device
bool m_bStartGrabbing; // ch:是否开始抓图 | en:Whether to start grabbing
int m_nTriggerMode; // ch:触发模式 | en:Trigger Mode
int m_bContinueStarted; // 开启过连续采集图像
MV_SAVE_IAMGE_TYPE m_nSaveImageType; // ch:保存图像格式 | en:Save Image Type
};
main.cpp
#include "PcbDetectv3.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PcbDetectv3 w;
w.show();
return a.exec();
}
PcbDetectv3.cpp
#include "PcbDetectv3.h"
#include <QWidget>
#include <QValidator>
#define TRIGGER_SOURCE 7
#define EXPOSURE_TIME 40000
#define FRAME 30
#define TRIGGER_ON 1
#define TRIGGER_OFF 0
#define START_GRABBING_ON 1
#define START_GRABBING_OFF 0
#define IMAGE_NAME_LEN 64
PcbDetectv3::PcbDetectv3(QWidget *parent): QWidget(parent)
{
ui.setupUi(this);
/*按键使能初始化*/
// 相机初始化控件
ui.bntEnumDevices->setEnabled(true);
ui.bntCloseDevices->setEnabled(false);
ui.bntOpenDevices->setEnabled(false);
// 图像采集控件
ui.rbnt_Continue_Mode->setEnabled(false);
ui.rbnt_SoftTigger_Mode->setEnabled(false);
ui.bntStartGrabbing->setEnabled(false);
ui.bntStopGrabbing->setEnabled(false);
ui.bntSoftwareOnce->setEnabled(false);
// 保存图像控件
ui.bntSave_BMP->setEnabled(false);
ui.bntSave_JPG->setEnabled(false);
// 线程对象实例化
myThread_LeftCamera = new MyThread; //左相机线程对象
myThread_RightCamera = new MyThread; //右相机线程对象
// 图像指针实例化
myImage_L = new cv::Mat(); // 图像指针实例化
myImage_R = new cv::Mat(); // 图像指针实例化
// 初始化变量
int devices_num = 0;
int m_nTriggerMode = TRIGGER_ON;
int m_bStartGrabbing = START_GRABBING_ON;
int m_bContinueStarted = 0;
MV_SAVE_IAMGE_TYPE m_nSaveImageType = MV_Image_Bmp;
// 将线程的信号与槽进行绑定
connect(myThread_LeftCamera, SIGNAL(Display(const Mat*, int)), this, SLOT(display_myImage_L(const Mat*, int)));
connect(myThread_RightCamera, SIGNAL(Display(const Mat*, int)), this, SLOT(display_myImage_R(const Mat*, int)));
// 相机初始化
connect(ui.bntEnumDevices, SIGNAL(clicked()), this, SLOT(OnBnClickedEnumButton()));
connect(ui.bntOpenDevices, SIGNAL(clicked()), this, SLOT(OnBnClickedOpenButton()));
connect(ui.bntCloseDevices, SIGNAL(clicked()), this, SLOT(OnBnClickedCloseButton()));
// 图像采集
connect(ui.rbnt_Continue_Mode, SIGNAL(clicked()), this, SLOT(OnBnClickedContinusModeRadio()));
connect(ui.rbnt_SoftTigger_Mode, SIGNAL(clicked()), this, SLOT(OnBnClickedTriggerModeRadio()));
connect(ui.bntStartGrabbing, SIGNAL(clicked()), this, SLOT(OnBnClickedStartGrabbingButton()));
connect(ui.bntStopGrabbing, SIGNAL(clicked()), this, SLOT(OnBnClickedStopGrabbingButton()));
connect(ui.bntSoftwareOnce, SIGNAL(clicked()), this, SLOT(OnBnClickedSoftwareOnceButton()));
connect(ui.bntSave_BMP, SIGNAL(clicked()), this, SLOT(OnBnClickedSaveBmpButton()));
connect(ui.bntSave_JPG, SIGNAL(clicked()), this, SLOT(OnBnClickedSaveJpgButton()));
}
/*************************************************** 定义槽函数 *************************************************** */
// ch:按下查找设备按钮:枚举 | en:Click Find Device button:Enumeration
void PcbDetectv3::OnBnClickedEnumButton()
{
memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); // ch:初始化设备信息列表
int nRet = MV_OK;
nRet = CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList); // ch:枚举子网内所有设备,相机设备数量
devices_num = m_stDevList.nDeviceNum;
if (devices_num > 0)
{
ui.bntOpenDevices->setEnabled(true);// 设备数大于0,使能打开设备按键
}
}
// 打开相机,开启相机
void PcbDetectv3::OpenDevices()
{
int nRet = MV_OK;
// 创建相机指针对象
for (unsigned int i = 0, j = 0; j < m_stDevList.nDeviceNum; j++, i++)
{
m_pcMyCamera[i] = new CMvCamera;
// 相机对象初始化
m_pcMyCamera[i]->m_pBufForDriver = NULL;
m_pcMyCamera[i]->m_pBufForSaveImage = NULL;
m_pcMyCamera[i]->m_nBufSizeForDriver = 0;
m_pcMyCamera[i]->m_nBufSizeForSaveImage = 0;
m_pcMyCamera[i]->m_nTLayerType = m_stDevList.pDeviceInfo[j]->nTLayerType;
nRet = m_pcMyCamera[i]->Open(m_stDevList.pDeviceInfo[j]); //打开相机
//设置触发模式
m_pcMyCamera[i]->setTriggerMode(TRIGGER_ON);
//设置触发源为软触发
m_pcMyCamera[i]->setTriggerSource(TRIGGER_SOURCE);
}
void PcbDetectv3::OnBnClickedOpenButton()
{
// 使能 "开始采集" 按键
//ui->bntStartGrabbing->setEnabled(true);
ui.bntOpenDevices->setEnabled(false);
ui.bntCloseDevices->setEnabled(true);
ui.rbnt_Continue_Mode->setEnabled(true);
ui.rbnt_SoftTigger_Mode->setEnabled(true);
ui.rbnt_Continue_Mode->setCheckable(true);
OpenDevices();
}
// ch:关闭设备 | en:Close Device
void PcbDetectv3::CloseDevices()
{
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++)
{
// 关闭线程、相机
if (myThread_LeftCamera->isRunning())
{
myThread_LeftCamera->requestInterruption();
myThread_LeftCamera->wait();
m_pcMyCamera[0]->StopGrabbing();
//myThread_LeftCamera->~MyThread();// 销毁线程
}
if (myThread_RightCamera->isRunning())
{
myThread_RightCamera->requestInterruption();
myThread_RightCamera->wait();
m_pcMyCamera[1]->StopGrabbing();
}
m_pcMyCamera[i]->Close();
}
// ch:关闭之后再枚举一遍 | en:Enumerate after close
memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); // ch:初始化设备信息列表
int devices_num = MV_OK;
devices_num = CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList); // ch:枚举子网内所有设备,相机设备数量
}
// ch:按下关闭设备按钮:关闭设备 ,包含销毁句柄| en:Click Close button: Close Device
void PcbDetectv3::OnBnClickedCloseButton()
{
ui.bntOpenDevices->setEnabled(true);
ui.bntCloseDevices->setEnabled(false);
// 图像采集控件
ui.rbnt_Continue_Mode->setEnabled(false);
ui.rbnt_SoftTigger_Mode->setEnabled(false);
ui.bntStartGrabbing->setEnabled(false);
ui.bntStopGrabbing->setEnabled(false);
// 保存图像控件
ui.bntSave_BMP->setEnabled(false);
ui.bntSave_JPG->setEnabled(false);
// 关闭设备,销毁线程
CloseDevices();
}
// 开始连续采集图像
void PcbDetectv3::OnBnClickedStartGrabbingButton()
{
m_bContinueStarted = 1; // 为触发模式标记一下,切换触发模式时先执行停止采集图像函数
// 图像采集控件
ui.bntStartGrabbing->setEnabled(false);
ui.bntStopGrabbing->setEnabled(true);
// 保存图像控件
ui.bntSave_BMP->setEnabled(true);
ui.bntSave_JPG->setEnabled(true);
int camera_Index = 0;
// 先判断什么模式,再判断是否正在采集
if (m_nTriggerMode == TRIGGER_ON)
{
// ch:开始采集之后才创建workthread线程 | en:Create workthread after start grabbing
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++)
{
//开启相机采集
m_pcMyCamera[i]->StartGrabbing();
camera_Index = i;
if (camera_Index == 0)
{
myThread_LeftCamera->getCameraPtr(m_pcMyCamera[0]); //线程获取左相机指针
myThread_LeftCamera->getImagePtr(myImage_L); //线程获取左图像指针
myThread_LeftCamera->getCameraIndex(0); //左相机 Index==0
if (!myThread_LeftCamera->isRunning())
{
myThread_LeftCamera->start();
m_pcMyCamera[0]->softTrigger();
m_pcMyCamera[0]->ReadBuffer(*myImage_L);//读取Mat格式的图像
}
}
if (camera_Index == 1)
{
myThread_RightCamera->getCameraPtr(m_pcMyCamera[1]); //线程获取右相机指针
myThread_RightCamera->getImagePtr(myImage_R); //线程获取右图像指针
myThread_RightCamera->getCameraIndex(1); //右相机 Index==1
if (!myThread_RightCamera->isRunning())
{
myThread_RightCamera->start();
m_pcMyCamera[1]->softTrigger();
m_pcMyCamera[1]->ReadBuffer(*myImage_R);//读取Mat格式的图像
}
}
}
}
}
// ch:按下结束采集按钮 | en:Click Stop button
void PcbDetectv3::OnBnClickedStopGrabbingButton()
{
ui.bntStartGrabbing->setEnabled(true);
ui.bntStopGrabbing->setEnabled(false);
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++)
{
//关闭相机
if (myThread_LeftCamera->isRunning())
{
m_pcMyCamera[0]->StopGrabbing();
myThread_LeftCamera->requestInterruption();
myThread_LeftCamera->wait();
}
if (myThread_RightCamera->isRunning())
{
m_pcMyCamera[1]->StopGrabbing();
myThread_RightCamera->requestInterruption();
myThread_RightCamera->wait();
}
}
}
void PcbDetectv3::Img_display()
{
}
void PcbDetectv3::display_myImage_L(const Mat* imagePrt, int cameraIndex)
{
cv::Mat rgb;
cv::cvtColor(*imagePrt, rgb, CV_BGR2RGB);
判断是黑白、彩色图像
QImage QmyImage_L;
if (myImage_L->channels() > 1)
{
QmyImage_L = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_RGB888);
}
else
{
QmyImage_L = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_Indexed8);
}
QmyImage_L = (QmyImage_L).scaled(ui.label_camera_display->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
//显示图像
ui.label_camera_display->setPixmap(QPixmap::fromImage(QmyImage_L));
}
void PcbDetectv3::display_myImage_R(const Mat* imagePrt, int cameraIndex)
{
cv::Mat rgb;
cv::cvtColor(*imagePrt, rgb, CV_BGR2RGB);
判断是黑白、彩色图像
QImage QmyImage_R;
if (myImage_R->channels() > 1)
{
QmyImage_R = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_RGB888);
}
else
{
QmyImage_R = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_Indexed8);
}
QmyImage_R = (QmyImage_R).scaled(ui.label_detect_display->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
//显示图像
ui.label_detect_display->setPixmap(QPixmap::fromImage(QmyImage_R));
}
// ch:获取曝光时间 | en:Get Exposure Time
int PcbDetectv3::GetExposureTime(void)
{
int i = 0;
return i;
}
// ch:获取增益 | en:Get Gain
int PcbDetectv3::GetGain(void)
{
int i = 0;
return i;
}
// ch:获取帧率 | en:Get Frame Rate
int PcbDetectv3::GetFrameRate(void)
{
int i = 0;
return i;
}
// ch:获取触发模式 | en:Get Trigger Mode
int PcbDetectv3::GetTriggerMode(void)
{
int i = 0;
return 0;
}
// ch:设置触发模式 | en:Set Trigger Mode
void PcbDetectv3::SetTriggerMode(int m_nTriggerMode)
{
}
// ch:按下连续模式按钮 | en:Click Continues button
void PcbDetectv3::OnBnClickedContinusModeRadio()
{
ui.bntStartGrabbing->setEnabled(true);
m_nTriggerMode = TRIGGER_ON;
}
// ch:按下触发模式按钮 | en:Click Trigger Mode button
void PcbDetectv3::OnBnClickedTriggerModeRadio()
{
if (m_bContinueStarted == 1) // 从连续采集模式已经正在采集的状态切换过来
{
OnBnClickedStopGrabbingButton();//先执行停止采集
}
ui.bntStartGrabbing->setEnabled(false);
ui.bntSoftwareOnce->setEnabled(true);
m_nTriggerMode = TRIGGER_OFF;
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++)
{
m_pcMyCamera[i]->setTriggerMode(m_nTriggerMode);
//ui.label_Real_fps->setText("000");
}
}
// ch:按下软触发一次按钮 | en:Click Execute button
void PcbDetectv3::OnBnClickedSoftwareOnceButton()
{
// 保存图像控件
ui.bntSave_BMP->setEnabled(true);
ui.bntSave_JPG->setEnabled(true);
if (m_nTriggerMode == TRIGGER_OFF)
{
int nRet = MV_OK;
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++)
{
//开启相机采集
m_pcMyCamera[i]->StartGrabbing();
if (i == 0)
{
nRet = m_pcMyCamera[i]->CommandExecute("TriggerSoftware");
m_pcMyCamera[i]->ReadBuffer(*myImage_L);
display_myImage_L(myImage_L, i);//左相机图像
//m_pcMyCamera[i]->StopGrabbing();
}
if (i == 1)
{
//开启相机采集
nRet = m_pcMyCamera[i]->CommandExecute("TriggerSoftware");
m_pcMyCamera[i]->ReadBuffer(*myImage_R);
display_myImage_R(myImage_R, i);
//m_pcMyCamera[i]->StopGrabbing();
}
}
}
}
// ch:按下保存bmp图片按钮 | en:Click Save BMP button
void PcbDetectv3::OnBnClickedSaveBmpButton()
{
m_nSaveImageType = MV_Image_Bmp;
SaveImage();
}
// ch:按下保存jpg图片按钮 | en:Click Save JPG button
void PcbDetectv3::OnBnClickedSaveJpgButton()
{
m_nSaveImageType = MV_Image_Jpeg;
SaveImage();
}
// ch:保存图片 | en:Save Image
void PcbDetectv3::SaveImage()
{
// ch:获取1张图 | en:Get one frame
MV_FRAME_OUT_INFO_EX stImageInfo = {
0 };
memset(&stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));
unsigned int nDataLen = 0;
int nRet = MV_OK;
for (int i = 0; i < devices_num; i++)
{
// ch:仅在第一次保存图像时申请缓存,在 CloseDevice 时释放
// en:Request buffer first time save image, release after CloseDevice
if (NULL == m_pcMyCamera[i]->m_pBufForDriver)
{
unsigned int nRecvBufSize = 0;
unsigned int nRet = m_pcMyCamera[i]->GetIntValue("PayloadSize", &nRecvBufSize);
m_pcMyCamera[i]->m_nBufSizeForDriver = nRecvBufSize; // 一帧数据大小
m_pcMyCamera[i]->m_pBufForDriver = (unsigned char*)malloc(m_pcMyCamera[i]->m_nBufSizeForDriver);
}
nRet = m_pcMyCamera[i]->GetOneFrameTimeout(m_pcMyCamera[i]->m_pBufForDriver, &nDataLen, m_pcMyCamera[i]->m_nBufSizeForDriver, &stImageInfo, 1000);
if (MV_OK == nRet)
{
// ch:仅在第一次保存图像时申请缓存,在 CloseDevice 时释放
// en:Request buffer first time save image, release after CloseDevice
if (NULL == m_pcMyCamera[i]->m_pBufForSaveImage)
{
// ch:BMP图片大小:width * height * 3 + 2048(预留BMP头大小)
// en:BMP image size: width * height * 3 + 2048 (Reserved BMP header size)
m_pcMyCamera[i]->m_nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
m_pcMyCamera[i]->m_pBufForSaveImage = (unsigned char*)malloc(m_pcMyCamera[i]->m_nBufSizeForSaveImage);
}
// ch:设置对应的相机参数 | en:Set camera parameter
MV_SAVE_IMAGE_PARAM_EX stParam = {
0 };
stParam.enImageType = m_nSaveImageType; // ch:需要保存的图像类型 | en:Image format to save;
stParam.enPixelType = stImageInfo.enPixelType; // 相机对应的像素格式 | en:Pixel format
stParam.nBufferSize = m_pcMyCamera[i]->m_nBufSizeForSaveImage; // 存储节点的大小 | en:Buffer node size
stParam.nWidth = stImageInfo.nWidth; // 相机对应的宽 | en:Width
stParam.nHeight = stImageInfo.nHeight; // 相机对应的高 | en:Height
stParam.nDataLen = stImageInfo.nFrameLen;
stParam.pData = m_pcMyCamera[i]->m_pBufForDriver;
stParam.pImageBuffer = m_pcMyCamera[i]->m_pBufForSaveImage;
stParam.nJpgQuality = 90; // ch:jpg编码,仅在保存Jpg图像时有效。保存BMP时SDK内忽略该参数
nRet = m_pcMyCamera[i]->SaveImage(&stParam);
char chImageName[IMAGE_NAME_LEN] = {
0 };
if (MV_Image_Bmp == stParam.enImageType)
{
if (i == 0)
{
/*sprintf_s(chImageName, IMAGE_NAME_LEN, "Image_w%d_h%d_fn%03d_L.bmp", stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);*/
//sprintf_s(chImageName, IMAGE_NAME_LEN, "%03d_L.bmp", stImageInfo.nFrameNum);
sprintf_s(chImageName, IMAGE_NAME_LEN, "current_image.bmp", stImageInfo.nFrameNum);
}
if (i == 1)
{
//sprintf_s(chImageName, IMAGE_NAME_LEN, "%03d_R.bmp", stImageInfo.nFrameNum);
sprintf_s(chImageName, IMAGE_NAME_LEN, "Image_w%d_h%d_fn%03d_R.bmp", stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);
}
}
else if (MV_Image_Jpeg == stParam.enImageType)
{
if (i == 0)
{
//sprintf_s(chImageName, IMAGE_NAME_LEN, "Image_w%d_h%d_fn%03d_L.bmp", stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);
sprintf_s(chImageName, IMAGE_NAME_LEN, "current_image.bmp", stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);
}
if (i == 1)
{
sprintf_s(chImageName, IMAGE_NAME_LEN, "Image_w%d_h%d_fn%03d_R.bmp", stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);
}
}
FILE* fp = fopen(chImageName, "wb");
fwrite(m_pcMyCamera[i]->m_pBufForSaveImage, 1, stParam.nImageLen, fp);
//ui->label_debug->setText("save imgs");
fclose(fp);
}
}
}
/*目标识别*/
// 使用权重进行读取识别
void PcbDetectv3::StartRecognize()
{
//---------------------------------------加载类别---------------------------------------
ifstream classNamesFile("./model/classes.names"); //ifstream默认以输入方式打开文件
vector<string> classNamesVec;
if (classNamesFile.is_open())
{
string className = "";
while (std::getline(classNamesFile, className))
classNamesVec.push_back(className);
}
//---------------------------------------模型设置---------------------------------------
String cfg = "./model/yolo-obj.cfg";
String weight = "./model/yolo-obj_4000.weights";
//模型读入
dnn::Net net = readNetFromDarknet(cfg, weight);
//预处理读取的图像,并将图像读入网络
Mat frame = imread("./current_image.bmp");
//imshow("src", frame);
Mat inputBlob = blobFromImage(frame, 1.0 / 255, Size(608, 608), Scalar());
net.setInput(inputBlob);
//获取未连接输出层
std::vector<String> outNames = net.getUnconnectedOutLayersNames();
std::vector<Mat> outs;
net.forward(outs, outNames);
//---------------------------------------目标检测---------------------------------------
//需要的变量
float* data;
Mat scores;
vector<Rect> boxes;
vector<int> classIds;
vector<float> confidences;
int centerX, centerY, width, height, left, top;
float confidenceThreshold = 0.2; // 置信度设置
double confidence;
Point classIdPoint;
//找出所有的目标及其位置
for (size_t i = 0; i < outs.size(); ++i)
{
data = (float*)outs[i].data;
for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols)
{
scores = outs[i].row(j).colRange(5, outs[i].cols);
minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);
//minMaxLoc(src, minVal, maxVal, minLoc, maxLoc, mask)在一个数组中找到全局最小值和全局最大值
if (confidence > confidenceThreshold)
{
centerX = (int)(data[0] * frame.cols);
centerY = (int)(data[1] * frame.rows);
width = (int)(data[2] * frame.cols);
height = (int)(data[3] * frame.rows);
left = centerX - width / 2;
top = centerY - height / 2;
classIds.push_back(classIdPoint.x);
confidences.push_back((float)confidence);
boxes.push_back(Rect(left, top, width, height));
}
}
}
vector<int> indices;
NMSBoxes(boxes, confidences, 0.3, 0.2, indices);
//---------------------------------------效果展示---------------------------------------
Scalar rectColor, textColor; //box 和 text 的颜色
Rect box, textBox;
int idx; //类别索引
String className;
Size labelSize;
QString show_text;
show_text = QString::fromLocal8Bit("当前图像的尺寸:"); // QString与string的转化,解决中文乱码问题
//show_text = "The pixel size of the current image: ";
show_text.append(QString::number(frame.size().width)); //将int转换成QString
show_text.append(QString::fromLocal8Bit("×"));
show_text.append(QString::number(frame.size().height));
show_text.append("\n");
cout << "当前图像的尺寸:" << frame.size() << endl;
for (size_t i = 0; i < indices.size(); ++i)
{
idx = indices[i];
className = classNamesVec[classIds[idx]];
labelSize = getTextSize(className, FONT_HERSHEY_SIMPLEX, 0.5, 1, 0);
box = boxes[idx];
textBox = Rect(Point(box.x - 1, box.y),
Point(box.x + labelSize.width, box.y - labelSize.height));
rectColor = Scalar(idx * 11 % 256, idx * 22 % 256, idx * 33 % 256);
textColor = Scalar(255 - idx * 11 % 256, 255 - idx * 22 % 256, 255 - idx * 33 % 256);
rectangle(frame, box, rectColor, 20, 8, 0); // 20表示线宽
rectangle(frame, textBox, rectColor, -1, 8, 0);
putText(frame, className.c_str(), Point(box.x, box.y - 2), FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, 8);
// API参考:https://blog.csdn.net/KYJL888/article/details/82217192
cout << className << ":" << "width:" << box.width << ",height:" << box.height << ",center:" << (box.tl() + box.br()) / 2 << endl;
show_text.append(QString::fromLocal8Bit(className.c_str())); //string转化成Qstring类型
show_text.append(": width:");
show_text.append(QString::number(box.width));
show_text.append(", height:");
show_text.append(QString::number(box.height));
show_text.append(", center:");
int center_x = (box.tl().x + box.br().x) / 2;
show_text.append(QString::number(center_x));
show_text.append(",");
int center_y = (box.tl().y + box.br().y) / 2;
show_text.append(QString::number(center_y));
show_text.append("\n");
}
ui.label_show_results->setText(show_text);
//imshow("dst", frame);
//imwrite("test.bmp", frame); // 保存图像
Mat show_detect_img;
cvtColor(frame, show_detect_img, COLOR_BGR2RGB); // 图像格式转换
QImage disImage = QImage((const unsigned char*)(show_detect_img.data), show_detect_img.cols, show_detect_img.rows, QImage::Format_RGB888);
ui.label_detect_display->setPixmap(QPixmap::fromImage(disImage.scaled(ui.label_detect_display->size(), Qt::KeepAspectRatio)));
}
MvCamera.cpp
#include "MvCamera.h"
#include <opencv.hpp>
#include"opencv2/opencv.hpp"
#include"opencv2/imgproc/types_c.h"
CMvCamera::CMvCamera()
{
m_hDevHandle = MV_NULL;
}
CMvCamera::~CMvCamera()
{
if (m_hDevHandle)
{
MV_CC_DestroyHandle(m_hDevHandle);
m_hDevHandle = MV_NULL;
}
}
// ch:获取SDK版本号 | en:Get SDK Version
int CMvCamera::GetSDKVersion()
{
return MV_CC_GetSDKVersion();
}
// ch:枚举设备 | en:Enumerate Device
int CMvCamera::EnumDevices(unsigned int nTLayerType, MV_CC_DEVICE_INFO_LIST* pstDevList)
{
return MV_CC_EnumDevices(nTLayerType, pstDevList);
}
// ch:判断设备是否可达 | en:Is the device accessible
bool CMvCamera::IsDeviceAccessible(MV_CC_DEVICE_INFO* pstDevInfo, unsigned int nAccessMode)
{
return MV_CC_IsDeviceAccessible(pstDevInfo, nAccessMode);
}
// ch:打开设备 | en:Open Device
int CMvCamera::Open(MV_CC_DEVICE_INFO* pstDeviceInfo)
{
if (MV_NULL == pstDeviceInfo)
{
return MV_E_PARAMETER;
}
if (m_hDevHandle)
{
return MV_E_CALLORDER;
}
int nRet = MV_CC_CreateHandle(&m_hDevHandle, pstDeviceInfo);
if (MV_OK != nRet)
{
return nRet;
}
nRet = MV_CC_OpenDevice(m_hDevHandle);
if (MV_OK != nRet)
{
MV_CC_DestroyHandle(m_hDevHandle);
m_hDevHandle = MV_NULL;
}
return nRet;
}
// ch:关闭设备 | en:Close Device
int CMvCamera::Close()
{
if (MV_NULL == m_hDevHandle)
{
return MV_E_HANDLE;
}
MV_CC_CloseDevice(m_hDevHandle);
int nRet = MV_CC_DestroyHandle(m_hDevHandle);
m_hDevHandle = MV_NULL;
return nRet;
}
// ch:判断相机是否处于连接状态 | en:Is The Device Connected
bool CMvCamera::IsDeviceConnected()
{
return MV_CC_IsDeviceConnected(m_hDevHandle);
}
// ch:注册图像数据回调 | en:Register Image Data CallBack
int CMvCamera::RegisterImageCallBack(void(__stdcall* cbOutput)(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), void* pUser)
{
return MV_CC_RegisterImageCallBackEx(m_hDevHandle, cbOutput, pUser);
}
// ch:开启抓图 | en:Start Grabbing
int CMvCamera::StartGrabbing()
{
return MV_CC_StartGrabbing(m_hDevHandle);
}
// ch:停止抓图 | en:Stop Grabbing
int CMvCamera::StopGrabbing()
{
return MV_CC_StopGrabbing(m_hDevHandle);
}
// ch:主动获取一帧图像数据 | en:Get one frame initiatively
int CMvCamera::GetImageBuffer(MV_FRAME_OUT* pFrame, int nMsec)
{
return MV_CC_GetImageBuffer(m_hDevHandle, pFrame, nMsec);
}
// ch:释放图像缓存 | en:Free image buffer
int CMvCamera::FreeImageBuffer(MV_FRAME_OUT* pFrame)
{
return MV_CC_FreeImageBuffer(m_hDevHandle, pFrame);
}
// ch:主动获取一帧图像数据 | en:Get one frame initiatively
int CMvCamera::GetOneFrameTimeout(unsigned char* pData, unsigned int* pnDataLen, unsigned int nDataSize, MV_FRAME_OUT_INFO_EX* pFrameInfo, int nMsec)
{
if (NULL == pnDataLen)
{
return MV_E_PARAMETER;
}
int nRet = MV_OK;
*pnDataLen = 0;
nRet = MV_CC_GetOneFrameTimeout(m_hDevHandle, pData, nDataSize, pFrameInfo, nMsec);
if (MV_OK != nRet)
{
return nRet;
}
*pnDataLen = pFrameInfo->nFrameLen;
return nRet;
}
// ch:设置显示窗口句柄 | en:Set Display Window Handle
int CMvCamera::DisplayOneFrame(MV_DISPLAY_FRAME_INFO* pDisplayInfo)
{
return MV_CC_DisplayOneFrame(m_hDevHandle, pDisplayInfo);
}
// ch:设置SDK内部图像缓存节点个数 | en:Set the number of the internal image cache nodes in SDK
int CMvCamera::SetImageNodeNum(unsigned int nNum)
{
return MV_CC_SetImageNodeNum(m_hDevHandle, nNum);
}
// ch:获取设备信息 | en:Get device information
int CMvCamera::GetDeviceInfo(MV_CC_DEVICE_INFO* pstDevInfo)
{
return MV_CC_GetDeviceInfo(m_hDevHandle, pstDevInfo);
}
// ch:获取GEV相机的统计信息 | en:Get detect info of GEV camera
int CMvCamera::GetGevAllMatchInfo(MV_MATCH_INFO_NET_DETECT* pMatchInfoNetDetect)
{
if (MV_NULL == pMatchInfoNetDetect)
{
return MV_E_PARAMETER;
}
MV_CC_DEVICE_INFO stDevInfo = {
0 };
GetDeviceInfo(&stDevInfo);
if (stDevInfo.nTLayerType != MV_GIGE_DEVICE)
{
return MV_E_SUPPORT;
}
MV_ALL_MATCH_INFO struMatchInfo = {
0 };
struMatchInfo.nType = MV_MATCH_TYPE_NET_DETECT;
struMatchInfo.pInfo = pMatchInfoNetDetect;
struMatchInfo.nInfoSize = sizeof(MV_MATCH_INFO_NET_DETECT);
memset(struMatchInfo.pInfo, 0, sizeof(MV_MATCH_INFO_NET_DETECT));
return MV_CC_GetAllMatchInfo(m_hDevHandle, &struMatchInfo);
}
// ch:获取U3V相机的统计信息 | en:Get detect info of U3V camera
int CMvCamera::GetU3VAllMatchInfo(MV_MATCH_INFO_USB_DETECT* pMatchInfoUSBDetect)
{
if (MV_NULL == pMatchInfoUSBDetect)
{
return MV_E_PARAMETER;
}
MV_CC_DEVICE_INFO stDevInfo = {
0 };
GetDeviceInfo(&stDevInfo);
if (stDevInfo.nTLayerType != MV_USB_DEVICE)
{
return MV_E_SUPPORT;
}
MV_ALL_MATCH_INFO struMatchInfo = {
0 };
struMatchInfo.nType = MV_MATCH_TYPE_USB_DETECT;
struMatchInfo.pInfo = pMatchInfoUSBDetect;
struMatchInfo.nInfoSize = sizeof(MV_MATCH_INFO_USB_DETECT);
memset(struMatchInfo.pInfo, 0, sizeof(MV_MATCH_INFO_USB_DETECT));
return MV_CC_GetAllMatchInfo(m_hDevHandle, &struMatchInfo);
}
// ch:获取和设置Int型参数,如 Width和Height,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Int type parameters, such as Width and Height, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetIntValue(IN const char* strKey, OUT unsigned int* pnValue)
{
if (NULL == strKey || NULL == pnValue)
{
return MV_E_PARAMETER;
}
MVCC_INTVALUE stParam;
memset(&stParam, 0, sizeof(MVCC_INTVALUE));
int nRet = MV_CC_GetIntValue(m_hDevHandle, strKey, &stParam);
if (MV_OK != nRet)
{
return nRet;
}
*pnValue = stParam.nCurValue;
return MV_OK;
}
int CMvCamera::SetIntValue(IN const char* strKey, IN int64_t nValue)
{
return MV_CC_SetIntValueEx(m_hDevHandle, strKey, nValue);
}
// ch:获取和设置Enum型参数,如 PixelFormat,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Enum type parameters, such as PixelFormat, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetEnumValue(IN const char* strKey, OUT MVCC_ENUMVALUE* pEnumValue)
{
return MV_CC_GetEnumValue(m_hDevHandle, strKey, pEnumValue);
}
int CMvCamera::SetEnumValue(IN const char* strKey, IN unsigned int nValue)
{
return MV_CC_SetEnumValue(m_hDevHandle, strKey, nValue);
}
int CMvCamera::SetEnumValueByString(IN const char* strKey, IN const char* sValue)
{
return MV_CC_SetEnumValueByString(m_hDevHandle, strKey, sValue);
}
// ch:获取和设置Float型参数,如 ExposureTime和Gain,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Float type parameters, such as ExposureTime and Gain, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetFloatValue(IN const char* strKey, OUT MVCC_FLOATVALUE* pFloatValue)
{
return MV_CC_GetFloatValue(m_hDevHandle, strKey, pFloatValue);
}
int CMvCamera::SetFloatValue(IN const char* strKey, IN float fValue)
{
return MV_CC_SetFloatValue(m_hDevHandle, strKey, fValue);
}
// ch:获取和设置Bool型参数,如 ReverseX,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Bool type parameters, such as ReverseX, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetBoolValue(IN const char* strKey, OUT bool* pbValue)
{
return MV_CC_GetBoolValue(m_hDevHandle, strKey, pbValue);
}
int CMvCamera::SetBoolValue(IN const char* strKey, IN bool bValue)
{
return MV_CC_SetBoolValue(m_hDevHandle, strKey, bValue);
}
// ch:获取和设置String型参数,如 DeviceUserID,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件UserSetSave
// en:Get String type parameters, such as DeviceUserID, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::GetStringValue(IN const char* strKey, MVCC_STRINGVALUE* pStringValue)
{
return MV_CC_GetStringValue(m_hDevHandle, strKey, pStringValue);
}
int CMvCamera::SetStringValue(IN const char* strKey, IN const char* strValue)
{
return MV_CC_SetStringValue(m_hDevHandle, strKey, strValue);
}
// ch:执行一次Command型命令,如 UserSetSave,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Execute Command once, such as UserSetSave, for details please refer to MvCameraNode.xlsx file under SDK installation directory
int CMvCamera::CommandExecute(IN const char* strKey)
{
return MV_CC_SetCommandValue(m_hDevHandle, strKey);
}
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
int CMvCamera::GetOptimalPacketSize(unsigned int* pOptimalPacketSize)
{
if (MV_NULL == pOptimalPacketSize)
{
return MV_E_PARAMETER;
}
int nRet = MV_CC_GetOptimalPacketSize(m_hDevHandle);
if (nRet < MV_OK)
{
return nRet;
}
*pOptimalPacketSize = (unsigned int)nRet;
return MV_OK;
}
// ch:注册消息异常回调 | en:Register Message Exception CallBack
int CMvCamera::RegisterExceptionCallBack(void(__stdcall* cbException)(unsigned int nMsgType, void* pUser), void* pUser)
{
return MV_CC_RegisterExceptionCallBack(m_hDevHandle, cbException, pUser);
}
// ch:注册单个事件回调 | en:Register Event CallBack
int CMvCamera::RegisterEventCallBack(const char* pEventName, void(__stdcall* cbEvent)(MV_EVENT_OUT_INFO* pEventInfo, void* pUser), void* pUser)
{
return MV_CC_RegisterEventCallBackEx(m_hDevHandle, pEventName, cbEvent, pUser);
}
// ch:强制IP | en:Force IP
int CMvCamera::ForceIp(unsigned int nIP, unsigned int nSubNetMask, unsigned int nDefaultGateWay)
{
return MV_GIGE_ForceIpEx(m_hDevHandle, nIP, nSubNetMask, nDefaultGateWay);
}
// ch:配置IP方式 | en:IP configuration method
int CMvCamera::SetIpConfig(unsigned int nType)
{
return MV_GIGE_SetIpConfig(m_hDevHandle, nType);
}
// ch:设置网络传输模式 | en:Set Net Transfer Mode
int CMvCamera::SetNetTransMode(unsigned int nType)
{
return MV_GIGE_SetNetTransMode(m_hDevHandle, nType);
}
// ch:像素格式转换 | en:Pixel format conversion
int CMvCamera::ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM* pstCvtParam)
{
return MV_CC_ConvertPixelType(m_hDevHandle, pstCvtParam);
}
// ch:保存图片 | en:save image
int CMvCamera::SaveImage(MV_SAVE_IMAGE_PARAM_EX* pstParam)
{
return MV_CC_SaveImageEx2(m_hDevHandle, pstParam);
}
// ch:保存图片为文件 | en:Save the image as a file
int CMvCamera::SaveImageToFile(MV_SAVE_IMG_TO_FILE_PARAM* pstSaveFileParam)
{
return MV_CC_SaveImageToFile(m_hDevHandle, pstSaveFileParam);
}
//设置是否为触发模式
int CMvCamera::setTriggerMode(unsigned int TriggerModeNum)
{
//0:Off 1:On
int tempValue = MV_CC_SetEnumValue(m_hDevHandle, "TriggerMode", TriggerModeNum);
if (tempValue != 0){
return -1;
}
else {
return 0;
}
}
//设置触发源
int CMvCamera::setTriggerSource(unsigned int TriggerSourceNum)
{
//0:Line0 1:Line1 7:Software
int tempValue = MV_CC_SetEnumValue(m_hDevHandle, "TriggerSource", TriggerSourceNum);
if (tempValue != 0) {
return -1;
}
else {
return 0;
}
}
// ************************************************************************************************
//发送软触发
int CMvCamera::softTrigger()
{
int tempValue = MV_CC_SetCommandValue(m_hDevHandle, "TriggerSoftware");
if (tempValue != 0)
{
return -1;
}
else
{
return 0;
}
}
//读取相机中的图像
//int ReadBuffer(cv::Mat &image);
//读取相机中的图像
int CMvCamera::ReadBuffer(cv::Mat& image)
{
cv::Mat* getImage = new cv::Mat();
unsigned int nRecvBufSize = 0;
MVCC_INTVALUE stParam;
memset(&stParam, 0, sizeof(MVCC_INTVALUE));
int tempValue = MV_CC_GetIntValue(m_hDevHandle, "PayloadSize", &stParam);
if (tempValue != 0)
{
return -1;
}
nRecvBufSize = stParam.nCurValue;
unsigned char* pDate;
pDate = (unsigned char*)malloc(nRecvBufSize);
MV_FRAME_OUT_INFO_EX stImageInfo = {
0 };
tempValue = MV_CC_GetOneFrameTimeout(m_hDevHandle, pDate, nRecvBufSize, &stImageInfo, 500);
if (tempValue != 0)
{
return -1;
}
m_nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
unsigned char* m_pBufForSaveImage;
m_pBufForSaveImage = (unsigned char*)malloc(m_nBufSizeForSaveImage);
bool isMono;
switch (stImageInfo.enPixelType)
{
case PixelType_Gvsp_Mono8:
case PixelType_Gvsp_Mono10:
case PixelType_Gvsp_Mono10_Packed:
case PixelType_Gvsp_Mono12:
case PixelType_Gvsp_Mono12_Packed:
isMono = true;
break;
default:
isMono = false;
break;
}
if (isMono)
{
*getImage = cv::Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC1, pDate);
//imwrite("d:\\测试opencv_Mono.tif", image);
}
else
{
//转换图像格式为BGR8
MV_CC_PIXEL_CONVERT_PARAM stConvertParam = {
0 };
memset(&stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));
stConvertParam.nWidth = stImageInfo.nWidth; //ch:图像宽 | en:image width
stConvertParam.nHeight = stImageInfo.nHeight; //ch:图像高 | en:image height
//stConvertParam.pSrcData = m_pBufForDriver; //ch:输入数据缓存 | en:input data buffer
stConvertParam.pSrcData = pDate; //ch:输入数据缓存 | en:input data buffer
stConvertParam.nSrcDataLen = stImageInfo.nFrameLen; //ch:输入数据大小 | en:input data size
stConvertParam.enSrcPixelType = stImageInfo.enPixelType; //ch:输入像素格式 | en:input pixel format
stConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed; //ch:输出像素格式 | en:output pixel format 适用于OPENCV的图像格式
//stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed; //ch:输出像素格式 | en:output pixel format
stConvertParam.pDstBuffer = m_pBufForSaveImage; //ch:输出数据缓存 | en:output data buffer
stConvertParam.nDstBufferSize = m_nBufSizeForSaveImage; //ch:输出缓存大小 | en:output buffer size
MV_CC_ConvertPixelType(m_hDevHandle, &stConvertParam);
*getImage = cv::Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC3, m_pBufForSaveImage);
}
(*getImage).copyTo(image);
(*getImage).release();
free(pDate);
free(m_pBufForSaveImage);
return 0;
}
mythread.cpp
#include "mythread.h"
MyThread::MyThread()
{
}
MyThread::~MyThread()
{
terminate();
if (cameraPtr != NULL)
{
delete cameraPtr;
}
if (imagePtr != NULL)
{
delete imagePtr;
}
}
void MyThread::getCameraPtr(CMvCamera* camera)
{
cameraPtr = camera;
}
void MyThread::getImagePtr(Mat* image)
{
imagePtr = image;
}
void MyThread::getCameraIndex(int index)
{
cameraIndex = index;
}
//void MyThread::get_TriggerMode(int m_nTriggerMode)
//{
// TriggerMode = m_nTriggerMode;
//}
void MyThread::run()
{
if (cameraPtr == NULL){
return;
}
if (imagePtr == NULL){
return;
}
while (!isInterruptionRequested())
{
std::cout << "Thread_Trigger:" << cameraPtr->softTrigger() << std::endl;
std::cout << "Thread_Readbuffer:" << cameraPtr->ReadBuffer(*imagePtr) << std::endl;
/*emit mess();*/
emit Display(imagePtr, cameraIndex);//发送信号 img_display_label接收并显示
msleep(30);
}
}
效果
(因为放假回家相机没带回来,这里只看下界面效果)
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/201362.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...