first commit
This commit is contained in:
commit
67366dffd1
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.vs/
|
||||
x64/
|
||||
QtWidget.DFE02648/
|
||||
29
M_camera.cpp
Normal file
29
M_camera.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "M_camera.h"
|
||||
|
||||
M_camera::M_camera(QObject* parent)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
M_camera::~M_camera()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//死循环,一直获取图像
|
||||
void M_camera::do_start() {
|
||||
|
||||
system = System::GetInstance();//新建相机系统
|
||||
camList = system->GetCameras();//获取相机列表
|
||||
const unsigned int numCameras = camList.GetSize();//获取相机数目
|
||||
cout << "Number of cameras detected: " << numCameras << endl << endl;
|
||||
pCam = camList.GetByIndex(0);//相机实例化,由于只有一个相机,因此相机index为0
|
||||
pCam->Init();//相机初始化
|
||||
pCam->BeginAcquisition();//开始采集图像
|
||||
while (1) {
|
||||
pResultImage = pCam->GetNextImage();
|
||||
pResultImage = processor.Convert(pResultImage, PixelFormat_RGB8);
|
||||
emit img_redy(pResultImage);
|
||||
}
|
||||
}
|
||||
41
M_camera.h
Normal file
41
M_camera.h
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <Spinnaker.h>
|
||||
#include <SpinGenApi/SpinnakerGenApi.h>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
|
||||
using namespace Spinnaker;
|
||||
using namespace Spinnaker::GenApi;
|
||||
using namespace Spinnaker::GenICam;
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
class M_camera : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
M_camera(QObject* parent);
|
||||
~M_camera();
|
||||
|
||||
SystemPtr system;
|
||||
CameraList camList;
|
||||
CameraPtr pCam = nullptr;
|
||||
Mat frame;
|
||||
ImageProcessor processor;
|
||||
ImagePtr pResultImage;
|
||||
|
||||
public slots:
|
||||
void do_start();
|
||||
|
||||
signals:
|
||||
|
||||
void img_redy(ImagePtr pResultImage);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
199
Mycontrol.cpp
Normal file
199
Mycontrol.cpp
Normal file
@ -0,0 +1,199 @@
|
||||
#include "Mycontrol.h"
|
||||
|
||||
|
||||
Mycontrol::Mycontrol()
|
||||
{
|
||||
}
|
||||
|
||||
// 获取单例实例(C++11 线程安全)
|
||||
Mycontrol& Mycontrol::getInstance() {
|
||||
static Mycontrol instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void Mycontrol::init() {
|
||||
volatile int result = 0;
|
||||
// Init vars
|
||||
int ioin_count = 0, motor_count = 0, connect_rebuild = 1;
|
||||
|
||||
// Load config file
|
||||
wchar_t path[] = L"D:\\Program Files\\demo\\glass.csv";
|
||||
result = XT_Controler_Extend::Profile_Load(path);
|
||||
if (result == 1) {
|
||||
qDebug() << "XTSystem - Init: Profile_Load succeed!";
|
||||
}
|
||||
else {
|
||||
qDebug() << "XTSystem - Init: Profile_Load failed!";
|
||||
return;
|
||||
}
|
||||
|
||||
// Init controller
|
||||
//XT_Controler_Extend::Profile_DeInit_Controller();
|
||||
//qDebug() << "Do deinit controller";
|
||||
result = XT_Controler_Extend::Profile_Init_Controller(1);
|
||||
qDebug() << "XTSystem - Init: Do init controller";
|
||||
if (result == 1) {
|
||||
qDebug() << "XTSystem - Init: Profile_Init_Controller succeed!";
|
||||
|
||||
ioin_count = XT_Controler_Extend::Profile_Get_IoIn_Count();
|
||||
motor_count = XT_Controler_Extend::Profile_Get_Axis_Count();
|
||||
connect_rebuild = 0;
|
||||
|
||||
qDebug() << "XTSystem - Init:ioin_count: " << ioin_count << ", "
|
||||
<< "motor_count: " << motor_count << ", "
|
||||
<< "connect_rebuild: " << connect_rebuild;
|
||||
}
|
||||
else {
|
||||
qDebug() << "XTSystem - Init: Profile_Init_Controller failed!";
|
||||
return;
|
||||
}
|
||||
|
||||
// Init 3 axis motors
|
||||
VCM_Resource_struct xtMotorsResources[3];
|
||||
xtMotorsResources[0].CanID = 1;
|
||||
xtMotorsResources[0].iAxis = motor_count + 1;
|
||||
xtMotorsResources[0].Connet_Rebuild = connect_rebuild;
|
||||
xtMotorsResources[0].IO_ID = ioin_count + 3 * 0;
|
||||
xtMotorsResources[0].iThread = 2;
|
||||
xtMotorsResources[0].iThread_Curve = 3;
|
||||
xtMotorsResources[0].Z_Index_ID = -1;
|
||||
xtMotorsResources[0].IO_CAN_ID = 4;
|
||||
xtMotorsResources[0].Extren_IO_Index = 0;
|
||||
|
||||
xtMotorsResources[1].CanID = 2;
|
||||
xtMotorsResources[1].iAxis = motor_count + 2;
|
||||
xtMotorsResources[1].Connet_Rebuild = connect_rebuild;
|
||||
xtMotorsResources[1].IO_ID = ioin_count + 3 * 1;
|
||||
xtMotorsResources[1].iThread = 5;
|
||||
xtMotorsResources[1].iThread_Curve = 6;
|
||||
xtMotorsResources[1].Z_Index_ID = -1;
|
||||
xtMotorsResources[1].IO_CAN_ID = 4;
|
||||
xtMotorsResources[1].Extren_IO_Index = 1;
|
||||
|
||||
xtMotorsResources[2].CanID = 3;
|
||||
xtMotorsResources[2].iAxis = motor_count + 3;
|
||||
xtMotorsResources[2].Connet_Rebuild = connect_rebuild;
|
||||
xtMotorsResources[2].IO_ID = ioin_count + 3 * 2;
|
||||
xtMotorsResources[2].iThread = 8;
|
||||
xtMotorsResources[2].iThread_Curve = 9;
|
||||
xtMotorsResources[2].Z_Index_ID = -1;
|
||||
xtMotorsResources[2].IO_CAN_ID = 4;
|
||||
xtMotorsResources[2].Extren_IO_Index = 2;
|
||||
|
||||
VCMT_resource_alloc(xtMotorsResources, 3);
|
||||
|
||||
// 初始化音圈控制端
|
||||
result = Soft_landing_dll_init(3);
|
||||
if (result == 1) {
|
||||
qDebug() << "XTSystem - Init:Soft_landing_dll_init succeed!";
|
||||
}
|
||||
else {
|
||||
qDebug() << "XTSystem - Init:Soft_landing_dll_init failed!";
|
||||
}
|
||||
|
||||
// 获取电机状态
|
||||
result = Get_Init_Ready();
|
||||
if (result == -1) {
|
||||
qDebug() << "XTSystem - Init:Motors not exist!";
|
||||
}
|
||||
else if (result == 0) {
|
||||
qDebug() << "XTSystem - Init:Motors busy!";
|
||||
}
|
||||
else {
|
||||
qDebug() << "XTSystem - Init:Motors init succeed!";
|
||||
}
|
||||
|
||||
// 电机使能
|
||||
SetServoOnOff(1, true);
|
||||
SetServoOnOff(2, true);
|
||||
SetServoOnOff(3, true);
|
||||
QThread::msleep(1000);
|
||||
qDebug() << "XTSystem - Init:Servos enable succeed!";
|
||||
|
||||
// 配置三轴参数,motor_id =3, 1, 2 对应 z, y, x
|
||||
SetPosModejerk(3, 500000);
|
||||
SetPosModeAcc(3, 50);
|
||||
SetPosModeSpeed(3, 15);
|
||||
SetGoZeroSpeed(3, 10);
|
||||
SetGoZeroDistance(3, 20);
|
||||
SetRunDirect(3, 0, 20000);
|
||||
|
||||
if (Init_Go_Zero(3, 1)) {
|
||||
qDebug() << "XTsystem - init: Z axis go zero succeed!";
|
||||
}
|
||||
|
||||
SetPosModejerk(1, 500000);
|
||||
SetPosModeAcc(1, 50);
|
||||
SetPosModeSpeed(1, 15);
|
||||
SetGoZeroSpeed(1, 10);
|
||||
SetGoZeroDistance(1, 500);
|
||||
SetRunDirect(1, 0, 10000);
|
||||
|
||||
if (Init_Go_Zero(1, 1)) {
|
||||
qDebug() << "XTsystem - init: Y axis go zero succeed!";
|
||||
}
|
||||
|
||||
SetPosModejerk(2, 500000);
|
||||
SetPosModeAcc(2, 5);
|
||||
SetPosModeSpeed(2, 15);
|
||||
SetGoZeroSpeed(2, 10);
|
||||
SetGoZeroDistance(2, 500);
|
||||
SetRunDirect(2, 1, 10000);
|
||||
|
||||
if (Init_Go_Zero(2, 1)) {
|
||||
qDebug() << "XTsystem - init: x axis go zero succeed!";
|
||||
}
|
||||
|
||||
|
||||
qDebug() << QString("XTSystem: init() called");
|
||||
|
||||
}
|
||||
|
||||
void Mycontrol::moveBy(int motorID, double distance, int block) {
|
||||
qDebug() << QString("Mycontrol: moveBy(motorID=%1, distance=%2, block=%3)")
|
||||
.arg(motorID).arg(distance).arg(block);
|
||||
double nowPosition = 0.0;
|
||||
GetNowPos(motorID, nowPosition);
|
||||
SetPosModePos(motorID, nowPosition + distance);
|
||||
TillPosModePos(motorID, block);
|
||||
}
|
||||
|
||||
void Mycontrol::moveTo(int motorID, double targetPosition, int block) {
|
||||
qDebug() << QString("Mycontrol: moveTo(motorID=%1, targetPosition=%2, block=%3)")
|
||||
.arg(motorID).arg(targetPosition).arg(block);
|
||||
SetPosModePos(motorID, targetPosition);
|
||||
TillPosModePos(motorID, block);
|
||||
}
|
||||
|
||||
void Mycontrol::moveByX(double xDis) {
|
||||
moveBy(2, xDis);
|
||||
}
|
||||
|
||||
void Mycontrol::moveByY(double yDis) {
|
||||
moveBy(1, yDis);
|
||||
}
|
||||
|
||||
void Mycontrol::moveByZ(double zDis) {
|
||||
moveBy(3, zDis);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
double Mycontrol::getXPos() const {
|
||||
double xPos;
|
||||
GetNowPos(2, xPos);
|
||||
return xPos;
|
||||
}
|
||||
|
||||
double Mycontrol::getYPos() const {
|
||||
double yPos;
|
||||
GetNowPos(1, yPos);
|
||||
return yPos;
|
||||
}
|
||||
|
||||
double Mycontrol::getZPos() const {
|
||||
double zPos;
|
||||
GetNowPos(3, zPos);
|
||||
return zPos;
|
||||
}
|
||||
40
Mycontrol.h
Normal file
40
Mycontrol.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QVector>
|
||||
#include <QDebug>
|
||||
#include <QQueue>
|
||||
#include <QMutex>
|
||||
|
||||
#include <C_SoftLanding_dll.h>
|
||||
#include <VCM_init_Struct.h>
|
||||
#include <XT_MotionControlerExtend_Client_Lib.h>
|
||||
|
||||
|
||||
|
||||
class Mycontrol : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Mycontrol(); // 私有构造函数
|
||||
Mycontrol(const Mycontrol&) = delete;
|
||||
Mycontrol& operator=(const Mycontrol&) = delete;
|
||||
|
||||
public:
|
||||
static Mycontrol& getInstance(); // 获取单例实例
|
||||
void init(); // 初始化 XT 控制系统
|
||||
void moveBy(int motorID, double distance, int block = 0); // 按距离移动,distance 参数单位为 um
|
||||
void moveTo(int motorID, double targetPosition, int block = 0); // 按坐标移动,targetPosition 参数单位为 mm
|
||||
|
||||
// 分轴移动接口
|
||||
void moveByX(double xDis); // 按距离移动 X 轴,左正右负
|
||||
void moveByY(double yDis); // 按距离移动 Y 轴,前正后负
|
||||
void moveByZ(double zDis); // 按距离移动 Z 轴,下正上负
|
||||
double getXPos() const; // 返回 X 轴当前位置(单位:mm)
|
||||
double getYPos() const; // 返回 Y 轴当前位置(单位:mm)
|
||||
double getZPos() const; // 返回 Z 轴当前位置(单位:mm)
|
||||
public slots:
|
||||
|
||||
};
|
||||
419
QtWidgetsApplication.cpp
Normal file
419
QtWidgetsApplication.cpp
Normal file
@ -0,0 +1,419 @@
|
||||
#include "QtWidgetsApplication.h"
|
||||
|
||||
QtWidgetsApplication::QtWidgetsApplication(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
|
||||
ui.setupUi(this);
|
||||
// 获取 控制系统 单例并初始化
|
||||
Mycontrol::getInstance().init();
|
||||
|
||||
//相机需要的显示控件
|
||||
m_scene = new QGraphicsScene(this);
|
||||
ui.imgView->setScene(m_scene);
|
||||
|
||||
//保存路径
|
||||
ui.edtSaveDir->setText("D:/");
|
||||
//TCT检测显示需要
|
||||
tct_pixmapItem = new QGraphicsPixmapItem(tct_pixmap);
|
||||
tct_scene = new QGraphicsScene(this);
|
||||
tct_scene->addItem(tct_pixmapItem);
|
||||
|
||||
//TCT模型处理的线程
|
||||
my_TCT = new TCT(this);
|
||||
m_infQthread = new QThread(nullptr);
|
||||
my_TCT->moveToThread(m_infQthread);
|
||||
|
||||
//TCT模型处理需要的信号与槽
|
||||
connect(this, &QtWidgetsApplication::emit_img, my_TCT, &TCT::main_module);
|
||||
connect(my_TCT, &TCT::em_img, this, &QtWidgetsApplication::input_img);
|
||||
m_infQthread->start();
|
||||
|
||||
//定时器定时获取当前位置
|
||||
QTimer* timer = new QTimer(this);
|
||||
timer->setInterval(50); // 设置定时器间隔为 50 毫秒
|
||||
timer->setSingleShot(false); // 非单次触发,持续运行
|
||||
connect(timer, &QTimer::timeout, [this]() {
|
||||
Mycontrol& Mycontrol = Mycontrol::getInstance();
|
||||
ui.m_xpos->setValue(Mycontrol::getInstance().getXPos());
|
||||
ui.m_ypos->setValue(Mycontrol::getInstance().getYPos());
|
||||
ui.m_zpos->setValue(Mycontrol::getInstance().getZPos());
|
||||
});
|
||||
timer->start();
|
||||
}
|
||||
|
||||
QtWidgetsApplication::~QtWidgetsApplication()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//选择相机
|
||||
void QtWidgetsApplication::on_pb_camera_clicked() {
|
||||
|
||||
QString currentText = ui.CameraBox->currentText(); // 获取文本
|
||||
if (currentText == "haikang camera")
|
||||
{
|
||||
// 创建相机线程,和信号与槽
|
||||
cam_thread = new QThread(this);
|
||||
Hacm_worker = new haikang(this);
|
||||
Hacm_worker->moveToThread(cam_thread);
|
||||
connect(cam_thread, &QThread::started, Hacm_worker, &haikang::GrabThreadProcess);
|
||||
//connect(Hacm_worker, &haikang::img_redy, this, &QtWidgetsApplication::do_hai_img_redy); //弃用
|
||||
m_hwndDisplay = (HWND)ui.imgView->winId();//弃用
|
||||
connect(cam_thread, &QThread::finished, Hacm_worker, &haikang::finish);
|
||||
connect(Hacm_worker, &haikang::img_to, this, &QtWidgetsApplication::hai_img_redy);
|
||||
cam_thread->start();
|
||||
setSlideSpinboxCheckboxSync();
|
||||
}
|
||||
if (currentText == "flir camera")
|
||||
{
|
||||
|
||||
qRegisterMetaType<ImagePtr>("ImagePtr");
|
||||
// 创建相机线程,和信号与槽
|
||||
cam_thread = new QThread(this);
|
||||
cam_worker = new M_camera(nullptr);
|
||||
cam_worker->moveToThread(cam_thread);
|
||||
connect(cam_thread, &QThread::started, cam_worker, &M_camera::do_start);//线程开始,让相机初始化
|
||||
connect(cam_worker, &M_camera::img_redy, this, &QtWidgetsApplication::do_img_redy);
|
||||
cam_thread->start();
|
||||
//让曝光,增益的Slide和Spinbox同步
|
||||
setSlideSpinboxCheckboxSync();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 将海康相机传回来的图片进行显示
|
||||
void QtWidgetsApplication::hai_img_redy(QImage image, void* handle)
|
||||
{
|
||||
hikimage = image; //往tct里面送的时候用
|
||||
HK_handle = handle; //相机句柄
|
||||
m_scene->clear(); // 清除旧图像
|
||||
QPixmap pixmap = QPixmap::fromImage(image);
|
||||
pixmapItem = m_scene->addPixmap(pixmap);
|
||||
|
||||
ui.imgView->fitInView(pixmapItem, Qt::KeepAspectRatio);
|
||||
ui.imgView->setScene(m_scene);
|
||||
ui.imgView->show();
|
||||
}
|
||||
|
||||
//将海康相机传回来的图片进行显示 //SB处理办法
|
||||
void QtWidgetsApplication::do_hai_img_redy(MV_FRAME_OUT stImageInfo, void *handle)
|
||||
{
|
||||
//HK_handle = handle;
|
||||
//MV_DISPLAY_FRAME_INFO stDisplayInfo = {0};
|
||||
//stDisplayInfo.hWnd = m_hwndDisplay; //显示的句柄 这种显示方式相当于绑定句柄
|
||||
//stDisplayInfo.pData = stImageInfo.pBufAddr;
|
||||
//stDisplayInfo.nDataLen = stImageInfo.stFrameInfo.nFrameLen;
|
||||
//stDisplayInfo.nWidth = stImageInfo.stFrameInfo.nWidth;
|
||||
//stDisplayInfo.nHeight = stImageInfo.stFrameInfo.nHeight;
|
||||
//stDisplayInfo.enPixelType = stImageInfo.stFrameInfo.enPixelType;
|
||||
//MV_CC_DisplayOneFrame(handle, &stDisplayInfo);
|
||||
//MV_CC_FreeImageBuffer(handle, &stImageInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//将flir相机传回来的图片进行显示
|
||||
void QtWidgetsApplication::do_img_redy(ImagePtr pResultImage)
|
||||
{
|
||||
const size_t width = pResultImage->GetWidth();
|
||||
const size_t height = pResultImage->GetHeight();
|
||||
const unsigned char* pData = (const unsigned char*)pResultImage->GetData();
|
||||
// 根据像素格式创建 QImage
|
||||
QImage qImage(pData, static_cast<int>(width), static_cast<int>(height),
|
||||
static_cast<int>(width * pResultImage->GetBitsPerPixel() / 8),
|
||||
QImage::Format_RGB888); // 根据实际情况调整格式
|
||||
|
||||
m_scene->clear(); // 清除旧图像
|
||||
QPixmap pixmap = QPixmap::fromImage(qImage);
|
||||
pixmapItem = m_scene->addPixmap(pixmap);
|
||||
|
||||
ui.imgView->fitInView(pixmapItem, Qt::KeepAspectRatio);
|
||||
ui.imgView->setScene(m_scene);
|
||||
ui.imgView->show();
|
||||
}
|
||||
|
||||
|
||||
int QtWidgetsApplication::resetExposure() {
|
||||
|
||||
Spinnaker::GenApi::INodeMap& nodeMap = cam_worker->pCam->GetNodeMap();
|
||||
|
||||
CEnumerationPtr exposureAuto = nodeMap.GetNode("ExposureAuto");
|
||||
exposureAuto->SetIntValue(exposureAuto->GetEntryByName("Continuous")->GetValue());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int QtWidgetsApplication::configureExposure(double exposure) {
|
||||
|
||||
Spinnaker::GenApi::INodeMap& nodeMap = cam_worker->pCam->GetNodeMap();
|
||||
|
||||
CEnumerationPtr exposureAuto = nodeMap.GetNode("ExposureAuto");
|
||||
exposureAuto->SetIntValue(exposureAuto->GetEntryByName("Off")->GetValue());
|
||||
|
||||
CEnumerationPtr exposureMode = nodeMap.GetNode("ExposureMode");
|
||||
exposureMode->SetIntValue(exposureMode->GetEntryByName("Timed")->GetValue());
|
||||
|
||||
CFloatPtr exposureTime = nodeMap.GetNode("ExposureTime");
|
||||
exposureTime->SetValue(exposure);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void QtWidgetsApplication::setSlideSpinboxCheckboxSync() {
|
||||
QString currentText = ui.CameraBox->currentText();
|
||||
if (currentText == "flir camera") {
|
||||
// Exposure
|
||||
connect(ui.sldExposure, &QSlider::valueChanged, ui.spinExposure, [this](int sliderValue) {
|
||||
ui.spinExposure->setValue(static_cast<double>(sliderValue));
|
||||
});
|
||||
connect(ui.spinExposure, QOverload<double>::of(&QDoubleSpinBox::valueChanged), ui.sldExposure, [this](double spinValue) {
|
||||
ui.sldExposure->setValue(static_cast<int>(spinValue));
|
||||
configureExposure(spinValue);
|
||||
});
|
||||
connect(ui.chkExposure, &QCheckBox::toggled, [this](bool checked) {
|
||||
bool isEnabled = !checked;
|
||||
ui.spinExposure->setEnabled(isEnabled);
|
||||
ui.sldExposure->setEnabled(isEnabled);
|
||||
resetExposure();
|
||||
});
|
||||
|
||||
// Gain
|
||||
connect(ui.sldGain, &QSlider::valueChanged, ui.spinGain, [this](int sliderValue) {
|
||||
ui.spinGain->setValue(static_cast<double>(sliderValue) / 100.0);
|
||||
});
|
||||
connect(ui.spinGain, QOverload<double>::of(&QDoubleSpinBox::valueChanged), ui.sldGain, [this](double spinValue) {
|
||||
ui.sldGain->setValue(static_cast<int>(spinValue * 100));
|
||||
configureGain(spinValue);
|
||||
});
|
||||
connect(ui.chkGain, &QCheckBox::toggled, [this](bool checked) {
|
||||
bool isEnabled = !checked;
|
||||
ui.spinGain->setEnabled(isEnabled);
|
||||
ui.sldGain->setEnabled(isEnabled);
|
||||
resetGain();
|
||||
});
|
||||
}
|
||||
if (currentText =="haikang camera") {
|
||||
// Exposure
|
||||
connect(ui.sldExposure, &QSlider::valueChanged, ui.spinExposure, [this](int sliderValue) {
|
||||
ui.spinExposure->setValue(static_cast<double>(sliderValue));
|
||||
});
|
||||
connect(ui.spinExposure, QOverload<double>::of(&QDoubleSpinBox::valueChanged), ui.sldExposure, [this](double spinValue) {
|
||||
ui.sldExposure->setValue(static_cast<int>(spinValue));
|
||||
HK_configureExposure(spinValue);
|
||||
});
|
||||
connect(ui.chkExposure, &QCheckBox::toggled, [this](bool checked) {
|
||||
bool isEnabled = !checked;
|
||||
ui.spinExposure->setEnabled(isEnabled);
|
||||
ui.sldExposure->setEnabled(isEnabled);
|
||||
HK_resetExposure();
|
||||
});
|
||||
|
||||
// Gain
|
||||
connect(ui.sldGain, &QSlider::valueChanged, ui.spinGain, [this](int sliderValue) {
|
||||
ui.spinGain->setValue(static_cast<double>(sliderValue) / 100.0);
|
||||
});
|
||||
connect(ui.spinGain, QOverload<double>::of(&QDoubleSpinBox::valueChanged), ui.sldGain, [this](double spinValue) {
|
||||
ui.sldGain->setValue(static_cast<int>(spinValue * 100));
|
||||
HK_configureGain(spinValue);
|
||||
});
|
||||
connect(ui.chkGain, &QCheckBox::toggled, [this](bool checked) {
|
||||
bool isEnabled = !checked;
|
||||
ui.spinGain->setEnabled(isEnabled);
|
||||
ui.sldGain->setEnabled(isEnabled);
|
||||
HK_resetGain();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QtWidgetsApplication::HK_resetGain() {
|
||||
|
||||
|
||||
MV_CC_SetExposureAutoMode(HK_handle, 2);
|
||||
|
||||
}
|
||||
|
||||
void QtWidgetsApplication::HK_resetExposure()
|
||||
{
|
||||
MV_CC_SetGain(HK_handle, 2);
|
||||
}
|
||||
|
||||
void QtWidgetsApplication::HK_configureExposure(double exposure)
|
||||
{
|
||||
MV_CC_SetFloatValue(HK_handle, "ExposureTime", exposure);
|
||||
}
|
||||
|
||||
void QtWidgetsApplication::HK_configureGain(double gain)
|
||||
{
|
||||
MV_CC_SetFloatValue(HK_handle, "Gain", gain);
|
||||
}
|
||||
|
||||
int QtWidgetsApplication::configureGain(double gain) {
|
||||
Spinnaker::GenApi::INodeMap& nodeMap = cam_worker->pCam->GetNodeMap();
|
||||
|
||||
CEnumerationPtr gainAuto = nodeMap.GetNode("GainAuto");
|
||||
gainAuto->SetIntValue(gainAuto->GetEntryByName("Off")->GetValue());
|
||||
|
||||
CFloatPtr gainValue = nodeMap.GetNode("Gain");
|
||||
gainValue->SetValue(gain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QtWidgetsApplication::resetGain() {
|
||||
Spinnaker::GenApi::INodeMap& nodeMap = cam_worker->pCam->GetNodeMap();
|
||||
|
||||
CEnumerationPtr gainAuto = nodeMap.GetNode("GainAuto");
|
||||
gainAuto->SetIntValue(gainAuto->GetEntryByName("Continuous")->GetValue());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//单张图片的保存
|
||||
void QtWidgetsApplication::on_btnSingleImageSave_clicked() {
|
||||
|
||||
QString currentText = ui.CameraBox->currentText();
|
||||
if (currentText == "flir camera") {
|
||||
qDebug() << "Single image save clicked";
|
||||
QString fileName = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
|
||||
QString absPath = ui.edtSaveDir->text() + "/" + fileName + ".tif";
|
||||
qDebug() << "Save path: " << absPath << "";
|
||||
|
||||
ImagePtr pImage = cam_worker->pCam->GetNextImage(1000);
|
||||
if (pImage->IsIncomplete()) {
|
||||
qDebug() << "Image incomplete in 1s: " << Image::GetImageStatusDescription(pImage->GetImageStatus()) << "...";
|
||||
}
|
||||
ImagePtr pConvertedImage = processor.Convert(pImage, PixelFormat_RGB8);
|
||||
pConvertedImage->Save(absPath.toStdString().c_str());
|
||||
}
|
||||
if (currentText == "haikang camera") {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//选择保存路径
|
||||
void QtWidgetsApplication::on_btnSaveDir_clicked() {
|
||||
qDebug() << "Choose save dir clicked";
|
||||
QString dirPath = QFileDialog::getExistingDirectory(
|
||||
this,
|
||||
QString::fromUtf8(u8"请选择图像保存路径")
|
||||
);
|
||||
qDebug() << "Choose save dir: " << dirPath << "";
|
||||
ui.edtSaveDir->setText(dirPath);
|
||||
}
|
||||
|
||||
|
||||
// 将TCT检测的图片进行显示
|
||||
void QtWidgetsApplication::input_img(QImage image)
|
||||
{
|
||||
in_image = image;
|
||||
// 显示经过网络检测后的图片
|
||||
this->ui.TCT_View->setScene(tct_scene);
|
||||
tct_pixmap = QPixmap::fromImage(in_image);
|
||||
tct_pixmapItem = tct_scene->addPixmap(tct_pixmap);
|
||||
// 自适应显示图片
|
||||
ui.TCT_View->fitInView(tct_pixmapItem, Qt::KeepAspectRatio);
|
||||
ui.TCT_View->setRenderHint(QPainter::Antialiasing); // 抗锯齿
|
||||
ui.TCT_View->setDragMode(QGraphicsView::ScrollHandDrag); // 启动手动拖动模式
|
||||
ui.TCT_View->show();
|
||||
}
|
||||
|
||||
// 将ImagePtr转换成QImage
|
||||
QImage convertToQImage(const ImagePtr& pImage)
|
||||
{
|
||||
// 获取图像尺寸
|
||||
int width = pImage->GetWidth();
|
||||
int height = pImage->GetHeight();
|
||||
|
||||
// 获取像素数据指针(假设为 uchar* 类型)
|
||||
const uchar* pData = reinterpret_cast<const uchar*>(pImage->GetData());
|
||||
|
||||
// 获取每行的字节数(步长)
|
||||
int stride = width * 3; // 假设存在此方法,若不存在可设为 width * 3
|
||||
|
||||
// 构造 QImage
|
||||
QImage qImage(pData, width, height, stride, QImage::Format_RGB888);
|
||||
|
||||
// 返回深拷贝,避免原始图像数据被释放导致 QImage 无效
|
||||
return qImage.copy();
|
||||
}
|
||||
|
||||
// 将相机图片输入到网络的线程中
|
||||
void QtWidgetsApplication::on_pb_model_clicked()
|
||||
{
|
||||
/*QString fileName = QFileDialog::getOpenFileName(this, "选择图片", "D:/TCT_down/dataset/test/images", "Images (*.png *.jpg)");
|
||||
QImage image(fileName);*/
|
||||
QString currentText = ui.CameraBox->currentText();
|
||||
if (currentText == "flir camera") {
|
||||
ImagePtr pImage = cam_worker->pCam->GetNextImage(1000);
|
||||
if (pImage->IsIncomplete()) {
|
||||
qDebug() << "Image incomplete in 1s: " << Image::GetImageStatusDescription(pImage->GetImageStatus()) << "...";
|
||||
}
|
||||
ImagePtr pConvertedImage = processor.Convert(pImage, PixelFormat_RGB8);
|
||||
QImage image = convertToQImage(pConvertedImage);
|
||||
emit emit_img(image);
|
||||
}
|
||||
if (currentText == "haikang camera") {
|
||||
|
||||
emit emit_img(hikimage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 运动控制
|
||||
void QtWidgetsApplication::on_btnUp_clicked() {
|
||||
double zdis = ui.spinZDis->value();
|
||||
qDebug() << "up clicked, move up: " << zdis << "um";
|
||||
Mycontrol::getInstance().moveBy(3, zdis * -1e-3);
|
||||
}
|
||||
|
||||
void QtWidgetsApplication::on_btnDown_clicked() {
|
||||
double zdis = ui.spinZDis->value();
|
||||
qDebug() << "up clicked, move up: " << zdis << "um";
|
||||
Mycontrol::getInstance().moveBy(3, -zdis * -1e-3);
|
||||
}
|
||||
|
||||
void QtWidgetsApplication::on_btnLeft_clicked() {
|
||||
double xdis = ui.spinXDis->value();
|
||||
qDebug() << "up clicked, move up: " << xdis << "um";
|
||||
Mycontrol::getInstance().moveBy(2, -xdis * -1e-3);
|
||||
}
|
||||
|
||||
void QtWidgetsApplication::on_btnRight_clicked() {
|
||||
double xdis = ui.spinXDis->value();
|
||||
qDebug() << "up clicked, move up: " << xdis << "um";
|
||||
Mycontrol::getInstance().moveBy(2, xdis * -1e-3);
|
||||
}
|
||||
|
||||
void QtWidgetsApplication::on_btnForward_clicked() {
|
||||
double ydis = ui.spinYDis->value();
|
||||
qDebug() << "up clicked, move up: " << ydis << "um";
|
||||
Mycontrol::getInstance().moveBy(1, -ydis * -1e-3);
|
||||
}
|
||||
|
||||
void QtWidgetsApplication::on_btnBackward_clicked() {
|
||||
double ydis = ui.spinYDis->value();
|
||||
qDebug() << "up clicked, move up: " << ydis << "um";
|
||||
Mycontrol::getInstance().moveBy(1, ydis * -1e-3);
|
||||
}
|
||||
|
||||
|
||||
double sharpnessSobel(cv::Mat image) {
|
||||
cv::Mat roi = image(cv::Rect(968, 768, 512, 512));
|
||||
cv::Mat gray;
|
||||
cv::cvtColor(roi, gray, cv::COLOR_BGR2GRAY);
|
||||
cv::GaussianBlur(gray, gray, cv::Size(5, 5), 0);
|
||||
cv::Mat sobelx, sobely;
|
||||
cv::Sobel(gray, sobelx, CV_64F, 1, 0, 3);
|
||||
cv::Sobel(gray, sobely, CV_64F, 0, 1, 3);
|
||||
cv::Mat magnitude;
|
||||
cv::magnitude(sobelx, sobely, magnitude);
|
||||
return cv::mean(magnitude)[0];
|
||||
}
|
||||
98
QtWidgetsApplication.h
Normal file
98
QtWidgetsApplication.h
Normal file
@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
#include <QThread>
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include "ui_QtWidgetsApplication.h"
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <QTimer.h>
|
||||
#include <Spinnaker.h>
|
||||
#include <SpinGenApi/SpinnakerGenApi.h>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "M_camera.h"
|
||||
#include "TCT.h"
|
||||
#include <QSlider>
|
||||
#include <QCheckBox>
|
||||
#include <QDateTime>
|
||||
#include <QFileDialog>
|
||||
#include "haikang.h"
|
||||
#include "Mycontrol.h"
|
||||
|
||||
|
||||
class QtWidgetsApplication : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtWidgetsApplication(QWidget *parent = nullptr);
|
||||
|
||||
~QtWidgetsApplication();
|
||||
|
||||
int resetExposure(); // filr自动曝光
|
||||
|
||||
int configureExposure(double exposure); //设置曝光
|
||||
|
||||
void setSlideSpinboxCheckboxSync(); //让曝光,增益的Slide和Spinbox同步
|
||||
|
||||
void HK_resetGain(); // HK设置增益
|
||||
|
||||
void HK_resetExposure(); // HK自动曝光
|
||||
|
||||
void HK_configureExposure(double exposure);
|
||||
|
||||
void HK_configureGain(double exposure); //HK调节增益
|
||||
|
||||
int configureGain(double gain); //设置增益
|
||||
|
||||
int resetGain(); //自动增益
|
||||
|
||||
QPixmap tct_pixmap;
|
||||
QGraphicsPixmapItem* tct_pixmapItem;
|
||||
QGraphicsScene* tct_scene; //TCT检测显示需要的
|
||||
|
||||
TCT* my_TCT; //创建模型处理的指针
|
||||
|
||||
QThread* m_infQthread; //模型处理的线程
|
||||
|
||||
QImage in_image; //经onnx模型检测后传回来的图片
|
||||
|
||||
QImage hikimage; //海康需要传入TCT时用
|
||||
|
||||
public slots:
|
||||
|
||||
void do_img_redy(ImagePtr pResultImage); //显示flir相机传回来的图像
|
||||
void on_btnSingleImageSave_clicked(); //保存单张图片
|
||||
void on_btnSaveDir_clicked(); //选择存储路径
|
||||
void input_img(QImage image); //接收经过网络后的图片
|
||||
void on_pb_model_clicked(); //TCT自动检测按钮
|
||||
|
||||
void do_hai_img_redy(MV_FRAME_OUT stImageInfo, void* handle); //将海康相机传回来的图片进行显示 //SB处理办法 弃用
|
||||
void on_pb_camera_clicked(); //选择相机
|
||||
void on_btnUp_clicked(); //Z向上
|
||||
void on_btnDown_clicked(); //Z向下
|
||||
void on_btnLeft_clicked(); //X向左
|
||||
void on_btnRight_clicked(); //X向右
|
||||
void on_btnForward_clicked(); //Y向前
|
||||
void on_btnBackward_clicked(); //Y向后
|
||||
void hai_img_redy(QImage image, void* handle); //将海康相机传回来的图片进行显示
|
||||
signals:
|
||||
void emit_img(QImage image); //将需要传入网络的图片传出去
|
||||
|
||||
|
||||
private:
|
||||
Ui::QtWidgetsApplicationClass ui;
|
||||
HWND m_hwndDisplay; //显示控件的句柄
|
||||
QPixmap pixmap;
|
||||
QGraphicsPixmapItem* pixmapItem;
|
||||
QGraphicsScene* m_scene; //相机显示
|
||||
void* HK_handle = NULL; //海康相机的句柄
|
||||
ImageProcessor processor;
|
||||
|
||||
ImagePtr pResultImage;
|
||||
|
||||
QThread* cam_thread; // 相机的线程
|
||||
M_camera* cam_worker; // filr相机
|
||||
haikang* Hacm_worker; // haikang相机
|
||||
|
||||
};
|
||||
|
||||
// 计算图像清晰度
|
||||
double sharpnessSobel(cv::Mat image);
|
||||
4
QtWidgetsApplication.qrc
Normal file
4
QtWidgetsApplication.qrc
Normal file
@ -0,0 +1,4 @@
|
||||
<RCC>
|
||||
<qresource prefix="QtWidgetsApplication">
|
||||
</qresource>
|
||||
</RCC>
|
||||
25
QtWidgetsApplication.sln
Normal file
25
QtWidgetsApplication.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35919.96 d17.13
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtWidgetsApplication", "QtWidgetsApplication.vcxproj", "{DFE02648-E0B0-477C-9592-2968ADF2C70B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DFE02648-E0B0-477C-9592-2968ADF2C70B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DFE02648-E0B0-477C-9592-2968ADF2C70B}.Debug|x64.Build.0 = Debug|x64
|
||||
{DFE02648-E0B0-477C-9592-2968ADF2C70B}.Release|x64.ActiveCfg = Release|x64
|
||||
{DFE02648-E0B0-477C-9592-2968ADF2C70B}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0BFAF1E1-EF2D-43DF-B91A-6C7644D4B72D}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
693
QtWidgetsApplication.ui
Normal file
693
QtWidgetsApplication.ui
Normal file
@ -0,0 +1,693 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QtWidgetsApplicationClass</class>
|
||||
<widget class="QMainWindow" name="QtWidgetsApplicationClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1439</width>
|
||||
<height>1169</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>QtWidgetsApplication</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>650</y>
|
||||
<width>1531</width>
|
||||
<height>471</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>用户模式</string>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="layoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>800</x>
|
||||
<y>0</y>
|
||||
<width>551</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinXDis">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string>um</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.989999999999782</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>500.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinYDis">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string>um</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.989999999999782</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>500.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinZDis">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string>um</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.989999999999782</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>800</x>
|
||||
<y>40</y>
|
||||
<width>551</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_xpos">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.989999999999782</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>500.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_ypos">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.989999999999782</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>500.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="m_zpos">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.989999999999782</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>380</x>
|
||||
<y>0</y>
|
||||
<width>372</width>
|
||||
<height>311</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>增 益:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>曝 光:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QSlider" name="sldGain">
|
||||
<property name="maximum">
|
||||
<number>4799</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="sldExposure">
|
||||
<property name="minimum">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>15000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinGain">
|
||||
<property name="suffix">
|
||||
<string>dB</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>47.990000000000002</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinExposure">
|
||||
<property name="suffix">
|
||||
<string>us</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>6.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>15000.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>6.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkGain">
|
||||
<property name="text">
|
||||
<string>自动</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkExposure">
|
||||
<property name="text">
|
||||
<string>自动</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>376</width>
|
||||
<height>219</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>请选择相机</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="CameraBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>flir camera</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>haikang camera</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_camera">
|
||||
<property name="text">
|
||||
<string>确定</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>保存路径:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="edtSaveDir">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSaveDir">
|
||||
<property name="text">
|
||||
<string>打开...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSingleImageSave">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>单张图像保存</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_model_3">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>自动对焦</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_model">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>自动检测</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_open_6">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>多视野采集自动对焦</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btnForward">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>990</x>
|
||||
<y>80</y>
|
||||
<width>81</width>
|
||||
<height>71</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>前</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btnUp">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>800</x>
|
||||
<y>90</y>
|
||||
<width>71</width>
|
||||
<height>61</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>上</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btnLeft">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>900</x>
|
||||
<y>130</y>
|
||||
<width>71</width>
|
||||
<height>71</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>左</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btnRight">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>1090</x>
|
||||
<y>130</y>
|
||||
<width>71</width>
|
||||
<height>71</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>右</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btnBackward">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>990</x>
|
||||
<y>180</y>
|
||||
<width>81</width>
|
||||
<height>71</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>后</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btnDown">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>800</x>
|
||||
<y>170</y>
|
||||
<width>71</width>
|
||||
<height>61</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>下</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="Tab2">
|
||||
<attribute name="title">
|
||||
<string>高级模式</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>1</x>
|
||||
<y>11</y>
|
||||
<width>1431</width>
|
||||
<height>641</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="imgView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="TCT_View"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1439</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mainToolBar">
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
<include location="QtWidgetsApplication.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
145
QtWidgetsApplication.vcxproj
Normal file
145
QtWidgetsApplication.vcxproj
Normal file
@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{DFE02648-E0B0-477C-9592-2968ADF2C70B}</ProjectGuid>
|
||||
<Keyword>QtVS_v304</Keyword>
|
||||
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0</WindowsTargetPlatformVersion>
|
||||
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
|
||||
<Import Project="$(QtMsBuild)\qt_defaults.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
|
||||
<QtInstall>5.12.3_msvc2017_64</QtInstall>
|
||||
<QtModules>core;gui;widgets</QtModules>
|
||||
<QtBuildConfig>debug</QtBuildConfig>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
|
||||
<QtInstall>5.12.3_msvc2017_64</QtInstall>
|
||||
<QtModules>core;gui;widgets</QtModules>
|
||||
<QtBuildConfig>release</QtBuildConfig>
|
||||
</PropertyGroup>
|
||||
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
|
||||
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
|
||||
</Target>
|
||||
<ImportGroup Label="ExtensionSettings" />
|
||||
<ImportGroup Label="Shared" />
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(QtMsBuild)\Qt.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(QtMsBuild)\Qt.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>D:\MVS\MVS\Development\Includes;D:\FUXIAOXI\MicroscopeController\3rdparty\opencv\build\include;D:\Spinnaker\include;D:\FUXIAOXI\MicroscopeController\3rdparty\XTController\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>D:\MVS\MVS\Development\Libraries\win64;D:\Spinnaker\lib64\vs2015;D:\FUXIAOXI\MicroscopeController\3rdparty\opencv\build\x64\vc16\lib;D:\FUXIAOXI\MicroscopeController\3rdparty\XTController\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opencv_world4100.lib;Spinnaker_v140.lib;SpinUpdate_v140.lib;SpinVideo_v140.lib;MvCameraControl.lib;MotionControlExtendDll.lib;voice_motor_dll.lib;GKZTMotion.lib;MotionControlDll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>D:\MVS\MVS\Development\Includes;D:\FUXIAOXI\MicroscopeController\3rdparty\XTController\include;D:\Spinnaker\include;D:\FUXIAOXI\MicroscopeController\3rdparty\opencv\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>D:\MVS\MVS\Development\Libraries\win64;D:\FUXIAOXI\MicroscopeController\3rdparty\opencv\build\x64\vc16\lib;D:\FUXIAOXI\MicroscopeController\3rdparty\XTController\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opencv_world4100d.lib;Spinnakerd_v140.lib;SpinUpdate_v140.lib;SpinVideod_v140.lib;MvCameraControl.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
|
||||
<ClCompile>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
|
||||
<ClCompile>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="focus.cpp" />
|
||||
<ClCompile Include="haikang.cpp" />
|
||||
<ClCompile Include="Mycontrol.cpp" />
|
||||
<ClCompile Include="TCT.cpp" />
|
||||
<QtRcc Include="QtWidgetsApplication.qrc" />
|
||||
<QtUic Include="QtWidgetsApplication.ui" />
|
||||
<QtMoc Include="QtWidgetsApplication.h" />
|
||||
<ClCompile Include="M_camera.cpp" />
|
||||
<ClCompile Include="QtWidgetsApplication.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="M_camera.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="TCT.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="haikang.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="Mycontrol.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="focus.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
||||
<Import Project="$(QtMsBuild)\qt.targets" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
76
QtWidgetsApplication.vcxproj.filters
Normal file
76
QtWidgetsApplication.vcxproj.filters
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Form Files">
|
||||
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
|
||||
<Extensions>ui</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Translation Files">
|
||||
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
|
||||
<Extensions>ts</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtRcc Include="QtWidgetsApplication.qrc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</QtRcc>
|
||||
<QtUic Include="QtWidgetsApplication.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtMoc Include="QtWidgetsApplication.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<ClCompile Include="QtWidgetsApplication.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="M_camera.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TCT.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="haikang.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Mycontrol.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="focus.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="M_camera.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="TCT.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="haikang.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Mycontrol.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="focus.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
14
QtWidgetsApplication.vcxproj.user
Normal file
14
QtWidgetsApplication.vcxproj.user
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<QtTouchProperty>
|
||||
</QtTouchProperty>
|
||||
<QtLastBackgroundBuild>2025-05-26T06:52:07.5163119Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<QtTouchProperty>
|
||||
</QtTouchProperty>
|
||||
<QtLastBackgroundBuild>2025-05-26T07:02:27.1347138Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
291
TCT.cpp
Normal file
291
TCT.cpp
Normal file
@ -0,0 +1,291 @@
|
||||
#include "TCT.h"
|
||||
|
||||
TCT::TCT(QObject* parent)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
TCT::~TCT()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TCT::TCT(const std::string& onnxModelPath, const cv::Size& modelInputShape, const std::string& classesTxtFile, const bool& runWithCuda)
|
||||
{
|
||||
modelPath = onnxModelPath;
|
||||
modelShape = modelInputShape;
|
||||
classesPath = classesTxtFile;
|
||||
cudaEnabled = runWithCuda;
|
||||
|
||||
loadOnnxNetwork();
|
||||
//loadClassesFromFile(); //The classes are hard-coded for this example
|
||||
|
||||
}
|
||||
|
||||
std::vector<Detection> TCT::runInference(const cv::Mat& input)
|
||||
{
|
||||
cv::Mat modelInput = input;
|
||||
if (letterBoxForSquare && modelShape.width == modelShape.height)
|
||||
modelInput = formatToSquare(modelInput);
|
||||
|
||||
cv::Mat blob;
|
||||
cv::dnn::blobFromImage(modelInput, blob, 1.0 / 255.0, modelShape, cv::Scalar(), true, false);
|
||||
net.setInput(blob);
|
||||
|
||||
std::vector<cv::Mat> outputs;
|
||||
net.forward(outputs, net.getUnconnectedOutLayersNames());
|
||||
|
||||
int rows = outputs[0].size[1];
|
||||
int dimensions = outputs[0].size[2];
|
||||
|
||||
bool yolov8 = false;
|
||||
// yolov5 has an output of shape (batchSize, 25200, 85) (Num classes + box[x,y,w,h] + confidence[c])
|
||||
// yolov8 has an output of shape (batchSize, 84, 8400) (Num classes + box[x,y,w,h])
|
||||
if (dimensions > rows) // Check if the shape[2] is more than shape[1] (yolov8)
|
||||
{
|
||||
yolov8 = true;
|
||||
rows = outputs[0].size[2];
|
||||
dimensions = outputs[0].size[1];
|
||||
|
||||
outputs[0] = outputs[0].reshape(1, dimensions);
|
||||
cv::transpose(outputs[0], outputs[0]);
|
||||
}
|
||||
float* data = (float*)outputs[0].data;
|
||||
|
||||
float x_factor = modelInput.cols / modelShape.width;
|
||||
float y_factor = modelInput.rows / modelShape.height;
|
||||
|
||||
std::vector<int> class_ids;
|
||||
std::vector<float> confidences;
|
||||
std::vector<cv::Rect> boxes;
|
||||
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
if (yolov8)
|
||||
{
|
||||
float* classes_scores = data + 4;
|
||||
|
||||
cv::Mat scores(1, classes.size(), CV_32FC1, classes_scores);
|
||||
cv::Point class_id;
|
||||
double maxClassScore;
|
||||
|
||||
minMaxLoc(scores, 0, &maxClassScore, 0, &class_id);
|
||||
|
||||
if (maxClassScore > modelScoreThreshold)
|
||||
{
|
||||
confidences.push_back(maxClassScore);
|
||||
class_ids.push_back(class_id.x);
|
||||
|
||||
float x = data[0];
|
||||
float y = data[1];
|
||||
float w = data[2];
|
||||
float h = data[3];
|
||||
|
||||
int left = int((x - 0.5 * w) * x_factor);
|
||||
int top = int((y - 0.5 * h) * y_factor);
|
||||
|
||||
int width = int(w * x_factor);
|
||||
int height = int(h * y_factor);
|
||||
|
||||
boxes.push_back(cv::Rect(left, top, width, height));
|
||||
}
|
||||
}
|
||||
else // yolov5
|
||||
{
|
||||
float confidence = data[4];
|
||||
|
||||
if (confidence >= modelConfidenceThreshold)
|
||||
{
|
||||
float* classes_scores = data + 5;
|
||||
|
||||
cv::Mat scores(1, classes.size(), CV_32FC1, classes_scores);
|
||||
cv::Point class_id;
|
||||
double max_class_score;
|
||||
|
||||
minMaxLoc(scores, 0, &max_class_score, 0, &class_id);
|
||||
|
||||
if (max_class_score > modelScoreThreshold)
|
||||
{
|
||||
confidences.push_back(confidence);
|
||||
class_ids.push_back(class_id.x);
|
||||
|
||||
float x = data[0];
|
||||
float y = data[1];
|
||||
float w = data[2];
|
||||
float h = data[3];
|
||||
|
||||
int left = int((x - 0.5 * w) * x_factor);
|
||||
int top = int((y - 0.5 * h) * y_factor);
|
||||
|
||||
int width = int(w * x_factor);
|
||||
int height = int(h * y_factor);
|
||||
|
||||
boxes.push_back(cv::Rect(left, top, width, height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data += dimensions;
|
||||
}
|
||||
|
||||
std::vector<int> nms_result;
|
||||
cv::dnn::NMSBoxes(boxes, confidences, modelScoreThreshold, modelNMSThreshold, nms_result);
|
||||
|
||||
std::vector<Detection> detections{};
|
||||
for (unsigned long i = 0; i < nms_result.size(); ++i)
|
||||
{
|
||||
int idx = nms_result[i];
|
||||
|
||||
Detection result;
|
||||
result.class_id = class_ids[idx];
|
||||
result.confidence = confidences[idx];
|
||||
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<int> dis(100, 255);
|
||||
result.color = cv::Scalar(dis(gen),
|
||||
dis(gen),
|
||||
dis(gen));
|
||||
|
||||
result.className = classes[result.class_id];
|
||||
result.box = boxes[idx];
|
||||
|
||||
detections.push_back(result);
|
||||
}
|
||||
|
||||
return detections;
|
||||
}
|
||||
|
||||
void TCT::loadClassesFromFile()
|
||||
{
|
||||
std::ifstream inputFile(classesPath);
|
||||
if (inputFile.is_open())
|
||||
{
|
||||
std::string classLine;
|
||||
while (std::getline(inputFile, classLine))
|
||||
classes.push_back(classLine);
|
||||
inputFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void TCT::loadOnnxNetwork()
|
||||
{
|
||||
net = cv::dnn::readNetFromONNX(modelPath);
|
||||
cudaEnabled = 1;
|
||||
if (cudaEnabled)
|
||||
{
|
||||
std::cout << "\nRunning on CUDA" << std::endl;
|
||||
net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
|
||||
net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "\nRunning on CPU" << std::endl;
|
||||
net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat TCT::formatToSquare(const cv::Mat& source)
|
||||
{
|
||||
int col = source.cols;
|
||||
int row = source.rows;
|
||||
int _max = MAX(col, row);
|
||||
cv::Mat result = cv::Mat::zeros(_max, _max, CV_8UC3);
|
||||
source.copyTo(result(cv::Rect(0, 0, col, row)));
|
||||
return result;
|
||||
}
|
||||
|
||||
//QImageToCvMat函数
|
||||
cv::Mat convertQImageToCvMat(const QImage& qImage) {
|
||||
// 转换为RGB888格式,确保三通道
|
||||
QImage swappedImage = qImage.convertToFormat(QImage::Format_RGB888);
|
||||
|
||||
// 创建临时cv::Mat,共享数据
|
||||
cv::Mat tmp(swappedImage.height(), swappedImage.width(), CV_8UC3,
|
||||
const_cast<uchar*>(swappedImage.bits()),
|
||||
static_cast<size_t>(swappedImage.bytesPerLine()));
|
||||
|
||||
// 将RGB转为OpenCV默认的BGR顺序
|
||||
cv::Mat cvMat;
|
||||
cv::cvtColor(tmp, cvMat, cv::COLOR_RGB2BGR);
|
||||
|
||||
// 克隆数据以确保独立于QImage的生命周期
|
||||
return cvMat.clone();
|
||||
}
|
||||
|
||||
// CvMatToQImage函数
|
||||
QImage CvMatToQImage(const cv::Mat& mat) {
|
||||
if (mat.empty())
|
||||
return QImage();
|
||||
|
||||
// 处理单通道和三通道情况
|
||||
cv::Mat rgbMat;
|
||||
switch (mat.channels()) {
|
||||
case 1:
|
||||
cv::cvtColor(mat, rgbMat, cv::COLOR_GRAY2RGB);
|
||||
break;
|
||||
case 3:
|
||||
cv::cvtColor(mat, rgbMat, cv::COLOR_BGR2RGB);
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unsupported channel count");
|
||||
}
|
||||
|
||||
// 构造QImage并拷贝数据(避免野指针)
|
||||
return QImage(
|
||||
rgbMat.data,
|
||||
rgbMat.cols,
|
||||
rgbMat.rows,
|
||||
static_cast<int>(rgbMat.step),
|
||||
QImage::Format_RGB888
|
||||
).copy(); // 必须.copy()保证独立内存
|
||||
}
|
||||
|
||||
// 总体处理函数
|
||||
void TCT::main_module(QImage image)
|
||||
{
|
||||
bool runOnGPU = false;
|
||||
TCT inf("E:/wjy/QtWidgetsApplication-master/best.onnx", cv::Size(640, 640), "classes.txt", runOnGPU); //处理模型
|
||||
|
||||
//std::vector<std::string> imageNames;
|
||||
//imageNames.push_back("D:/4.png"); //读取图片
|
||||
|
||||
cv::Mat frame = convertQImageToCvMat(image);
|
||||
|
||||
std::vector<Detection> output = inf.runInference(frame);
|
||||
|
||||
int detections = output.size();
|
||||
std::cout << "Number of detections:" << detections << std::endl;
|
||||
|
||||
for (int i = 0; i < detections; ++i)
|
||||
{
|
||||
Detection detection = output[i];
|
||||
|
||||
cv::Rect box = detection.box;
|
||||
cv::Scalar color = detection.color;
|
||||
|
||||
// Detection box
|
||||
cv::rectangle(frame, box, color, 2);
|
||||
|
||||
// Detection box text
|
||||
std::string classString = detection.className + ' ' + std::to_string(detection.confidence).substr(0, 4);
|
||||
cv::Size textSize = cv::getTextSize(classString, cv::FONT_HERSHEY_DUPLEX, 1, 2, 0);
|
||||
cv::Rect textBox(box.x, box.y - 40, textSize.width + 10, textSize.height + 20);
|
||||
|
||||
cv::rectangle(frame, textBox, color, cv::FILLED);
|
||||
cv::putText(frame, classString, cv::Point(box.x + 5, box.y - 10), cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(0, 0, 0), 2, 0);
|
||||
}
|
||||
// Inference ends here...
|
||||
|
||||
// This is only for preview purposes
|
||||
float scale = 0.8;
|
||||
QImage img_i = CvMatToQImage(frame);
|
||||
cv::Mat myframe = convertQImageToCvMat(img_i);
|
||||
emit em_img(img_i);
|
||||
|
||||
}
|
||||
|
||||
|
||||
87
TCT.h
Normal file
87
TCT.h
Normal file
@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
#include <QLabel>
|
||||
#include <QPixmap>
|
||||
#include <QImage>
|
||||
// Cpp native
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <random>
|
||||
|
||||
// OpenCV / DNN / Inference
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/dnn.hpp>
|
||||
|
||||
|
||||
|
||||
struct Detection
|
||||
{
|
||||
int class_id{ 0 };
|
||||
std::string className{};
|
||||
float confidence{ 0.0 };
|
||||
cv::Scalar color{};
|
||||
cv::Rect box{};
|
||||
};
|
||||
|
||||
class TCT : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TCT(QObject* parent = nullptr);
|
||||
~TCT();
|
||||
|
||||
// 处理onnx模型(传入onnx模型地址,网络所需图片size, classes, 是否使用GPU)
|
||||
TCT(const std::string& onnxModelPath, const cv::Size& modelInputShape = { 640, 640 }, const std::string& classesTxtFile = "", const bool& runWithCuda = false);
|
||||
std::vector<Detection> runInference(const cv::Mat& input);
|
||||
|
||||
QImage img_i;
|
||||
|
||||
public slots:
|
||||
|
||||
//总体处理函数
|
||||
void main_module(QImage image);
|
||||
|
||||
signals:
|
||||
|
||||
//将经过网络的图片发给主线程
|
||||
void em_img(QImage img);
|
||||
|
||||
private:
|
||||
|
||||
void loadClassesFromFile();
|
||||
|
||||
//读取模型
|
||||
void loadOnnxNetwork();
|
||||
|
||||
cv::Mat formatToSquare(const cv::Mat& source);
|
||||
|
||||
std::string modelPath{};
|
||||
|
||||
std::string classesPath{};
|
||||
|
||||
bool cudaEnabled{};
|
||||
|
||||
|
||||
/*"bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush" };*/
|
||||
std::vector<std::string> classes{ "cancer" }; //类别数及其名称
|
||||
cv::Size2f modelShape{};
|
||||
|
||||
float modelConfidenceThreshold{ 0.25 }; //置信度
|
||||
|
||||
float modelScoreThreshold{ 0.15 }; //得分门槛
|
||||
|
||||
float modelNMSThreshold{ 0.50 }; //最大值抑制
|
||||
|
||||
bool letterBoxForSquare = true;
|
||||
|
||||
cv::dnn::Net net; //定义的网络
|
||||
|
||||
};
|
||||
12
focus.cpp
Normal file
12
focus.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "focus.h"
|
||||
|
||||
|
||||
focus::focus(QObject* parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
focus::~focus()
|
||||
{
|
||||
|
||||
}
|
||||
34
focus.h
Normal file
34
focus.h
Normal file
@ -0,0 +1,34 @@
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <cstdio>
|
||||
#include <QPixmap>
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QLineEdit>
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include <QDateTime>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <QMutex>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class focus : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
focus(QObject* parent);
|
||||
~focus();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
164
haikang.cpp
Normal file
164
haikang.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
#pragma once
|
||||
#pragma execution_character_set("UTF-8")
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include "haikang.h"
|
||||
#include <Image.h>
|
||||
|
||||
|
||||
|
||||
haikang::haikang(QWidget* parent)
|
||||
{
|
||||
nRet = MV_CC_Initialize();
|
||||
// ch:枚举设备 | en:Enum device
|
||||
MV_CC_DEVICE_INFO_LIST stDeviceList;
|
||||
memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
|
||||
nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE, &stDeviceList);
|
||||
if (MV_OK != nRet)
|
||||
{
|
||||
printf("Enum Devices fail! nRet [0x%x]\n", nRet);
|
||||
|
||||
}
|
||||
if (stDeviceList.nDeviceNum > 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++)
|
||||
{
|
||||
printf("[device %d]:\n", i);
|
||||
MV_CC_DEVICE_INFO* pDeviceInfo = stDeviceList.pDeviceInfo[i];
|
||||
if (NULL == pDeviceInfo)
|
||||
{
|
||||
break;
|
||||
}
|
||||
PrintDeviceInfo(pDeviceInfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Find No Devices!\n");
|
||||
|
||||
}
|
||||
printf("Please Input camera index(0-%d):", stDeviceList.nDeviceNum - 1);
|
||||
unsigned int nIndex = 0;
|
||||
|
||||
// ch:选择设备并创建句柄 | en:Select device and create handle
|
||||
nRet = MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[nIndex]);
|
||||
if (MV_OK != nRet)
|
||||
{
|
||||
printf("Create Handle fail! nRet [0x%x]\n", nRet);
|
||||
}
|
||||
|
||||
// ch:打开设备 | en:Open device
|
||||
nRet = MV_CC_OpenDevice(handle);
|
||||
if (MV_OK != nRet)
|
||||
{
|
||||
printf("Open Device fail! nRet [0x%x]\n", nRet);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Open Device success! nRet [0x%x]\n", nRet);
|
||||
}
|
||||
|
||||
// ch:开始取流 | en:Start grab image
|
||||
nRet = MV_CC_StartGrabbing(handle);
|
||||
|
||||
}
|
||||
|
||||
haikang::~haikang()
|
||||
{
|
||||
finish();
|
||||
|
||||
}
|
||||
|
||||
bool haikang::PrintDeviceInfo(MV_CC_DEVICE_INFO* pstMVDevInfo)
|
||||
{
|
||||
if (NULL == pstMVDevInfo)
|
||||
{
|
||||
printf("The Pointer of pstMVDevInfo is NULL!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
else if (pstMVDevInfo->nTLayerType == MV_USB_DEVICE)
|
||||
{
|
||||
printf("UserDefinedName: %s\n", pstMVDevInfo->SpecialInfo.stUsb3VInfo.chUserDefinedName);
|
||||
printf("Serial Number: %s\n", pstMVDevInfo->SpecialInfo.stUsb3VInfo.chSerialNumber);
|
||||
printf("Device Number: %d\n\n", pstMVDevInfo->SpecialInfo.stUsb3VInfo.nDeviceNumber);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void haikang::GrabThreadProcess() {
|
||||
MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_OFF);
|
||||
while (1) {
|
||||
MV_CC_GetImageBuffer(handle, &stImageInfo, 1000);
|
||||
// 检查像素格式是否为Bayer RG8
|
||||
if (stImageInfo.stFrameInfo.enPixelType == PixelType_Gvsp_BayerRG8) {
|
||||
// 使用OpenCV处理Bayer数据
|
||||
cv::Mat bayerMat(
|
||||
stImageInfo.stFrameInfo.nHeight,
|
||||
stImageInfo.stFrameInfo.nWidth,
|
||||
CV_8UC1,
|
||||
stImageInfo.pBufAddr
|
||||
);
|
||||
cv::Mat rgbMat;
|
||||
cv::cvtColor(bayerMat, rgbMat, cv::COLOR_BayerRG2RGB);
|
||||
// 转换为QImage(RGB888)
|
||||
QImage tempImage(
|
||||
rgbMat.data,
|
||||
rgbMat.cols,
|
||||
rgbMat.rows,
|
||||
rgbMat.step,
|
||||
QImage::Format_RGB888
|
||||
);
|
||||
// 深拷贝数据确保安全
|
||||
QImage safeImage = tempImage.copy();
|
||||
// 发送信号到主线程显示
|
||||
emit img_to(safeImage, handle);
|
||||
}
|
||||
MV_CC_FreeImageBuffer(handle, &stImageInfo);
|
||||
}
|
||||
}
|
||||
|
||||
//memcpy(&m_stImageInfo, &(stImageInfo.stFrameInfo), sizeof(MV_FRAME_OUT_INFO_EX)); //复制一份出来,用于保存图片
|
||||
/*QImage image(stImageInfo.pBufAddr,
|
||||
stImageInfo.stFrameInfo.nWidth,
|
||||
stImageInfo.stFrameInfo.nHeight,
|
||||
QImage::Format_Indexed8);
|
||||
|
||||
int bytesPerLine = stImageInfo.stFrameInfo.enPixelType;
|
||||
qDebug() << "is: " << stImageInfo.stFrameInfo.enPixelType << "";
|
||||
printf("bytesPerLine");
|
||||
emit img_to(image, handle);
|
||||
MV_CC_FreeImageBuffer(handle, &stImageInfo);*/
|
||||
|
||||
//MV_FRAME_OUT stOutFrame = stImageInfo;
|
||||
//emit img_redy(stImageInfo, handle);
|
||||
|
||||
|
||||
void haikang::finish() {
|
||||
|
||||
nRet = MV_CC_StopGrabbing(handle);
|
||||
nRet = MV_CC_RegisterImageCallBackEx(handle, NULL, NULL);
|
||||
nRet = MV_CC_CloseDevice(handle);
|
||||
if (MV_OK != nRet)
|
||||
{
|
||||
printf("ClosDevice fail! nRet [0x%x]\n", nRet);
|
||||
}
|
||||
nRet = MV_CC_DestroyHandle(handle);
|
||||
if (MV_OK != nRet)
|
||||
{
|
||||
printf("Destroy Handle fail! nRet [0x%x]\n", nRet);
|
||||
}
|
||||
handle = NULL;
|
||||
if (handle != NULL)
|
||||
{
|
||||
MV_CC_DestroyHandle(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
// ch:反初始化SDK | en:Finalize SDK
|
||||
MV_CC_Finalize();
|
||||
printf("Destroy Handle success! nRet [0x%x]\n", nRet);
|
||||
|
||||
}
|
||||
|
||||
45
haikang.h
Normal file
45
haikang.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#include "MvCameraControl.h"
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <cstdio>
|
||||
#include <QPixmap>
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QLineEdit>
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include <QDateTime>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <QMutex>
|
||||
|
||||
class haikang : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
haikang(QWidget* parent = nullptr);
|
||||
~haikang();
|
||||
|
||||
unsigned char* m_pSaveImageBuf; // 保存图像缓冲区指针
|
||||
HWND m_hwndDisplay;
|
||||
QMutex m_hSaveImageMux;
|
||||
int nRet = MV_OK;
|
||||
void* handle = NULL;
|
||||
bool PrintDeviceInfo(MV_CC_DEVICE_INFO* pstMVDevInfo);
|
||||
|
||||
MV_FRAME_OUT_INFO_EX m_stImageInfo; // 图像信息结构体变量
|
||||
MV_FRAME_OUT stImageInfo = {0};
|
||||
|
||||
|
||||
public slots:
|
||||
void GrabThreadProcess();
|
||||
void finish();
|
||||
signals:
|
||||
void img_redy(MV_FRAME_OUT stImageInfo, void* handle);
|
||||
|
||||
void img_to(QImage img, void* handle);
|
||||
|
||||
|
||||
};
|
||||
12
main.cpp
Normal file
12
main.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "QtWidgetsApplication.h"
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_ERROR);//抑制日志输出
|
||||
QApplication a(argc, argv);
|
||||
QtWidgetsApplication w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user