QtWidgetsApplication-master/QtWidgetsApplication.cpp
2025-05-28 10:47:46 +08:00

419 lines
13 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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];
}