3:QT聯合HALCON編程—海康相機SDK二次程序開發

思路:

1.定義帶UI界面的主函數類

? ? ? ? ?1.1在主函數中包含其它所有類頭文件,進行聲明和實例化;使用相機時,是用公共相機的接口在某一個具體函數中去實例化具體的海康相機對象。

? ? ? ? 1.2設計界面:連接相機,單次采集,連續采集,停止采集,關閉相機

? ? ? ? 1.3在連續采集中,開始啟用線程。需要在線程類中采集圖像,通過信號與槽在主函數中接收并顯示圖像。

2.定義公共相機接口類

3.定義海康相機類

4.定義線程類

? ? ? ? 4.1里面包含:接收海康相機的函數,在主函數中可以直接調用線程里面的這個函數,并通過指針傳參。

? ? ? ? 4.2定義run函數,在函數里面采集圖像,并發送信號。

? ? ? ? ?4.3定義if語句判斷線程狀態,控制線程啟停。

? ? ? ? 4.4定義bool變量去結合if進行判斷

5.定義日志類

6.定義加載保存參數,公共結構體類

7.定義其它圖像處理功能類

? ? ? ? 7.1例如:測量,匹配,檢測等...............


1.主目錄框架

列表中含有:

1.src里面是圖像處理的各種模塊功能以及公共文件(日志和參數加載)

2.相機的公共接口類

3.Halcon類

4.海康相機類

5.主函數

6.線程類


2.定義公共相機接口(camerainterface)

camerainterface.h

#ifndef CAMERAINTERFACE_H
#define CAMERAINTERFACE_H#include "HalconCpp.h"
#include "HDevThread.h"
using namespace HalconCpp;
#include"iostream"
class CameraInterface
{
public:CameraInterface();~CameraInterface();//關閉相機采集 // ch:連接設備virtual int connectCamera(int id)=0;//設置是否為觸發模式virtual int setTriggerMode(unsigned int TriggerModeNum)=0;//開啟相機采集virtual int startCamera()=0;virtual int stopCamera()=0;//關閉相機virtual int closeCamera()=0;//軟觸發virtual int softTrigger()=0;//讀取buffervirtual int ReadBuffer(HObject &image)=0;//設置圖像高度virtual int setHeight(unsigned int height)=0;//設置圖像ROI寬度virtual int setWidth(unsigned int width)=0;//獲取圖像高度值virtual int getHeight()=0;//獲取圖像寬度值virtual int getWidth()=0;//獲取相機曝光時間virtual float getExposureTime()=0;//設置圖像水平偏移OffsetXvirtual int setOffsetX(unsigned int offsetX)=0;//設置圖像豎直偏移OffsetYvirtual int setOffsetY(unsigned int offsetY)=0;//設置觸發源virtual int setTriggerSource(unsigned int TriggerSourceNum)=0;//設置幀率控制使能virtual int setFrameRateEnable(bool comm)=0;//設置心跳時間virtual int setHeartBeatTime(unsigned int time)=0;//設置曝光時間virtual int setExposureTime(float ExposureTimeNum)=0;//設置增益virtual int setGain(float Gain)=0;//關閉自動曝光virtual int setExposureAuto(bool exposureAutoFlag)=0;//關閉自動增益virtual int setGainAuto(bool gainAutoFlag)=0;//virtual int setGain(float Gain)=0;//清理相機緩存virtual void clearBuffer()=0;
};#endif // CAMERAINTERFACE_H

3.定義海康相機類(hikvisionsdk)

1.hikvisionsdk.h文件,海康相機功能函數聲明(包含公共相機頭文件)

#ifndef HIKVISIONSDK_H
#define HIKVISIONSDK_H
#include"camerainterface.h"
#include"MvCameraControl.h"
#include "HalconCpp.h"
#include "HDevThread.h"
#include <QImage>
using namespace HalconCpp;
class HikvisionSDK:public CameraInterface
{
public:HikvisionSDK();~HikvisionSDK();// ch:連接設備//int connectCamera(std::string id);int connectCamera(int id);//設置是否為觸發模式int setTriggerMode(unsigned int TriggerModeNum);//開啟相機采集int startCamera();//關閉相機采集int stopCamera();//關閉相機int closeCamera();//軟觸發int softTrigger();//讀取bufferint ReadBuffer(HObject &image);//設置圖像高度int setHeight(unsigned int height);//設置圖像ROI寬度int setWidth(unsigned int width);//獲取圖像高度值int getHeight();//獲取圖像寬度值int getWidth();//獲取相機曝光時間float getExposureTime();//設置圖像水平偏移OffsetXint setOffsetX(unsigned int offsetX);//設置圖像豎直偏移OffsetYint setOffsetY(unsigned int offsetY);//設置觸發源int setTriggerSource(unsigned int TriggerSourceNum);//設置幀率控制使能int setFrameRateEnable(bool comm);//設置心跳時間int setHeartBeatTime(unsigned int time);//設置曝光時間int setExposureTime(float ExposureTimeNum);//設置增益int  setGain(float Gain);//關閉自動曝光int setExposureAuto(bool exposureAutoFlag);//關閉自動增益int setGainAuto(bool gainAutoFlag);//清理相機緩存void clearBuffer();bool QImage2HObject(QImage &qImg, HObject &hImg);private:void*         m_hDevHandle;
public:// 用于保存圖像的緩存unsigned int    m_nBufSizeForSaveImage;// 用于從驅動獲取圖像的緩存unsigned int    m_nBufSizeForDriver;
};#endif // HIKVISIONSDK_H

2.hikvisionsdk.cpp文件(海康相機各功能實現)

在讀圖相機中圖像函數里面有個事件,此時需要找到自己相機的型號才能執行,要不然程序容易閃退

#include "hikvisionsdk.h"MV_CC_DEVICE_INFO_LIST m_stDevList;         // ch:設備信息列表結構體變量,用來存儲設備列表
MV_CC_DEVICE_INFO* m_Device=NULL;                 //設備對象#include <QDebug>
#include <QString>
#include <QDebug>
HikvisionSDK::HikvisionSDK()
{m_hDevHandle    = NULL;
}HikvisionSDK::~HikvisionSDK()
{if (m_hDevHandle){MV_CC_DestroyHandle(m_hDevHandle);m_hDevHandle    = NULL;}
}//連接相機
int  HikvisionSDK::connectCamera(int id)
{// Enum deviceMV_CC_DEVICE_INFO_LIST stDeviceList;memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);if (nRet!=0){qDebug()<<"nRet:="<<nRet;return -1;}if (stDeviceList.nDeviceNum > 0){for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++){MV_CC_DEVICE_INFO* pDeviceInfo = stDeviceList.pDeviceInfo[i];if (NULL == pDeviceInfo){break;}}}else{return -1;}unsigned int nIndex = 0;// Select device and create handlenRet = MV_CC_CreateHandle(&m_hDevHandle, stDeviceList.pDeviceInfo[nIndex]);if (nRet!=0){//printf("Create Handle fail! nRet [0x%x]\n", nRet);return -1;}// open devicenRet = MV_CC_OpenDevice(m_hDevHandle);if (nRet!=0){//printf("Open Device fail! nRet [0x%x]\n", nRet);return -1;}return 0;
}//啟動相機采集
int HikvisionSDK::startCamera()
{int tempValue=MV_CC_StartGrabbing(m_hDevHandle);if(tempValue!=0){return -1;}else{return 0;}
}//停止相機采集
int HikvisionSDK::stopCamera()
{int tempValue=MV_CC_StopGrabbing(m_hDevHandle);if(tempValue!=0){return -1;}else{return 0;}
}//關閉相機
int HikvisionSDK::closeCamera()
{if (NULL == m_hDevHandle){return -1;}MV_CC_CloseDevice(m_hDevHandle);int tempValue = MV_CC_DestroyHandle(m_hDevHandle);m_hDevHandle = NULL;if(tempValue!=0){return -1;}else{return 0;}
}//發送軟觸發
int HikvisionSDK::softTrigger()
{int tempValue= MV_CC_SetCommandValue(m_hDevHandle, "TriggerSoftware");if(tempValue!=0){return -1;}else{return 0;}
}//讀取相機中的圖像
int HikvisionSDK::ReadBuffer(HObject &halconImage)
{//Mat* getImage=new Mat();unsigned int nRecvBufSize = 0;MVCC_INTVALUE stParam;qDebug()<<"enter3";memset(&stParam, 0, sizeof(MVCC_INTVALUE));int tempValue = MV_CC_GetIntValue(m_hDevHandle, "PayloadSize", &stParam);qDebug()<<"enter4";if (tempValue != 0){return -1;}//分配一個指針的內存大小 ,  c語言的庫函數  malloc;nRecvBufSize = stParam.nCurValue;//指針  圖像接收數據的指針unsigned char* pDate;pDate=(unsigned char *)malloc(nRecvBufSize);qDebug()<<"enter41";//句柄  指針   nRecvBufSize  700 ,  輸出  (指針和圖像信息的結構體)stImageInfo。MV_FRAME_OUT_INFO_EX stImageInfo = {0};tempValue= MV_CC_GetOneFrameTimeout(m_hDevHandle, pDate, nRecvBufSize, &stImageInfo, 700);if(tempValue!=0){return -1;}
//    m_nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
//    unsigned char* m_pBufForSaveImage;
//    m_pBufForSaveImage = (unsigned char*)malloc(m_nBufSizeForSaveImage);qDebug()<<"enter42";bool isMono;//HObject halconImage;//stImageInfo.enPixelType//像素格式  的  stImageInfo  ,switch  調整,switch (stImageInfo.enPixelType){case PixelType_Gvsp_Mono8:case PixelType_Gvsp_Mono10:case PixelType_Gvsp_Mono10_Packed:case PixelType_Gvsp_Mono12:case PixelType_Gvsp_Mono12_Packed:case      17301512:isMono=true;break;default:isMono=false;break;}if(isMono){//*getImage=Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC1,pDate);//imwrite("d:\\測試opencv_Mono.tif", image);qDebug()<<" stImageInfo.nHeight:"<< stImageInfo.nHeight;qDebug()<<" stImageInfo.nWidth:"<< stImageInfo.nWidth;qDebug()<<"pDate:"<<pDate;GenImage1(&halconImage, "byte", stImageInfo.nWidth,stImageInfo.nHeight,(Hlong)(pDate));//轉換為hoject
//        GenImage1(&hImg, "byte", tFrameInfo.iWidth, tFrameInfo.iHeight, (Hlong)m_pchImgBuffer[camId]);
//         qDebug()<<"pDate11:"<<pDate;//WriteImage(halconImage, "png", 0, "./picture/halcon_Mono.png");}else{//轉換圖像格式為BGR8MV_CC_PIXEL_CONVERT_PARAM stConvertParam = {0};memset(&stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));stConvertParam.nWidth = stImageInfo.nWidth;                 //ch:圖像寬 | en:image widthstConvertParam.nHeight = stImageInfo.nHeight;               //ch:圖像高 | en:image height//stConvertParam.pSrcData = m_pBufForDriver;                  //ch:輸入數據緩存 | en:input data bufferstConvertParam.pSrcData = pDate;                  //ch:輸入數據緩存 | en:input data bufferstConvertParam.nSrcDataLen = stImageInfo.nFrameLen;         //ch:輸入數據大小 | en:input data sizestConvertParam.enSrcPixelType = stImageInfo.enPixelType;    //ch:輸入像素格式 | en:input pixel formatstConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed; //ch:輸出像素格式 | en:output pixel format  適用于OPENCV的圖像格式//stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed; //ch:輸出像素格式 | en:output pixel format//stConvertParam.pDstBuffer = m_pBufForSaveImage;                    //ch:輸出數據緩存 | en:output data bufferstConvertParam.nDstBufferSize = m_nBufSizeForSaveImage;            //ch:輸出緩存大小 | en:output buffer sizeMV_CC_ConvertPixelType(m_hDevHandle, &stConvertParam);QImage img = QImage((const uchar*)pDate,  stImageInfo.nWidth,stImageInfo.nHeight, QImage::Format_RGB888);QImage2HObject(img, halconImage);//QImage2HObject(img, hImg);//halconImage  輸出  rgb   hobject 格式的圖像 。//因為 這里沒有 圖片 輸出  所以 代碼就奔潰了。//*getImage=Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC3,m_pBufForSaveImage);//imwrite("d:\\測試opencv_Color.tif", image);}//CopyImage(halconImage, &image);free(pDate);//free(m_pBufForSaveImage);return 0;
}//Qimage  轉換成 hobject image
bool HikvisionSDK::QImage2HObject(QImage &qImg, HObject &hImg)
{try{if (qImg.isNull()) return false;int width = qImg.width();int height = qImg.height();QImage::Format format = qImg.format();if (format == QImage::Format_RGB32 ||format == QImage::Format_ARGB32 ||format == QImage::Format_ARGB32_Premultiplied){GenImageInterleaved(&hImg, Hlong(qImg.bits()), "bgrx", width, height, 0, "byte", width, height, 0, 0, 8, 0);}else if (format == QImage::Format_RGB888){GenImageInterleaved(&hImg, Hlong(qImg.bits()), "bgr", width, height, 0, "byte", width, height, 0, 0, 8, 0);}else if (format == QImage::Format_Grayscale8 || format == QImage::Format_Indexed8){GenImage1Extern(&hImg, "byte", width, height, Hlong(qImg.bits()), NULL);}}catch (const std::exception&){return false;}return true;
}//獲取圖像高度值
int HikvisionSDK::getHeight()
{MVCC_INTVALUE stParam;memset(&stParam, 0, sizeof(MVCC_INTVALUE));int tempValue=MV_CC_GetIntValue(m_hDevHandle, "Height", &stParam);int value= stParam.nCurValue;if(tempValue!=0){return -1;}else{return value;}
}//獲取圖像寬度值
int HikvisionSDK::getWidth()
{MVCC_INTVALUE stParam;memset(&stParam, 0, sizeof(MVCC_INTVALUE));int tempValue=MV_CC_GetIntValue(m_hDevHandle, "Width", &stParam);int value= stParam.nCurValue;if(tempValue!=0){return -1;}else{return value;}
}//獲取相機曝光時間
float HikvisionSDK::getExposureTime()
{MVCC_FLOATVALUE stParam;memset(&stParam, 0, sizeof(MVCC_INTVALUE));int tempValue=MV_CC_GetFloatValue(m_hDevHandle, "ExposureTime", &stParam);float value= stParam.fCurValue;if(tempValue!=0){return -1;}else{return value;}
}//設置圖像ROI高度
int HikvisionSDK::setHeight(unsigned int height)
{int tempValue=MV_CC_SetIntValue(m_hDevHandle, "Height", height);if(tempValue!=0){return -1;}else{return 0;}
}//設置圖像ROI寬度
int HikvisionSDK::setWidth(unsigned int width)
{int tempValue=MV_CC_SetIntValue(m_hDevHandle, "Width", width);if(tempValue!=0){return -1;}else{return 0;}
}//設置圖像水平偏移OffsetX
int HikvisionSDK::setOffsetX(unsigned int offsetX)
{int tempValue=MV_CC_SetIntValue(m_hDevHandle, "OffsetX", offsetX);if(tempValue!=0){return -1;}else{return 0;}
}//設置圖像豎直偏移OffsetY
int HikvisionSDK::setOffsetY(unsigned int offsetY)
{int tempValue=MV_CC_SetIntValue(m_hDevHandle, "OffsetY", offsetY);if(tempValue!=0){return -1;}else{return 0;}
}//設置是否為觸發模式
int HikvisionSDK::setTriggerMode(unsigned int TriggerModeNum)
{//0:Off  1:Onint tempValue= MV_CC_SetEnumValue(m_hDevHandle,"TriggerMode", TriggerModeNum);if(tempValue!=0){return -1;}else{return 0;}
}//設置觸發源
int HikvisionSDK::setTriggerSource(unsigned int TriggerSourceNum)
{//0:Line0  1:Line1  7:Softwareint tempValue= MV_CC_SetEnumValue(m_hDevHandle,"TriggerSource", TriggerSourceNum);if(tempValue!=0){return -1;}else{return 0;}
}//設置幀率控制使能
int HikvisionSDK::setFrameRateEnable(bool comm)
{int tempValue =MV_CC_SetBoolValue(m_hDevHandle, "AcquisitionFrameRateEnable", comm);if (tempValue != 0){return -1;}else{return 0;}
}//設置心跳時間
int HikvisionSDK::setHeartBeatTime(unsigned int time)
{//心跳時間最小為500msif(time<500)time=500;int tempValue=MV_CC_SetIntValue(m_hDevHandle, "GevHeartbeatTimeout", time);if(tempValue!=0){return -1;}else{return 0;}
}//設置曝光時間
int HikvisionSDK::setExposureTime(float ExposureTimeNum)
{int tempValue= MV_CC_SetFloatValue(m_hDevHandle, "ExposureTime",ExposureTimeNum );if(tempValue!=0){return -1;}else{return 0;}
}//設置曝光時間
int HikvisionSDK::setGain(float Gain)
{int tempValue= MV_CC_SetFloatValue(m_hDevHandle, "Gain",Gain);if(tempValue!=0){return -1;}else{return 0;}
}//關閉自動曝光
int HikvisionSDK::setExposureAuto(bool exposureAutoFlag)
{int tempValue= MV_CC_SetEnumValue(m_hDevHandle,"ExposureAuto", exposureAutoFlag);if (tempValue != 0){return -1;}else{return 0;}
}//關閉自動增益
int HikvisionSDK::setGainAuto(bool gainAutoFlag)
{int tempValue= MV_CC_SetEnumValue(m_hDevHandle,"GainAuto", gainAutoFlag);if (tempValue != 0){return -1;}else{return 0;}
}//清理相機緩存
void HikvisionSDK::clearBuffer()
{//stopCamera();//startCamera();
}

4.在主程序相機實例化

1.首先包含公共相機和海康相機的頭文件

2.用公共相機接口去實例化海康相機

.h主文件

private: 
//相機指針CameraInterface * camera=NULL;

.cpp主文件

  camera=new HikvisionSDK();用公共相機接口實例化海康相機類

析構函數中

if(camera!=NULL){delete camera;camera=NULL;}

5.連接相機

1.在IU界面下添加連接相機按鈕轉到槽函數

//連接相機
void MainWindow::on_btn_Connect_clicked()
{//初始化相機句柄if(camera!=NULL){delete camera;camera=NULL;}qDebug()<<111;if(camera==NULL){qDebug()<<112;InitCam();//連接相機函數//控制按鈕是否可以按下ui->btn_Close->setEnabled(false);ui->btn_Connect->setEnabled(false);ui->btn_Trigger->setEnabled(true);ui->lxcj->setEnabled(true);ui->StopAcquisition->setEnabled(true);}}

2.連接相機函數實現

注意:次函數是實例化具體的相機(因為在項目中可能用到不同類型的相機,所以在頭文件首先用公共相機接口)然后在具體的連接相機下面去實例化具體的相機類型對象。

? 最后一行程序,是把這個具體的海康相機對象通過傳參,傳入到線程類中去。

void MainWindow::InitCam()
{camera=new HikvisionSDK();此時用到了上面提到的海康相機實例化//連接相機//std::cout<<"Connect:  "<<camera->connectCamera(1)<<std::endl;int  ret=camera->connectCamera(1);if(ret!=0){//失敗//QMessageBox::warning()}//設置為觸發模式  打開std::cout<<"TriggerMode:  "<<camera->setTriggerMode(1)<<std::endl;//設置觸發源為軟觸發std::cout<<"TriggerSource:  "<<camera->setTriggerSource(7)<<std::endl;//設置曝光時間std::cout<<"SetExposureTime:  "<<camera->setExposureTime(40000)<<std::endl;//開啟相機采集std::cout<<"StartCamera:  "<<camera->startCamera()<<std::endl;myThread->getCameraPtr(camera);//把實例化后的海康相機類傳入到線程中去//myThread->getImagePtr(myImage);}

6.定義線程類(mythread)

1.在線程里面需要包含公共相機的頭文件

#include "QThread"//線程
#include "camerainterface.h"//公共相機接口
#include <QImage>

2.頭文件定義接收海康相機類的函數

    void getCameraPtr(CameraInterface* camera);

3..cpp文件具體實現

//析構函數
MyThread::~MyThread()
{if(cameraPtr==NULL){delete cameraPtr;}
}//具體實現
void MyThread::getCameraPtr(CameraInterface *camera)
{cameraPtr=camera;
}

7.單次采集

1.在IU界面添加單次采集按鈕轉跳槽函數

2.需要在主頭文件中,private: 下面去聲明 bool IsRun = false;(目的是為了更好的調節相機采圖啟停,方便后續操作(在這里可以不用))

3.轉到線程中,去執行停止線程工作內容(因為單次采集不需要啟動線程)

//單次采集
void MainWindow::on_btn_Trigger_clicked()
{HObject image;HTuple hv_Width,hv_Height;IsRun =true;//單次采圖狀態myThread->ChangeCloseStatus();//線程狀態啟停std::cout<<"TriggerMode:  "<<camera->setTriggerMode(1)<<std::endl;std::cout<<"SoftTrigger:  "<<camera->softTrigger()<<std::endl;//讀取Mat格式的圖像qDebug()<<"enter1";camera->ReadBuffer(image);   //相機類里面的讀圖函數CopyImage(image, &halconImage);if(ui->checkBox_saveImage->isChecked()){//保存圖像QString path="./data/"+QString::number(ui->sB_Num->value())+".png";WriteImage(halconImage, "png", 0, HTuple(path.toLatin1().data()));}GetImageSize(image, &hv_Width, &hv_Height);SetPart(WindowHandle, 0, 0, hv_Height,hv_Width); // 1944 2592qDebug()<<"enter2";DispObj(halconImage, WindowHandle);//其它圖像處理功能//m_pMeasure01->OutMeasure01(halconImage);
}

4.在線程類中,.h的public:下定義 bool Status=false;

同時定義線程狀態啟停函數

    void ChangeCloseStatus();//關閉void ChangeOpenStatus();//打開.cpp文件void MyThread::ChangeCloseStatus()
{Status=false;//qDebug()<<"Status:="<<Status;
}void MyThread::ChangeOpenStatus()
{Status=true;//qDebug()<<"Status:="<<Status;
}


8.連續采集

1.此時需要利用線程進行連續圖像采集,需要在主程序中實例化線程類(應該在一開始就實例化)

    //線程對象MyThread* myThread=NULL;
   //  線程對象實例化myThread = new MyThread();
    if(myThread!=NULL){delete myThread;myThread=NULL;}

2.在IU界面上添加連續采集按鈕轉到槽函數

void MainWindow::on_lxcj_clicked()
{std::cout<<"TriggerMode:  "<<camera->setTriggerMode(0)<<std::endl;myThread->ChangeOpenStatus();//打開線程工作內容if(!IsRun)//判斷單次采集是否打開{IsRun = false;關閉單次采集myThread->start();//開啟連續彩圖線程}else{IsRun = false;//關閉單次采集myThread->start();//開啟連續彩圖線程}
}

3.在線程類里面

.h文件

    void run();//定義run函數(線程里的工作內容)void display( HObject imagePtr);//(用來其它作用顯示)signals:void CaptureImage(HObject);//定義一個發送圖像的信號

.cpp文件

void MyThread::run()
{if(cameraPtr==NULL){return;}while(!isInterruptionRequested()){if(Status)  //判斷是否停止的狀態{qDebug()<<"thread current" <<currentThread();std::cout<<"Thread_Trigger:"<<cameraPtr->softTrigger()<<std::endl;HObject image;//讀取Mat格式的圖像cameraPtr->ReadBuffer(image);emit CaptureImage(image);//發送圖像信號msleep(100);}}
}
void MyThread::display( HObject imagePtr)
{//qDebug()<<"Enter2";//std::cout<<"so"<<std::endl;//判斷是黑白、彩色圖像DispObj((imagePtr), WindowHandle);QString path="./picture/halcon"+QString::number(1)+".png";//WriteImage((*imagePtr), "png", 0, HTuple(path.toLatin1().data()));//int num=ui->sB_Num->value();//ui->sB_Num->setValue(num+1);
}

4.在線程中發送圖像信號之后,需要在主函數中去接收這個圖像信號

 //信號與槽connect(myThread,SIGNAL(CaptureImage(HObject)),this,SLOT(ImageProcess01(HObject)),\Qt::BlockingQueuedConnection);//信號槽函數   。必須display  是slot
private slots://顯示連續圖像,接收槽函數void ImageProcess01(HObject image); //信號槽函數  --收到圖像之后的  圖像處理槽函數

//槽函數接收顯示圖像
void MainWindow::ImageProcess01(HObject halconImage)
{HTuple hv_Width,hv_Height;qDebug()<<"Enter1";GetImageSize(halconImage, &hv_Width, &hv_Height);SetPart(WindowHandle, 0, 0, hv_Height,hv_Width); // 1944 2592display(halconImage);m_pMeasure01->OutMeasure01(halconImage);  //輸出一個寬度//tuple -length  ,length ==1   識別 成功//TCP  服務器 發給客戶端  ,一個字符串。myThread->ChangeOpenStatus();//采圖   收到圖像處理完的信號,可以啟動繼續采圖。同步采集!qDebug()<<"Enter2";}

9.停止采集

void MainWindow::on_StopAcquisition_clicked()
{myThread->ChangeCloseStatus();//停止線程狀態ui->btn_Close->setEnabled(true);if(IsRun){myThread->requestInterruption();myThread->wait();//線程等待IsRun =false;//單次采集關閉// camera->stopCamera();// camera->closeCamera();}
}

10.關閉相機

void MainWindow::on_btn_Close_clicked()
{ui->btn_Trigger->setEnabled(false);ui->lxcj->setEnabled(false);ui->StopAcquisition->setEnabled(false);if(camera!=NULL){myThread->requestInterruption();camera->closeCamera();}//ui->Image_Label->clear();ui->btn_Connect->setEnabled(true);}

11.保存圖像

void MainWindow::on_saveImage_clicked()
{QString filePath ="./data/picture/"+ QDateTime::currentDateTime().toString("yyyy-MM-dd");HTuple file1=HTuple(filePath.toStdString().c_str());WriteImage(halconImage, "bmp", 0, file1);//ui->textBrowser_log->append("write image success.");
}

12.設置曝光、增益

//曝光
void MainWindow::on_pB_exposTime_clicked()
{int exposTime=ui->sB_exposure->value();int ret=camera->setExposureTime(exposTime);qDebug()<<"ret:="<<ret;
}//增益
void MainWindow::on_pB_setGain_clicked()
{int Gain =ui->sB_Gain->value();int ret=camera->setGain(Gain);qDebug()<<"ret:="<<ret;
}

13.保存參數

//把界面的參數  固化 到 本地文件
void Measure01::on_pB_saveParameters_clicked()
{/*AmplitudeThreshold = 23;RoiWidthLen = 67;Alpha1 = 3.4;LineRowStart = 879.281;LineColumnStart = 1436.34;LineRowEnd = 1769.58;LineColumnEnd = 3055.55;*///把界面的參數 賦值 給局部作用域的變量MeasureParam01.AmplitudeThreshold=ui->SpinBox_AmpThre->value();MeasureParam01.Alpha1=ui->SpinBox_Alpha1->value();MeasureParam01.RoiWidthLen=ui->SpinBox_RoiWidthLen->value();MeasureParam01.LineRowStart=ui->SpinBox_LineRowStart->value();MeasureParam01.LineColumnStart=ui->SpinBox_LineColumnStart->value();MeasureParam01.LineRowEnd=ui->SpinBox_LineRowEnd->value();MeasureParam01.LineColumnEnd=ui->SpinBox_LineColumnEnd->value();//再通過qsetting的方法 把參數保存到qt 本地的 文件中去SaveSetting(CONFIG_FILEPATH,"Measure01","AmplitudeThreshold",\QVariant(MeasureParam01.AmplitudeThreshold));//AmpThreSaveSetting(CONFIG_FILEPATH,"Measure01","Alpha1",\QVariant(MeasureParam01.Alpha1));//AmpThreSaveSetting(CONFIG_FILEPATH,"Measure01","RoiWidthLen",\QVariant(MeasureParam01.RoiWidthLen));//AmpThreSaveSetting(CONFIG_FILEPATH,"Measure01","LineRowStart",\QVariant(MeasureParam01.LineRowStart));//AmpThreSaveSetting(CONFIG_FILEPATH,"Measure01","LineColumnStart",\QVariant(MeasureParam01.LineColumnStart));//AmpThreSaveSetting(CONFIG_FILEPATH,"Measure01","LineRowEnd",\QVariant(MeasureParam01.LineRowEnd));//AmpThreSaveSetting(CONFIG_FILEPATH,"Measure01","LineColumnEnd",\QVariant(MeasureParam01.LineColumnEnd));//AmpThre}

14.加載參數

構造函數里面

 // //把界面的參數 賦值 給局部作用域的變量//double AmpThre=ui->SpinBox_AmpThre->value();//再通過qsetting的方法 把參數保存到qt 本地的 文件中去//SaveSetting(CONFIG_FILEPATH,"Measure01","AmplitudeThreshold",QVariant(AmpThre));//AmpThreQVariant ValueAmpThre;QVariant ValueAlpha1;QVariant ValueRoiWidthLen;QVariant ValueRowStart;QVariant ValueColumnStart;QVariant ValueRowEnd;QVariant ValueColumnEnd;LoadSetting(CONFIG_FILEPATH,"Measure01","AmplitudeThreshold",ValueAmpThre);LoadSetting(CONFIG_FILEPATH,"Measure01","Alpha1",ValueAlpha1);//AmpThreLoadSetting(CONFIG_FILEPATH,"Measure01","RoiWidthLen",ValueRoiWidthLen);//AmpThreLoadSetting(CONFIG_FILEPATH,"Measure01","LineRowStart",ValueRowStart);//AmpThreLoadSetting(CONFIG_FILEPATH,"Measure01","LineColumnStart",ValueColumnStart);//AmpThreLoadSetting(CONFIG_FILEPATH,"Measure01","LineRowEnd",ValueRowEnd);//AmpThreLoadSetting(CONFIG_FILEPATH,"Measure01","LineColumnEnd",ValueColumnEnd);//AmpThre//把QVariant 類型 轉換 double 類型MeasureParam01.AmplitudeThreshold=ValueAmpThre.toDouble();MeasureParam01.Alpha1=ValueAlpha1.toDouble();MeasureParam01.RoiWidthLen=ValueRoiWidthLen.toDouble();MeasureParam01.LineRowStart=ValueRowStart.toDouble();MeasureParam01.LineColumnStart=ValueColumnStart.toDouble();MeasureParam01.LineRowEnd=ValueRowEnd.toDouble();MeasureParam01.LineColumnEnd=ValueColumnEnd.toDouble();ui->SpinBox_AmpThre->setValue(MeasureParam01.AmplitudeThreshold);ui->SpinBox_Alpha1->setValue(MeasureParam01.Alpha1);ui->SpinBox_RoiWidthLen->setValue(MeasureParam01.RoiWidthLen);ui->SpinBox_LineRowStart->setValue(MeasureParam01.LineRowStart);ui->SpinBox_LineColumnStart->setValue(MeasureParam01.LineColumnStart);ui->SpinBox_LineRowEnd->setValue(MeasureParam01.LineRowEnd);ui->SpinBox_LineColumnEnd->setValue(MeasureParam01.LineColumnEnd);ui->SpinBox_AmpThre->setStyleSheet("background-color: green");

15.日志類(lxlog)

.h

#ifndef __LX_LOG_H__
#define __LX_LOG_H__#include<QString>
#include <QTextBrowser>void WriteLog(QString LogType, QString str);
void MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);#endif

.cpp

#include "lxlog.h"
#include "paramsconfig.h"
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QTextBrowser>extern QTextBrowser * g_pTb;void WriteLog(QString LogType, QString str)
{//文件名QString filePath = QString(LOG_PATH) + '/'+ QDateTime::currentDateTime().toString("yyyy-MM-dd")+".log";//時間QString strToWrite = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");//類型strToWrite.append(QString(" %1 ").arg(LogType));//信息strToWrite.append(QString("%1").arg(str));QFile file(filePath);file.open(QIODevice::WriteOnly | QIODevice::Append);QTextStream text_stream(&file);text_stream << strToWrite << "\r\n";file.flush();file.close();g_pTb->append(strToWrite);
}void MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{QString txtMessage = "";QString messageType = "";switch (type) {case QtDebugMsg:    //調試信息提示messageType = "Debug";txtMessage = QString("Debug: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);break;case QtInfoMsg:messageType = "Info";txtMessage = QString("Warning: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);break;case QtWarningMsg:    //一般的warning提示messageType = "Waring";txtMessage = QString("Warning: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);break;case QtCriticalMsg:    //嚴重錯誤提示messageType = "Critical";txtMessage = QString("Critical: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);//PostErrorMessage(txtMessage, messageType);break;case QtFatalMsg:    //致命錯誤提示messageType = "Fatal";txtMessage = QString("Fatal: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);abort();}WriteLog(txtMessage, messageType);
}


16.公共參數、結構體類(paramsconfig)

.h

#ifndef PARAMSCONFIG_H
#define PARAMSCONFIG_H#include <QString>
#include <QVariant>#define SYS_CONFIG_FILE				"./data/sysConfig/params.ini"
#define USER_CONFIG_PATH			"./data/userConfig"
#define LOG_PATH					"./data/log"
#define TRAIN_FILEPATH              "./data/train"
#define CALIB_DATA_PATH             "data/calib"
#define IMG_DEPETH_FILEPATH         "data/imageDepth"
#define IMG_RAW_FILEPATH            "data/imageRaw"
#define MODEL_FILEPATH              "data/model"
#define SENCE_FILEPATH              "data/sence"
#define CONFIG_FILEPATH             "data/config/params.ini"
#define CONFIG_Main_FILEPAT         "data/config/my.ini"
#define CONFIG_Face_FILEPAT         "data/config/Face.ini"
#define CONFIG_Box_FILEPAT          "data/config/Box.ini"
#define CONFIG_CreatModel_FILEPAT   "data/config/CreatModel.ini"#define POSE_TO_HTUPLE(pose, hTuple) {hTuple[0] = pose.x; hTuple[1] = pose.y; hTuple[2] = pose.z; hTuple[3] = pose.rx; hTuple[4] = pose.ry; hTuple[5] = pose.rz; hTuple[6] = 0.0;}
#define HTUPLE_TO_POSE(hTuple, pose) {pose.x = hTuple[0]; pose.y = hTuple[1]; pose.z = hTuple[2]; pose.rx = hTuple[3]; pose.ry = hTuple[4]; pose.rz = hTuple[5];}#define KD_PI 3.141592653
#define LENGTH_UNIT "mm"
#define LX_STATIONS_NUM    3       // 相機數量#include "HalconCpp.h"
using namespace HalconCpp;/*** measure*/
typedef struct
{double AmplitudeThreshold;double RoiWidthLen;double Alpha1;double LineRowStart;double LineColumnStart;double LineRowEnd;double LineColumnEnd;
}MeasureParam;/*** pose*/
typedef struct {double x;                               ///X偏移double y;                               ///Y偏移double z;                               ///Z偏移double rx;                              ///X旋轉double ry;                              ///Y旋轉double rz;                              ///Z旋轉int type;                               ///姿態類型
} KD_POSE;/*** point select*/
typedef struct {double xMin;                            ///X范圍double xMax;                            ///X范圍double yMin;                            ///Y范圍double yMax;                            ///Y范圍double zMin;                            ///Z范圍double zMax;                            ///Z范圍int type;                               ///備用
} KD_POINT_SELECT;/*** 機械臂工具類型*/
typedef enum {ROT_TOOL_SUCKER = 0,                    ///吸盤ROT_POSE_GRIPPER_PNEUMATIC,             ///夾具氣動ROT_POSE_GRIPPER_ELECTRIC,              ///夾具電動
}ROT_TOOL_TYPE;/*** 三維點云控制參數*/
typedef struct {KD_POSE calibPose;                      ///校正PoseKD_POINT_SELECT potSelc;                ///范圍限定
} KD_3D_CTRL;                               ///三維控制參數/*** 三維物體參數*/
typedef struct {KD_POSE * pObjChangePose;               ///偏移poseunsigned int surfaceNum;                ///面數double objGuideHigh;                    ///物體抓取引導高度
} KD_OBJECT_CTRL;                           ///三維控制參數/*** 3d匹配參數*/
typedef struct {double objectMaxLength;                 ///物體最大長度double sampleDis;                       ///采樣距離double keyPotFraction;                  ///特征點最小得分double minScore;                        ///最小得分QString * modelFileName;                ///模型文件名KD_POSE toolInFlangeCenter;             ///工具在法蘭盤中心(由機械臂標定得出)KD_POSE camInBase;                      ///相機在基礎 (由halcon手眼標定得出)KD_POSE toolInObj;                      ///工具在物體 (由halcon手眼標定得出)KD_3D_CTRL bgInfo;                      ///背景抽取參數
} KD_SURFACE_MATCH_CTRL;/*** 機械臂參數*/
typedef struct {int speed;                              ///速度(測試用)double jointVelc;                       ///角速度double jointAcc;                        ///角加速度double lineVelc;                        ///線速度double lineAcc;                         ///線加速度int colliClass;                         ///防撞等級KD_POSE toolInFlangeCenter;             ///工具在法蘭盤中心
} KD_ROBOT_CTRL;/*** 機械臂碼垛參數*/
typedef struct {KD_POSE oriPose;                        ///起始碼垛姿態KD_POSE offsetPose;                     ///偏移碼垛姿態int palletNum;                          ///碼垛數量double palletSize;                      ///工件尺寸
} KD_ROBOT_PALLET_CTRL;/*** 機械臂運動參數*/
typedef struct {double doorHigh;                        ///門型高度int ioId;                               ///吸盤、夾具IO口int moveTime;                           ///機械臂從抓取到放置位置延時時間int doorUpDownTime;                     ///門型上下移動延時時間int suctionTime;                        ///吸盤、夾具延時時間KD_POSE halfWayPose;                    ///中途路點KD_ROBOT_PALLET_CTRL pallet;            ///碼垛參數ROT_TOOL_TYPE toolType;                 ///工具類型
} KD_ROBOT_MOVE_CTRL;typedef enum {UNINIT,				//還未初始化RUNNING,			//運行STOP				//停止
}PROGRAM_STATUS;/**
* DO輸出0
*/
typedef enum {KEY_RELEASE = 0,KEY1 = 1,KEY2 = 2,KEY3 = 4,KEYS = 8,KEYU = 16,KEYD = 32
}HC_KEY_TYPE;/**
* DO輸出1
*/
typedef enum {DO_NONE	   = 0,DO_GUIDE1  = 1,	// 推進DO_GUIDE2  = 2, // 推出DO_BUZZER  = 4,DO_LIGHT   = 8,DO_BACKUP1 = 16,DO_BACKUP2 = 32
}HC_DO_TYPE;/**
* DI輸入
*/
typedef enum {DI_GUIDE1 = 1,	// 推進狀態DI_GUIDE2 = 2,  // 推出狀態DI_START  = 4,DI_RESET  = 8,DI_STOP   = 16,DI_BACKUP = 32
}HC_DI_TYPE;/*** 矩形*/
typedef struct {int x;int y;int w;int h;
} LX_RECT;/*** 識別參數*/
typedef struct {LX_RECT roiRect;                    ///ROI區域int erosionVal;                     ///腐蝕參數int dilationVal;                    ///膨脹參數int noiseArea;                      ///噪聲面積(小于該面積都被認為是噪聲)int decimalPointArea;				///小數點面積double confidence;					///最低置信率QString trainFile;					///訓練文件QString usrconfigFile;				///測試項目配置文件
} LX_RECOGNISE_CTRL;//LX_RECOGNISE_CTRL LX_RECOGNISE_CTRL1;
//LX_RECOGNISE_CTRL LX_RECOGNISE_CTRL2;
/*** 相機參數*/
typedef struct {int exposureTime;int exposureTimeMin;int exposureTimeMax;int gain;int gainMin;int gainMax;
//    bool bMiroH;
//    bool bMiroV;
} LX_CAMERA_CTRL;/*** io*/
typedef struct {QString key1Do;									//io口IDQString key2Do;									//io口IDQString key3Do;									//io口IDQString keySDo;									//io口IDQString keyUpDo;								//io口IDQString keyDownDo;								//io口IDQString keyBuzzerDo;                            //io口IDQString keyStartDi;								//io口IDQString keyResetDi;								//io口IDQString keyStopDi;								//io口ID
} LX_IO_CTRL;/*** 初始化參數*/
typedef struct {int pressTime;                      ///按下時間QString defaultVal;                 ///初始值
} HC_INIT_CTRL;/*** 公英制參數*/
typedef struct {int unit;							///0為公制值, 1為英制
} HC_METRIC_IMPERIAL_CTRL;/*** 數字缺失*/
typedef struct {QString defaultVal;					///預設值
} HC_NUM_MISS_CTRL;/*** 記憶位*/
typedef struct {int pressTime;                     ///單次上升時間
} HC_MEMORY_POS_CTRL;/*** 陀螺儀*/
typedef struct {QString defaultVal;                ///陀螺儀預設等級
} HC_GYRO_CTRL;/*** 上升下降鎖*/
typedef struct {int pressTime;                      ///按下時間
} HC_LOCK_CTRL;/*** 異常碼*/
//typedef struct {
//    int pressTimeE05;                   ///E05按下時間
//}HC_EXCEPTION_CTRL;/*** 手控器檢測和預設參數*/
typedef struct {HC_INIT_CTRL initCtrl;HC_METRIC_IMPERIAL_CTRL metricImperialCtrl;HC_NUM_MISS_CTRL numMisCtrl;HC_MEMORY_POS_CTRL memoryPosCtrl;HC_GYRO_CTRL gyroCtrl;HC_LOCK_CTRL lockCtrl;int testItem;														//測試項int workStationId;
} LX_HC_CTRL;/***2d模板匹配的預設參數*/typedef  struct {double OffsetRow;double OffsetColumn;double TPhi;double TLength1;double TLength2;int m_nModecase;   // =1HTuple ModelID;HObject ShapeModel;
} LX_MATCH_CTRL;//保存加載配置
void SaveSetting(QString fileName, QString group, QString key, QVariant value);
void LoadSetting(QString fileName, QString group, QString key, QVariant &value);//保存加載識別配置
void SaveRecogniseCtrl(QString fileName, QString group, LX_RECOGNISE_CTRL recCtrl);
void LoadRecogniseCtrl(QString fileName, QString group, LX_RECOGNISE_CTRL &recCtrl);//保存加載IO配置
void SaveIoCtrl(QString fileName, QString group, LX_IO_CTRL ioCtrl);
void LoadIoCtrl(QString fileName, QString group, LX_IO_CTRL &ioCtrl);//保存加載相機配置
void SaveCameraCtrl(QString fileName, QString group, LX_CAMERA_CTRL camCtrl);
void LoadCameraCtrl(QString fileName, QString group, LX_CAMERA_CTRL &camCtrl);//保存加載手控器配置
void SaveHandCtrlerCtrl(QString fileName, QString group, LX_HC_CTRL hcCtrl);
void LoadHandCtrlerCtrl(QString fileName, QString group, LX_HC_CTRL &hcCtrl);//保存相機的 產品唯一序列號和工位
void  SaveCameraAscn(QString fileName, QString Key,QString  CameraNumber );
void  LoadCameraAscn(QString fileName, QString Key,QString  &CameraNumber );double AngleToRad(double angle);
double RadToAngle(double rad);//保存pose
void SavePose(QString group, KD_POSE pose);//加載pose
void LoadPose(QString group, KD_POSE &pose);class paramsConfig
{
public:paramsConfig();
};#endif // PARAMSCONFIG_H

.cpp

#include "paramsconfig.h"
#include <QSettings>
#include <QDebug>paramsConfig::paramsConfig()
{}void SaveRecogniseCtrl(QString fileName, QString group, LX_RECOGNISE_CTRL recCtrl)
{}void SaveCameraCtrl(QString fileName, QString group, LX_CAMERA_CTRL camCtrl)
{  // 淇濆瓨鍔犺澆鐩告満閰嶇疆SaveSetting(fileName, group, "exposureTime", QVariant(camCtrl.exposureTime));SaveSetting(fileName, group, "gain", QVariant(camCtrl.gain));SaveSetting(fileName, group, "gainMin", QVariant(camCtrl.gainMin));SaveSetting(fileName, group, "gainMax", QVariant(camCtrl.gainMax));SaveSetting(fileName, group, "exposureTimeMin", QVariant(camCtrl.exposureTimeMin));SaveSetting(fileName, group, "exposureTimeMax", QVariant(camCtrl.exposureTimeMax));
}void LoadCameraCtrl(QString fileName, QString group, LX_CAMERA_CTRL &camCtrl)
{  // 鍔犺澆鐩告満閰嶇疆QVariant qexposureTime;QVariant qexposureTimeMin;QVariant qexposureTimeMax;QVariant qGain;QVariant qGainMin;QVariant qGainMax;LoadSetting(fileName, group, "exposureTime", qexposureTime);LoadSetting(fileName, group, "exposureTimeMin", qexposureTimeMin);LoadSetting(fileName, group, "exposureTimeMax", qexposureTimeMax);LoadSetting(fileName, group, "gain", qGain);LoadSetting(fileName, group, "gainMin", qGainMin);LoadSetting(fileName, group, "gainMax", qGainMax);camCtrl.exposureTime = qexposureTime.toInt();camCtrl.exposureTimeMin = qexposureTimeMin.toInt();camCtrl.exposureTimeMax = qexposureTimeMax.toInt();camCtrl.gain = qGain.toInt();camCtrl.gainMin = qGainMin.toInt();camCtrl.gainMax = qGainMax.toInt();
//    qDebug()<<"camCtrl.gain"<<camCtrl.gain;
//    qDebug()<<"camCtrl.qexposureTime:+"<<camCtrl.exposureTime;
}void SaveHandCtrlerCtrl(QString fileName, QString group, LX_HC_CTRL hcCtrl)
{}void LoadCameraAscn(QString fileName, QString Key, QString &CameraNumber)
{QString group = "CameraManage";QVariant ValueCameraNumber;LoadSetting(fileName,group,Key,ValueCameraNumber);CameraNumber = ValueCameraNumber.toString();qDebug() << "CameraName:= " << CameraNumber;
}void LoadSetting(QString fileName, QString group, QString key, QVariant &value)
{QSettings settings(fileName,QSettings::IniFormat);if(group.size() != 0){settings.beginGroup(group);}value = settings.value(key);if(group.size() != 0){settings.endGroup();}
}void SaveSetting(QString fileName, QString group, QString key, QVariant value)
{QSettings settings(fileName, QSettings::IniFormat);if (group.size() != 0) {settings.beginGroup(group);}settings.setValue(key, value);if (group.size() != 0) {settings.endGroup();}
}void SavePose(QString group, KD_POSE pose)
{}

已經看到這里了,點個贊和關注吧!

? ? ? 剛開始寫文章,如有不足請多多包含;之后會持續更新關于(halcon學習,VS聯合編程,QT聯合編程,C++,C#,Opencv圖像處理庫,三維點云庫pcl,相機以及機器人的二次開發)等系統化學習文章。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77268.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77268.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77268.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于大模型底座重構司法信息系統

前置篇章&#xff1a;法律智能體所需的基礎知識 構建一個高效的法律智能體&#xff0c;特別是在基于RAG&#xff08;Retrieval-Augmented Generation&#xff09;架構的背景下&#xff0c;需要融合多種學科和領域的知識。以下是對法律智能體開發和應用所需核心基礎知識的簡要介…

類《雙人成行》3D動作益智冒險類雙人控制游戲開發

服務器端采用了基于開源Kbengine&#xff08;引擎使用C和Python編寫&#xff09;的多人在線游戲服務器&#xff0c;客戶端采用Unity3D。游戲支持線上的雙人聯機房間功能。 資源地址&#xff1a;類《雙人成行》3D動作益智冒險類雙人控制游戲開發教程 | Unity 中文課堂 一、游戲…

Spark--基本介紹

Spark是基于內存的快速&#xff0c;通農用&#xff0c;可拓展的大數據分析計算引擎&#xff0c;Hadoop是一個分布式系統基礎架構 Spark和Hadoop之間的對比和聯系 架構與組件&#xff1a; Hadoop&#xff1a; ■ HDFS&#xff1a;分布式文件系統&#xff0c;負責海量數據存儲。…

05-GPIO原理

一、概述 1、GPIO,即通用I/O(輸入/輸出)端口&#xff0c;是STM32可控制的引腳。STM32芯片的GPIO引腳與外部設備連接起來&#xff0c;可實現與外部通訊、控制外部硬件或者采集外部硬件數據的功能。 2、GPIO的復用:引腳復用是指將單個引腳配置為多個功能的能力。在 STM32 中&…

基于LangChain4J的AI Services實踐:用聲明式接口重構LLM應用開發

基于LangChain4J的AI Services實踐&#xff1a;用聲明式接口重構LLM應用開發 前言&#xff1a;當Java開發遇上LLM編程困境 在LLM應用開發領域&#xff0c;Java開發者常面臨兩大痛點&#xff1a;一是需要手動編排Prompt工程、記憶管理和結果解析等底層組件&#xff0c;二是復雜…

深入解析 Docker 容器進程的 cgroup 和命名空間信息

深入解析 Docker 容器進程的 cgroup 和命名空間信息 在現代 Linux 系統中&#xff0c;控制組&#xff08;cgroup&#xff09;和命名空間&#xff08;namespace&#xff09;是實現容器化技術的核心機制。cgroup 用于管理和限制進程的資源使用&#xff08;如 CPU、內存、I/O&…

【汽車ECU電控數據管理篇】S19文件格式解析篇章

一、S19格式是啥 在電控文件管理的初期階段&#xff0c;我首次接觸到的是 A2L 和 HEX 文件。其中&#xff0c;A2L 文件主要承擔著描述性功能&#xff0c;它詳細地描述了各種參數和配置等相關信息。而 HEX 文件則是一種刷寫文件&#xff0c;其內部明確記錄了具體的地址以及對應的…

python編程相關的單詞

the: 在編程中&#xff0c;“the” 是一個常見的英語單詞&#xff0c;用于指定特定的對象或變量。例如&#xff0c;“the function” 指的是某個特定的函數。 the的拼寫是t,h,e.再讀一次t,h,e and: 在編程中&#xff0c;“and” 是一個邏輯運算符&#xff0c;用于連接兩個條件&…

網絡原理 - 4(TCP - 1)

目錄 TCP 協議 TCP 協議段格式 可靠傳輸 幾個 TCP 協議中的機制 1. 確認應答 2. 超時重傳 完&#xff01; TCP 協議 TCP 全稱為 “傳輸控制協議”&#xff08;Transmission Control Protocol&#xff09;&#xff0c;要對數據的傳輸進行一個詳細的控制。 TCP 協議段格…

python博客爬蟲列表

我希望對指定網頁的&#xff0c;博客列表&#xff0c;獲取url&#xff0c;然后保存成本地文件&#xff0c;用python實現 step1: import requests from bs4 import BeautifulSoup import jsondef get_blog_links(url):headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win6…

軟件測試入門學習筆記

今天學習新知識&#xff0c;軟件測試。 什么是軟件測試&#xff1f; 使用人工和自動手段來運行或測試某個系統的過程&#xff0c;目的在于檢驗它是否滿足規定的需求或弄清實際結果與預期結果之間的差別。 軟件測試的目的&#xff1f; 1&#xff09;為了發現程序&#xff0…

uniapp開發2--uniapp中的條件編譯總結

以下是對 uni-app 中條件編譯的總結&#xff1a; 概念&#xff1a; 條件編譯是一種技術&#xff0c;允許你根據不同的平臺或環境&#xff0c;編譯不同的代碼。 在 uni-app 中&#xff0c;這意味著你可以編寫一套代碼&#xff0c;然后根據要編譯到的平臺&#xff08;例如微信小…

【k8s】sidecar邊車容器

一、Sidecar 模式簡介 Sidecar 模式是一種常見的微服務架構設計模式。它通過將附加功能或服務與主應用程序部署在同一容器或主機上&#xff0c;從而實現對主應用程序的增強和擴展。Sidecar 的名稱來源于摩托車的邊車&#xff0c;它與摩托車緊密相連&#xff0c;為主車提供額外…

MySQL索引使用一定有效嗎?如何排查索引效果?

MySQL索引使用一定有效嗎&#xff1f;如何排查索引效果&#xff1f; 1. 索引一定有效嗎&#xff1f; 不一定&#xff01; 即使你創建了索引&#xff0c;MySQL 也可能因為以下原因 不使用索引 或 索引效果不佳&#xff1a; 索引選擇錯誤&#xff1a;MySQL 優化器可能選擇了錯…

漏洞管理體系:從掃描評估到修復驗證的全生命周期實踐

漏洞管理體系&#xff1a;從掃描評估到修復驗證的全生命周期實踐 在網絡安全防御體系中&#xff0c;漏洞管理是“攻防博弈”的核心戰場。據NVD&#xff08;國家漏洞數據庫&#xff09;統計&#xff0c;2023年新增漏洞超21萬個&#xff0c;平均每天披露575個&#xff0c;其中32…

cdh平臺管理與運維最佳實踐

一、容量規劃:構建可持續擴展的數據湖底座 1.1 資源評估三維模型 #mermaid-svg-4Fd5JDKTgwqF1BUd {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4Fd5JDKTgwqF1BUd .error-icon{fill:#552222;}#mermaid-svg-4Fd5J…

力扣347:前K個高頻元素

給你一個整數數組 nums 和一個整數 k &#xff0c;請你返回其中出現頻率前 k 高的元素。你可以按 任意順序 返回答案。 示例 1: 輸入: nums [1,1,1,2,2,3], k 2 輸出: [1,2]示例 2: 輸入: nums [1], k 1 輸出: [1]題解&#xff1a; 一、思路&#xff1a; 1.我希望將nu…

前饋神經網絡層

FeedForward Network 論文地址 https://arxiv.org/pdf/1706.03762 前饋網絡介紹 前饋網絡是Transformer模型中的關鍵組件&#xff0c;每個Transformer層包含一個多頭注意力模塊和一個前饋網絡模塊。該模塊通過兩次線性變換和激活函數&#xff0c;為模型提供非線性建模能力。其核…

如何將 sNp 文件導入并繪制到 AEDT (HFSS)

導入 sNp 文件 打開您的項目&#xff0c;右鍵單擊 “Result” 繪制結果 導入后&#xff0c;用戶可以選擇它進行打印。請參閱下面的示例。要點&#xff1a;確保從 Solution 中選擇它。

es-核心儲存原理介紹

原始數據 idusernamegradedescription1ahua87i like study2xiaowang92i like es3zhaoyun63i like java 倒排索引 description使用的text分詞&#xff0c;使用倒排索引 termidi1,2,3like1,2,3study1es2java3 分詞后&#xff0c;如果匹配 es&#xff0c;則需要逐行匹配&…