• Qt 调SDK图像处理显示


    1. pro
    #-------------------------------------------------
    #
    # Project created by QtCreator 2022-10-19T09:56:51
    #
    #-------------------------------------------------
    
    QT       += core gui
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = LC260QtDemo
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which as been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    
    SOURCES += main.cpp\
            IRMainWindow.cpp \
        guidecoremanage.cpp \
        IRManage.cpp
    
    HEADERS  += IRMainWindow.h \
        common.h \
        connmonType.h \
        guidecoremanage.h \
        IRManage.h
    
    FORMS    += IRMainWindow.ui
    
    MOC_DIR += ./moc            # 中间文件存放位置
    
    win32: LIBS += -L$$PWD/../lib/libcurl/lib/x64/Release/ -llibcurl
    
    INCLUDEPATH += $$PWD/../lib/libcurl/include
    DEPENDPATH += $$PWD/../lib/libcurl/include
    
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../lib/libcurl/lib/x64/Release/libcurl.lib
    #else:win32-g++: PRE_TARGETDEPS += $$PWD/../lib/libcurl/lib/x64/Release/liblibcurl.a
    
    win32: LIBS += -L$$PWD/../lib/ -llibusb-1.0
    
    INCLUDEPATH += $$PWD/../lib
    DEPENDPATH += $$PWD/../lib
    
    
    win32: LIBS += -L$$PWD/../lib/pthread/lib/x64/ -lpthreadVC2
    
    INCLUDEPATH += $$PWD/../lib/pthread/include
    DEPENDPATH += $$PWD/../lib/pthread/include
    
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../lib/pthread/lib/x64/pthreadVC2.lib
    #else:win32-g++: PRE_TARGETDEPS += $$PWD/../lib/pthread/lib/x64/libpthreadVC2.a   # only linux
    
    
    #  
    win32: LIBS += -L$$PWD/../win64/dll/ -lArmSdk
    
    INCLUDEPATH += $$PWD/../win64/include
    DEPENDPATH += $$PWD/../win64/include
    
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../win64/dll/ArmSdk.lib
    #else:win32-g++: PRE_TARGETDEPS += $$PWD/../win64/dll/libArmSdk.a
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    2、USBCore

    /*
    *	红外业务协议应用层
    */
    
    #ifndef GUIDECOREMANAGE_H
    #define GUIDECOREMANAGE_H
    #include "guideusbmanage.h"
    
    #include "ModuleSDK.h"
    #include 
    #include 
    #include 
    #include 
    
    #define GUIDE_CORE_SMOOTH_TEMP_NUM  15
    
    typedef struct{
    	float maxTemp;
    	float minTemp;
    	int maxTempPoint;
    	int minTempPoint;
    }TempInFo;
    
    
    static GUIDE_REF_RGB_PARAM_CALLBACKV golb_fRefRgbPicCallback;
    static void *golb_pRefrgbPicCbPara;
    
    static HANDLE_T g_Module = 0;
    
    class GuideCoreManage 
    {   
    public:  
        GuideCoreManage(char *jobNum); 
    	~GuideCoreManage();
    
        void startConnect();
        void startDisConnect();
    
        void setRotate(int rotate);     // set image rotate
    
        void getEnvTemp(float *envTemp);
    
        void getBodyTemp(short Y16 ,  float &bodyTemp );
    
        // for get data from SDK
        void setCallackFunc(ImageCallBack imageCallBack, void *param, float scaleTime);
    
        // sdk IR Image parameter
        void setPaletteType(int palette);      // set palette
    	 
        void initailSdk();
    
    private:
        float m_ambientTem;
    };
    
    #endif // GUIDECOREMANAGE_H
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    USBCore.cpp

    #include "guidecoremanage.h"
    GuideCoreManage::GuideCoreManage(char *jobNum)
    {
    
    }
    
    GuideCoreManage::~GuideCoreManage()
    {
    
    }
    
    
    void GuideCoreManage:: startConnect() {
        /******************************???sdk??******************************/
        initailSdk();
    }
    
    
    void GuideCoreManage::initailSdk()
    {
        int isDebugging =1;
    
        g_Module = CreateModuleInstance("");
        MeasureParamsControl(g_Module, DEBUGGING_PATH, (void*)"log");
        MeasureParamsControl(g_Module, SET_DEBUGGING, &isDebugging);
    
        // register user callback function to get data
    //    RegisterImgCallBack(g_Module, cbFuncHandle, nullptr, 1);
        if (g_Module) {
            /******************************??????******************************/
            //???????????????0.8?
            float fDistance = 0.8;
            if (MeasureParamsControl(g_Module, SET_DISTANCE, (void *)&fDistance) != GUIDEIR_OK){
                std::cout << "set distance error!" << std::endl;
            }
            //?????????????????25???
            float fEnvironment = 25.0;
            if (MeasureParamsControl(g_Module, SET_AMBIENT_TEMP , (void *)&fEnvironment) != GUIDEIR_OK){
                std::cout << "set environment error!" << std::endl;
            }
            int format = 2;
            ImageParamsControl(g_Module, SET_FORMAT, &format);
        }
    
        return;
    }
    
    void GuideCoreManage::startDisConnect()
    {
        if (g_Module) {
            DestroyModuleInstance(g_Module);
        }
    }
    
    void GuideCoreManage::setRotate(int rotate)
    {
        if ( 0 <= rotate  && rotate <= 3) {
            ImageParamsControl(g_Module, SET_ROTATION , (void*)&rotate);
        }
    }
    
    void GuideCoreManage::getEnvTemp(float *envTemp)
    {
        if (g_Module)
            MeasureParamsControl(g_Module, GET_AMBIENT_TEMP, (void*)&m_ambientTem);
    
        *envTemp = m_ambientTem;
    }
    
    void GuideCoreManage::getBodyTemp(short Y16, float &bodyTemp)
    {
        // input parameter
        float surTemp = 0.0;
        MeasureTempByY16(g_Module, Y16, &surTemp);
        MeasureBodyTemp(g_Module, surTemp, m_ambientTem, &bodyTemp);
    }
    
    void GuideCoreManage::setPaletteType(int palette)
    {
        if (g_Module) {
            ImageParamsControl(g_Module, SET_PALETTE, (void*)palette);
        }
    }
    
    void GuideCoreManage::setCallackFunc(ImageCallBack imageCallBack, void *param, float scaleTime)
    {
        if(g_Module)
            RegisterImgCallBack(g_Module, imageCallBack, param, scaleTime);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    3、界面
    MainWindow.h

    #ifndef IRMAINWINDOW_H
    #define IRMAINWINDOW_H
    
    #include 
    
    
    namespace Ui {
    class IRMainWindow;
    }
    
    class IRMainWindow : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit IRMainWindow(QWidget *parent = 0);
        ~IRMainWindow();
    
    public slots:
        void slot_updateImg(QPixmap *rgbData);
        void slot_openDev();        // 打开设备
        void slot_closeDev();       // 关闭设备
        void slot_shutter();        // 快门
        void slot_NUC();            // NUC
        void slot_scalChange(int);  // 缩放图像
        void slot_PaletteChange(int);
    	void slot_snapImg();
    	void slot_recordVideo();
    	void slot_updateCenterTemp(QString centerTemp);
    	void slot_updateCurPosTemp(QString curPosTemp);
    	void slot_updateMinMaxTemp(QString min, QString max);
    	void slot_shutterOff();
    	void slot_shutterOn();
    	void slot_update();
    	void slot_changeRange();
    	void slot_saveTempMat();
    	void slot_resetFactory();		// 恢复出厂设置
    	void slot_updateSelectPos();	// 更新选择的测温点
    
    signals:
        void sig_startConnect();
        void sig_startDisConnect();
        void sig_shutter();
        void sig_NUC();
        void sig_scalChange(int);
        void sig_PaletteChange(int);
    	void sig_snapImg();
    	void sig_recordVideo(bool);		
    	void sig_saveTempMat();
    	void sig_setSelPos();					// 选择测温点
    	void sig_openShutterOff(bool status);	// 快门open 是否失电
    	void sig_update();
    	void sig_changeRange(int range);
    	void sig_reFactorySet();				// 
    	void sig_shutterOff();
    	void sig_shutterOn();
    	void sig_updateSelectPos(int x, int y);
    
    private:
        Ui::IRMainWindow *ui;
        int m_imageScaledRation;
    };
    
    #endif // IRMAINWINDOW_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    MainWindow.cpp

    #include "IRMainWindow.h"
    #include "ui_IRMainWindow.h"
    #include 
    #include 
    #include 
    #include 
    #include "common.h"
    
    IRMainWindow::IRMainWindow(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::IRMainWindow)
    {
        ui->setupUi(this);
        connect(ui->comboBoxPalette, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &IRMainWindow::slot_PaletteChange);
        connect(ui->comboBoxScale, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &IRMainWindow::slot_scalChange);
        connect(ui->pushButtonOpen, &QPushButton::clicked, this, &IRMainWindow::slot_openDev);
        connect(ui->pushButtonClose, &QPushButton::clicked, this, &IRMainWindow::slot_closeDev);
        connect(ui->pushButtonShutter, &QPushButton::clicked, this, &IRMainWindow::slot_shutter);
        connect(ui->pushButtonNUC, &QPushButton::clicked, this, &IRMainWindow::slot_NUC);
    	connect(ui->pushButtonSnape, &QPushButton::clicked, this, &IRMainWindow::slot_snapImg);
    	connect(ui->pushButtonSaveTempMat, &QPushButton::clicked, this, &IRMainWindow::slot_saveTempMat);
    	connect(ui->pushButtonUpdate, &QPushButton::clicked, this, &IRMainWindow::slot_update);
    	connect(ui->pushButtonChangeRange, &QPushButton::clicked, this, &IRMainWindow::slot_changeRange);
    	connect(ui->pushButtonReset, &QPushButton::clicked, this, &IRMainWindow::slot_resetFactory);
    	connect(ui->pushButtonShutterOpen, &QPushButton::clicked, this, &IRMainWindow::slot_shutterOn);
    	connect(ui->pushButtonShutterClose, &QPushButton::clicked, this, &IRMainWindow::slot_shutterOff);
    	connect(ui->lineEditSelectX, &QLineEdit::textChanged, this, &IRMainWindow::slot_updateSelectPos);
    	connect(ui->lineEditSelectY, &QLineEdit::textChanged, this, &IRMainWindow::slot_updateSelectPos);
    	connect(ui->pushButtonRecord, &QPushButton::clicked, this, &IRMainWindow::slot_recordVideo);
        m_imageScaledRation = 2;
        ui->labelVideo->setMinimumSize(256, 192);
        ui->labelVideo->resize(256, 192);    // 设置图像显示窗口大小,要与图像一样大
        this->showFullScreen();             // 无效就用 下面resize
        //this->resize(QSize(1080, 720));
    	ui->comboBoxScale->setCurrentIndex(1);
    }
    
    IRMainWindow::~IRMainWindow()
    {
        delete ui;
    }
    
    void IRMainWindow::slot_updateImg(QPixmap *pix)
    {
        // X修改第三个参数, 显示图像自由缩放
    	ui->labelVideo->setPixmap(pix->scaled(GUIDE_RES_WIDETH*m_imageScaledRation, GUIDE_RES_HEIGHT*m_imageScaledRation, Qt::KeepAspectRatioByExpanding, Qt::FastTransformation));
    }
    
    void IRMainWindow::slot_openDev()
    {
        emit sig_startConnect();
        qDebug() << "open clicked.";
    }
    
    void IRMainWindow::slot_closeDev()
    {
        emit sig_startDisConnect();
    }
    
    void IRMainWindow::slot_shutter()
    {
        emit sig_shutter();
    }
    
    void IRMainWindow::slot_NUC()
    {
        emit sig_NUC();
    }
    
    void IRMainWindow::slot_scalChange(int para)
    {
    //    int scaleValue = ui->comboBoxScale->currentIndex() + 1;
        emit sig_scalChange(para);
    	m_imageScaledRation = para +1;
    }
    
    void IRMainWindow::slot_PaletteChange(int para)
    {
        emit sig_PaletteChange(para);
    }
    
    void IRMainWindow::slot_snapImg()
    {
    	emit sig_snapImg();
    }
    
    void IRMainWindow::slot_recordVideo()
    {
    	if (ui->pushButtonRecord->text() == "record") {
    		emit sig_recordVideo(true);
    		ui->pushButtonRecord->setText ("stop record");
    	}
    	else {
    		emit sig_recordVideo(false);
    		ui->pushButtonRecord->setText("record");
    	}
    }
    
    void IRMainWindow::slot_updateCenterTemp(QString centerTemp)
    {
    	ui->labelCenterTemp->setText(centerTemp);
    }
    
    void IRMainWindow::slot_updateCurPosTemp(QString curPosTemp)
    {
    	ui->labelCurPosTemp->setText(curPosTemp);
    }
    
    void IRMainWindow::slot_updateMinMaxTemp(QString min, QString max)
    {
    	ui->labelMinTemp->setText(min);
    	ui->labelMaxTemp->setText(max);
    }
    
    
    void IRMainWindow::slot_shutterOff()
    {
    	emit sig_shutterOff();
    }
    
    void IRMainWindow::slot_shutterOn()
    {
    	emit sig_shutterOn();
    }
    
    void IRMainWindow::slot_update()
    {
    	emit sig_update();
    }
    
    void IRMainWindow::slot_changeRange()
    {
    	QString currMeasureRange = ui->pushButtonChangeRange->text();
    	QString curText;
    	int range;
    	if (currMeasureRange == "change High")
    	{
    		curText = "change Low";
    		range = 2;
    	}
    	else if(currMeasureRange == "change Low")
    	{
    		curText = "change High";
    		range = 1;
    	}
    	ui->pushButtonChangeRange->setText(curText);
    	emit sig_changeRange(range);
    }
    
    void IRMainWindow::slot_saveTempMat()
    {
    	emit sig_saveTempMat();
    }
    
    void IRMainWindow::slot_resetFactory()
    {
    	emit sig_reFactorySet();
    }
    
    void IRMainWindow::slot_updateSelectPos()
    {
    	int x = ui->lineEditSelectX->text().toInt();
    	int y = ui->lineEditSelectY->text().toInt();
    
    	if (x < 0)
    	{
    		x = 0;
    		ui->lineEditSelectX->setText("0");
    	}
    	if (x > 255)
    	{
    		x = 255;
    		ui->lineEditSelectX->setText("255");
    	}
    	if (y < 0)
    	{
    		y = 0;
    		ui->lineEditSelectY->setText("0");
    	}
    	if (y > 192)
    	{
    		y = 191;
    		ui->lineEditSelectY->setText("192");
    	}
    
    	emit sig_updateSelectPos(x, y);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188

    4、中间架构类 IRManage.h

    #ifndef IRMANAGE_H
    #define IRMANAGE_H
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 	
    #include 
    #include 
    #include 
    #include "guidecoremanage.h"
    #include "common.h"
    #include "IRMainWindow.h"
    #include 
    #define CLIPVALUE(x, minValue, maxValue) ((x) < (minValue) ? (minValue) : ((x) > (maxValue) ? (maxValue) : (x)))
    #define YUVToR(Y, U, V) ( (Y) + 1.4075 * ((V) - 128) )
    #define YUVToG(Y, U, V) ( (Y) - 0.3455 * ((U) - 128) - 0.7169 * ((V) - 128) )
    #define YUVToB(Y, U, V) ( (Y) + 1.779 * ((U) - 128) )
    
    //static void GuideRefRgbPicCb(unsigned char *data, void *para);
    //static void GuideDeviceDisconnectCb(void *para);
    
    //注册回调红外数据回调函数
    int cbFuncHandle(CallBackData cbData, void *param, int scaleTime);
    void handleY16Data(short* pY16Data, const int& iLen, const int& iWidth, const int& iHeight);
    void handleYuvData(unsigned char* pYuvData, const int& iLen, const int& iWidth, const int& iHeight);
    
    
    //ImageCallBack getDataCallback();
    
    class IRManage: public QObject
    {
        Q_OBJECT
    
    public:
        IRManage();
        ~IRManage();
    
        void addfVidoPara(unsigned char *data);
        void addfTemData(short *data);
        void deviceDisconnect();
    
    public slots:  
        void slot_open();					     	 //打开设备
        void slot_close();						     //关闭设备
        void slot_shutter();						 //快门
    	void slot_shutterOpen();					 //快门打开单向
    	void slot_shutterClose();					 //快门关闭 
        void slot_NUC();							 //NUC
        void slot_scalChange(int para);              //缩放 palette
        void slot_PaletteChange(int para);           //切换色带
    	void slot_snapeImage();
    	void slot_saveTempMat();
    	void slot_setOpenShutterOffPower(bool status);
    	void slot_updateAsic();					     //升级 asic
    	void slot_changeRange(int range);			
    	void slot_getUpdateProgressTimer();	         //升级状态获取
    	void slot_reFactorySet();					 // 恢复出厂设置
    	void slot_updatePos(int x, int y);           // 更新测温点坐标
    	void slot_recordVideo(bool para);			 // 录制yuv数据
    
    signals:
        void sig_connectSuccess();
        void sig_disConnect();
    	void sig_updateCenterTemp(QString centerTemp);	// 中心温度更新
    	void sig_updateCurPosTemp(QString centerTemp);	// 当前选择点温度更新
    	void sig_updateMinMaxTemp(QString min, QString max);
    
    protected:
    //   void slotGetConnectProgressTimer();	// 刷连接状态
        void slot_refVideoTimer();	        // 刷图像数据
    	void slot_refTempTimer();	        // 刷温度数据
    
    private:
        bool yuv422torgb(unsigned char *rgbImageData, unsigned char *yuvImageData, short width, short height);
    	void saveImage(QPixmap &img);
    	void checkDataDir();					       // 检查需要的文件夹是否存在,不存在则创建
        GuideCoreManage *m_coreManage;
        IRMainWindow *m_IRWindow;
    
        bool m_deviceDisconnect;                        // 设备连接状态
        std::deque<unsigned char*> m_videoQueue;		// 图像数据缓存,  all data push nhere
        std::deque<short *> m_TempDataQueue;			// 温度数据缓存
        std::mutex *m_videoQueueMutex;
        std::mutex *m_TempQueueMutex;
        float m_maxTemp;
        float m_minTemp;
        QTimer m_getConnectProgressTimer;
        QTimer m_refVideoTimer;                        // 图像数据刷新定时器
        QTimer m_refUiInfoTimer;                       // 界面数据刷新定时器
        QTimer m_refTempTimer;                         // 温度刷新定时器
    	QTimer m_getUpdateProgressTimer;			   
        int m_tryConnectTimes;
    
        bool m_snapImgFlag;
        int m_scaleValue;
    	bool m_saveTempMatFlag;						 // 保存温度矩阵
    
    	int m_selectX;							     // 指定点测温坐标 X
    	int m_selectY;	
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    #endif // IRMANAGE_H
    4.架构类中间架构类 IRManage.cpp

    #include "IRManage.h"
    #include 
    
    IRManage::IRManage()
    {
    	m_coreManage = new GuideCoreManage(nullptr);
    	m_IRWindow = new IRMainWindow();
    	m_IRWindow->show();
    
    	checkDataDir();	
    
    	m_videoQueueMutex = new std::mutex();
        m_TempQueueMutex = new std::mutex();
    	m_deviceDisconnect = false;
    
    	m_snapImgFlag = false;
    	m_scaleValue = 2;
    
    	m_selectX = 0;
    	m_selectY = 0;
    
    	m_videoQueue.clear();
    
    //    m_coreManage->registerDeviceDisconnectCb(GuideDeviceDisconnectCb, this);
    
    	connect(m_IRWindow, &IRMainWindow::sig_startConnect, this, &IRManage::slot_open);
    	connect(m_IRWindow, &IRMainWindow::sig_startDisConnect, this, &IRManage::slot_close);
    	connect(m_IRWindow, &IRMainWindow::sig_shutter, this, &IRManage::slot_shutter);
    	connect(m_IRWindow, &IRMainWindow::sig_NUC, this, &IRManage::slot_NUC);
    	connect(m_IRWindow, &IRMainWindow::sig_PaletteChange, this, &IRManage::slot_PaletteChange);
    	connect(m_IRWindow, &IRMainWindow::sig_scalChange, this, &IRManage::slot_scalChange);
        //connect(&m_getConnectProgressTimer, &QTimer::timeout, this, &IRManage::slotGetConnectProgressTimer);
    	connect(&m_refVideoTimer, &QTimer::timeout, this, &IRManage::slot_refVideoTimer);
    	connect(&m_refTempTimer, &QTimer::timeout, this, &IRManage::slot_refTempTimer);
    	connect(m_IRWindow, &IRMainWindow::sig_snapImg, this, &IRManage::slot_snapeImage);
    
    	connect(this, &IRManage::sig_updateCenterTemp, m_IRWindow, &IRMainWindow::slot_updateCenterTemp);
    	connect(this, &IRManage::sig_updateCurPosTemp, m_IRWindow, &IRMainWindow::slot_updateCurPosTemp);
    	connect(this, &IRManage::sig_updateMinMaxTemp, m_IRWindow, &IRMainWindow::slot_updateMinMaxTemp);
    	connect(m_IRWindow, &IRMainWindow::sig_changeRange, this, &IRManage::slot_changeRange);
    
    	connect(m_IRWindow, &IRMainWindow::sig_shutterOff, this, &IRManage::slot_shutterClose);
    	connect(m_IRWindow, &IRMainWindow::sig_shutterOn, this, &IRManage::slot_shutterOpen);
    }
    
    IRManage::~IRManage()
    {
        delete m_coreManage;
        delete m_videoQueueMutex;
        delete m_TempQueueMutex;
        m_IRWindow->deleteLater();
    }
    
    void IRManage::slot_open()
    {
        m_coreManage->startConnect();
        m_coreManage->setCallackFunc((ImageCallBack)cbFuncHandle, this , 1);
        qDebug() << "open start";
    
        std::cout << "OnBnClickedOpenCamea open device..." << std::endl;
    
    //    m_getConnectProgressTimer.start(500);
    
        return;
    }
    
    void IRManage::slot_close()
    {
        m_coreManage->startDisConnect();
    	m_refTempTimer.stop();
    	m_refVideoTimer.stop();
    }
    
    void IRManage::slot_shutter()
    {
       // m_coreManage->doShutter();
    }
    
    void IRManage::slot_shutterClose()
    {
        //m_coreManage->doShutterOff();
    }
    
    
    void IRManage::slot_shutterOpen()
    {
        //m_coreManage->doShutterOn();
    }
    
    void IRManage::slot_NUC()
    {
        //m_coreManage->doNUC();
    }
    
    void IRManage::slot_scalChange(int para)
    {
        m_scaleValue = para;
    
    }
    
    void IRManage::slot_PaletteChange(int para)
    {
    	// TODO: 在此添加控件通知处理程序代码
    	switch (para)
    	{
    	case 0:
    		m_coreManage->setPaletteType(GUIDE_FIRST_PALETTE);
    		break;
    	case 1:
    		m_coreManage->setPaletteType(GUIDE_SECOND_PALETTE);
    		break;
    	case 2:
    		m_coreManage->setPaletteType(GUIDE_THIRD_PALETTE);
    		break;
    	case 3:
    		m_coreManage->setPaletteType(GUIDE_FOURTH_PALETTE);
    		break;
    	case 4:
    		m_coreManage->setPaletteType(GUIDE_FIFTH_PALETTE);
    		break;
    	case 5:
    		m_coreManage->setPaletteType(GUIDE_SIXTH_PALETTE);
    		break;
    	case 6:
    		m_coreManage->setPaletteType(GUIDE_SEVENTH_PALETTE);
    		break;
    	case 7:
    		m_coreManage->setPaletteType(GUIDE_EIGHTH_PALETTE);
    		break;
    	case 8:
    		m_coreManage->setPaletteType(GUIDE_NINTEEN_PALETTE);
    	case 9:
    		m_coreManage->setPaletteType(GUIDE_TWETEEN_PALETTE);
    		break;
    	default:
    		break;
    	}
    }
    
    void IRManage::slot_snapeImage()
    {
    	m_snapImgFlag = true;
    }
    
    void IRManage::slot_saveTempMat()
    {
    	// 检测文件夹存在
    	QString path = QDir::currentPath() + "/TempMatrix";//获取当前工程目录
    	qDebug() << "当前保存温度矩阵目录: " << path;
    	QDir dir(path);
    	if (!dir.exists()) {
    		dir.mkdir(path);
    	}
    
    	// 保存温度矩阵
        //m_coreManage->saveTemp();
    }
    
    void IRManage::slot_setOpenShutterOffPower(bool status)
    {
        //m_coreManage->setOpenShutterOffPower(status);
    }
    
    void IRManage::slot_updateAsic()
    {
    	//定义文件对话框类
    	QFileDialog *fileDialog = new QFileDialog();
    
    	//定义文件对话框标题
    	fileDialog->setWindowTitle(QStringLiteral("选择固件升级包"));
    
    	//设置打开的文件路径
    	fileDialog->setDirectory("./");
    
    	//设置文件过滤器,只显示.ui .cpp 文件,多个过滤文件使用空格隔开
    	fileDialog->setNameFilter(tr("File(*.bin* *.uimg*)"));
    
    	//设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles
    	fileDialog->setFileMode(QFileDialog::ExistingFiles);
    
    	//设置视图模式
    	fileDialog->setViewMode(QFileDialog::Detail);
    
    	//获取选择的文件的路径
    	QStringList fileNames;
    	if (fileDialog->exec()) {
    		fileNames = fileDialog->selectedFiles();
    	}
    	if (!fileNames.isEmpty()){
    		QString cfileName  = fileNames.first();
    
    		QByteArray tmpName = cfileName.toLocal8Bit();
    		m_getUpdateProgressTimer.start(500);
            //m_coreManage->startUpdata(tmpName.data());
    		printf("update file path :%s ", tmpName.data());
    	}
    
    	fileDialog->deleteLater();
    }
    
    void IRManage::slot_changeRange(int range)
    {
        //m_coreManage->sendCmdToUsb(GUIDE_SET_TEMP_GRADE_CMD, range);
    }
    
    void IRManage::slot_getUpdateProgressTimer()
    {
    //	bool updataResult = false;
    //	if (!m_coreManage->getWorkProgress(updataResult))
    //	{
    //		GUI_PN("updataResult:%d", updataResult);
    
    //		QMessageBox dialog;
    //		dialog.addButton(tr("OK"), QMessageBox::ActionRole);
    //		if (updataResult)
    //		{
    //            dialog.setText("operation success");
    //			GUI_PN("%s", "updata success!");
    //			m_getConnectProgressTimer.stop();
    //		}
    //		else
    //		{
    //            dialog.setText("operation failed!");
    //			m_getConnectProgressTimer.stop();
    //		}
    //		dialog.exec();
    //		m_getUpdateProgressTimer.stop();
    //	}
    }
    
    void IRManage::slot_reFactorySet()
    {
        //m_coreManage->reFactorySetting();
    }
    
    void IRManage::slot_updatePos(int x, int y)
    {
    	m_selectX = x;
    	m_selectY = y;
    }
    
    void IRManage::slot_recordVideo(bool para)
    {
        //m_coreManage->saveYuvData(para);
    }
    
    //void IRManage::slotGetConnectProgressTimer()
    //{
    //    bool connectState = false;
    //    if (m_coreManage->getWorkProgress(connectState) == false)
    //    {
    //        if (connectState)
    //        {
    //            m_getConnectProgressTimer.stop();
    //            m_refVideoTimer.start(5);		// 启动数据刷新显示
    //            m_refUiInfoTimer.start(1000);
    //            m_refTempTimer.start(300);
    //            m_tryConnectTimes = 0;
    //            m_deviceDisconnect = false;
    
    //            emit sig_connectSuccess();
    //        }
    //        else if (m_tryConnectTimes < 10)
    //        {
    //            m_tryConnectTimes++;
    //        }
    //        else
    //        {
    //            m_deviceDisconnect = true;
    //            printf("device be occupied.\n");
    //        }
    //    }
    //}
    
    
    void  IRManage::slot_refVideoTimer()
    {
        m_videoQueueMutex->lock();
    
        if (m_videoQueue.size())
        {
            unsigned char * data = m_videoQueue.front();
            unsigned char * rgb = (unsigned char *)malloc(256 * 192 * 3);
    		yuv422torgb(rgb, data, GUIDE_RES_WIDETH, GUIDE_RES_HEIGHT);
    
            // 显示图片到控件上
            // ShowRGBToWnd(IDC_STATICPICTURE, rgb, GUIDE_RES_WIDETH, GUIDE_RES_HEIGHT);
    		QPixmap pix = QPixmap::fromImage(QImage(rgb, GUIDE_RES_WIDETH, GUIDE_RES_HEIGHT, QImage::Format_RGB888));    //Format_Grayscale16
    		m_IRWindow->slot_updateImg(&pix);																						 //m_IRWindow->slot_updateImg(pix);
    		if (m_snapImgFlag)
    		{
    			pix.scaled(GUIDE_RES_WIDETH, GUIDE_RES_HEIGHT, Qt::KeepAspectRatio, Qt::SmoothTransformation);
                saveImage(pix);
                m_snapImgFlag = false;
            }
            free(data);
            free(rgb);
            m_videoQueue.pop_front();
        }
        m_videoQueueMutex->unlock();
    }
    
    void IRManage::slot_refTempTimer()
    {
    
        m_TempQueueMutex->lock();
    
        if (m_TempDataQueue.size())
        {
            short * data = m_TempDataQueue.front();
    
            char tempStr[50] = { 0 };
    
            float temp = 0.0f;
            short centerY16 = data[256*192/2];
            m_coreManage->getBodyTemp(centerY16, temp);
            qDebug() << "center temperature f=" << temp;
            snprintf(tempStr, sizeof(tempStr), "%.2f", temp);
    
            cout << "center temp = " << tempStr << endl;
            QString cstr1(tempStr);
            qDebug() << "center temperature=" << cstr1;
    
            //	显示中心点人体温度
            emit sig_updateCenterTemp(cstr1);
    
            // 最高温,最低温建议复制到线程进行计算
            m_maxTemp = data[0];
            m_minTemp = data[0];
            for (int i = 0; i<GUIDE_RES_WIDETH * GUIDE_RES_HEIGHT; i++) {
                if (data[i] < m_minTemp) {
                    m_minTemp = data[i];
                }
                if (data[i] > m_maxTemp)  {
                    m_maxTemp = data[i];
                }
            }
    
            // 选择点的温度
            int size = m_selectX*m_selectY;
            short currPosY16 = data[size];
            float currPosTemp = 0.0f;
            m_coreManage->getBodyTemp(currPosY16, currPosTemp);
            qDebug() << "curPosTmp temperature=" <<  currPosTemp;
            QString strCurPosTmp = QString::number(currPosTemp);
    
            //	显示当前点温度
            emit sig_updateCurPosTemp(strCurPosTmp);
    
            QString min = QString::number(m_minTemp);
            QString max = QString::number(m_maxTemp);
            emit sig_updateMinMaxTemp(min, max);
            free(data);
            m_TempDataQueue.pop_front();
        }
    
        m_TempQueueMutex->unlock();
    }
    
    
    bool IRManage::yuv422torgb(unsigned char *rgbImageData, unsigned char *yuvImageData, short width, short height)
    {
        if (yuvImageData == NULL)
        {
            return -1;
        }
    
        if (rgbImageData == NULL)
        {
            rgbImageData = (unsigned char*)malloc(width * height * 3);
        }
    
        int y, u, v;
        int frame_size = width * height;
    
        for (int j = 0; j < height; j++)
        {
            unsigned char* pRGB = rgbImageData + j * width * 3;
            unsigned char* pY = yuvImageData + j * width;
            unsigned char* pU = yuvImageData + frame_size + (j >> 1) * width;
            unsigned char* pV = pU + (frame_size >> 1);
            for (int i = 0; i < width; i++)
            {
                y = *(pY + i);
                u = *(pU + (i >> 1));
                v = *(pV + (i >> 1));
    
                *(pRGB) = CLIPVALUE(YUVToR(y, u, v), 0, 255);
                *(pRGB + 1) = CLIPVALUE(YUVToG(y, u, v), 0, 255);
                *(pRGB + 2) = CLIPVALUE(YUVToB(y, u, v), 0, 255);
                pRGB += 3;
            }
        }
    
        return 0;
    }
    
    void IRManage::saveImage(QPixmap & img)
    {
    	QString path = QDir::currentPath();//获取当前工程目录
    	QDir dir(path);
    	QString newImgName = path + "/image";
    	dir.setPath(newImgName);
        int imgCout = dir.count() - 1;  // 文件夹下有一个父目录
        newImgName += ("/IMG_" + QString::number(imgCout) + ".png");
        img.save(newImgName, "png", 100);           // 按照百分百原图保存不损失质量
    }
    
    void IRManage::checkDataDir()
    {
    	// 检测文件夹存在
    	QString path = QDir::currentPath() + "/TempMatrix";//获取当前工程目录
    	QDir dir(path);
    	if (!dir.exists()) {
    		dir.mkdir(path);
    	}
    	dir.setPath(QDir::currentPath() + "/Y16");
    	if (!dir.exists()) {
    		dir.mkdir(QDir::currentPath() + "/Y16");
    	}
    
    	
    	dir.setPath(QDir::currentPath() + "/image");
    
    	if (!dir.exists()) {
    		dir.mkdir(QDir::currentPath() + "/image");
    	}
    }
    
    void IRManage::addfVidoPara(unsigned char *data)
    {
        m_videoQueueMutex->lock();
        int queueSize = m_videoQueue.size();
    
        if (queueSize > 30)
        {
            unsigned char *queueData = m_videoQueue.front();
            free(queueData);
            m_videoQueue.pop_front();
        }
    
        m_videoQueue.push_back(data);
        m_videoQueueMutex->unlock();
    }
    
    void IRManage::addfTemData(short *data)
    {
        m_TempQueueMutex->lock();
        int queueSize = m_TempDataQueue.size();
    
        if (queueSize > 30)
        {
            short *queueData = m_TempDataQueue.front();
            free(queueData);
            m_TempDataQueue.pop_front();
        }
    
        m_TempDataQueue.push_back(data);
        m_TempQueueMutex->unlock();
    }
    
    void IRManage::deviceDisconnect()
    {
        m_deviceDisconnect = true;
    //    GUI_PN("%s", "device disconnect!");
    }
    
    
    void GuideDeviceDisconnectCb(void *para)
    {
        if (NULL != para)
        {
            IRManage *manage = (IRManage *)para;
            manage->deviceDisconnect();
        }
    
        return;
    }
    
    int cbFuncHandle(CallBackData cbData, void *param, int scaleTime)
    {
        //实时画面更新操作
        if(cbData.yuvData) {
            //handleYuvData(cbData.yuvData, cbData.yuvLength, cbData.width, cbData.height);
            if (NULL != param)
            {
                IRManage *manage = (IRManage *)param;
                manage->addfVidoPara(cbData.yuvData);
            }
        }
    
        //实时y16测温数据更新操作
        if(cbData.y16Data){
            handleY16Data(cbData.y16Data, cbData.y16Length,cbData.width, cbData.height);
            if (NULL != param)
            {
                IRManage *manage = (IRManage *)param;
                manage->addfTemData(cbData.y16Data);
            }
        }
    
        scaleTime = 1;
    
        return 0;
    }
    
    void handleYuvData(unsigned char *pYuvData)
    {
        qDebug() << "get a yuv data" << sizeof(pYuvData);
    
    }
    
    void handleY16Data(short *pY16Data, const int &iLen, const int &iWidth, const int &iHeight)
    {
        qDebug() << "get a Y16 data";
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
  • 相关阅读:
    【变压器故障诊断分类及预测】基于GRNN神经网络
    Java代码的编译过程(没写完,不要点进来)
    Pytorch疑难小实验:理解torch.cat()在不同维度下的连接方式
    学习Hadoop的前提条件
    贪心算法篇——经典题型
    2019年数维杯数学建模A题 我国省际生态环境与经济交互状况的综合评价求解全过程文档及程序
    初识DQL语言
    【路径遍历漏洞】查找、利用、预防
    HTML5响应式网页设计——核心技能考核示例(用于2022年11月H5考核)
    基于asp.net的文献检索系统
  • 原文地址:https://blog.csdn.net/weixin_44075027/article/details/128045909