Qt,C++海康2D工业相机二次开发
1.先下载海康的MVS客户端下载安装后路径下会自动有相应的安装包包括头文件以及lib库文件海康机器人-机器视觉-下载中心2.在pro项目文件里面配置库文件以及头文件INCLUDEPATH $$PWD/Hik_Includes DEPENDPATH $$PWD/Hik_Includes LIBS -L$$PWD/Libs/ -lMvCameraControl也可以配置opencv或者与PLC的snap7通讯如果需要win32:CONFIG(release, debug|release): LIBS -LD:/MY_Software/opencv4.5.1/opencv4.5.1/opencv/build/x64/vc14/lib/ -lopencv_world451 else:win32:CONFIG(debug, debug|release): LIBS -LD:/MY_Software/opencv4.5.1/opencv4.5.1/opencv/build/x64/vc14/lib/ -lopencv_world451d INCLUDEPATH D:/MY_Software/opencv4.5.1/opencv4.5.1/opencv/build/include DEPENDPATH D:/MY_Software/opencv4.5.1/opencv4.5.1/opencv/build/include win32:CONFIG(release, debug|release): LIBS -L$$PWD/./release/ -lsnap7 else:win32:CONFIG(debug, debug|release): LIBS -L$$PWD/./debug/ -lsnap7 else:unix: LIBS -L$$PWD/./ -lsnap7 INCLUDEPATH $$PWD/ DEPENDPATH $$PWD/3.相机与电脑连接我的相机是通过一个USB-以太网和电脑相连需要改电脑端口IP相机IP在MVS客户端上面改就可以了改电脑IP可以参考我的基于Qt和C的海康网络摄像头SDK开发详细步骤_海康威视摄像头sdk-CSDN博客为了方便相机连接我也将两个相机改了名字yzw123和ocr456。在MVS可以试试看看相机拍摄的画面在qt里面调试程序记得把MVS关了要不然会占用相机导致qt程序无法调用该相机4.我这里写了camerainterface和hikvisionsdk来实现连接调用相机并抓取画面。程序是借鉴别人的。camerainterface.h#ifndef CAMERAINTERFACE_H #define CAMERAINTERFACE_H #includeopencv2/opencv.hpp #includeiostream class CameraInterface { public: CameraInterface(); ~CameraInterface(); // ch:连接设备 virtual int connectCamera(std::string 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; //读取buffer virtual int ReadBuffer(cv::Mat 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; //设置图像水平偏移OffsetX virtual int setOffsetX(unsigned int offsetX)0; //设置图像竖直偏移OffsetY virtual 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 setExposureAuto(bool exposureAutoFlag)0; //关闭自动增益 virtual int setGainAuto(bool gainAutoFlag)0; //清理相机缓存 virtual void clearBuffer()0; }; #endif // CAMERAINTERFACE_Hcamerainterface.cpp#include camerainterface.h CameraInterface::CameraInterface() { } CameraInterface::~CameraInterface() { }hikvisionsdk.h#ifndef HIKVISIONSDK_H #define HIKVISIONSDK_H #includecamerainterface.h #includeMvCameraControl.h using namespace cv; class HikvisionSDK:public CameraInterface { public: HikvisionSDK(); ~HikvisionSDK(); // ch:连接设备 int connectCamera(std::string id); //设置是否为触发模式 int setTriggerMode(unsigned int TriggerModeNum); //开启相机采集 int startCamera(); //关闭相机采集 int stopCamera(); //关闭相机 int closeCamera(); //软触发 int softTrigger(); //读取buffer int ReadBuffer(cv::Mat image); //设置图像高度 int setHeight(unsigned int height); //设置图像ROI宽度 int setWidth(unsigned int width); //获取图像高度值 int getHeight(); //获取图像宽度值 int getWidth(); //获取相机曝光时间 float getExposureTime(); //设置图像水平偏移OffsetX int setOffsetX(unsigned int offsetX); //设置图像竖直偏移OffsetY int setOffsetY(unsigned int offsetY); //设置触发源 int setTriggerSource(unsigned int TriggerSourceNum); //设置帧率控制使能 int setFrameRateEnable(bool comm); //设置心跳时间 int setHeartBeatTime(unsigned int time); //设置曝光时间 int setExposureTime(float ExposureTimeNum); //关闭自动曝光 int setExposureAuto(bool exposureAutoFlag); //关闭自动增益 int setGainAuto(bool gainAutoFlag); //清理相机缓存 void clearBuffer(); // // 获取相机IP地址 // std::string getCameraIpAddress(); private: void* m_hDevHandle; public: // 用于保存图像的缓存 unsigned int m_nBufSizeForSaveImage; // 用于从驱动获取图像的缓存 unsigned int m_nBufSizeForDriver; }; #endif // HIKVISIONSDK_Hhikvisonsdk.cpp#include hikvisionsdk.h #include MvCameraControl.h MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量用来存储设备列表 MV_CC_DEVICE_INFO* m_DeviceNULL; //设备对象 HikvisionSDK::HikvisionSDK() { m_hDevHandle NULL; } HikvisionSDK::~HikvisionSDK() { if (m_hDevHandle) { MV_CC_DestroyHandle(m_hDevHandle); m_hDevHandle NULL; } } //连接相机 int HikvisionSDK::connectCamera(std::string id) { //查询设备列表 int tempValueMV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, m_stDevList); if(tempValue!0) //设备更新成功接收命令的返回值为0返回值不为0则为异常 return -1; if(m_stDevList.nDeviceNum0) //未找到任何相机 return 2; for (unsigned int i 0; i m_stDevList.nDeviceNum; i) { MV_CC_DEVICE_INFO* pDeviceInfo m_stDevList.pDeviceInfo[i]; if (NULL pDeviceInfo) { continue; } if(pDeviceInfo-nTLayerTypeMV_USB_DEVICE) { if(id (char*)pDeviceInfo-SpecialInfo.stUsb3VInfo.chSerialNumber||id (char*)pDeviceInfo-SpecialInfo.stUsb3VInfo.chUserDefinedName||id (char*)pDeviceInfo-SpecialInfo.stUsb3VInfo.chSerialNumber||idPECVD) { m_Device m_stDevList.pDeviceInfo[i]; break; } } if(pDeviceInfo-nTLayerTypeMV_GIGE_DEVICE) { if(id (char*)pDeviceInfo-SpecialInfo.stUsb3VInfo.chSerialNumber||id (char*)pDeviceInfo-SpecialInfo.stGigEInfo.chUserDefinedName||id (char*)pDeviceInfo-SpecialInfo.stGigEInfo.chSerialNumber||idPECVD) { m_Device m_stDevList.pDeviceInfo[i]; break; } } continue; } if(m_DeviceNULL) { //未找到指定名称的相机 return 3; } tempValue MV_CC_CreateHandle(m_hDevHandle, m_Device); if(tempValue!0) return -1; tempValue MV_CC_OpenDevice(m_hDevHandle); if (tempValue!0) { MV_CC_DestroyHandle(m_hDevHandle); m_hDevHandle NULL; return -1; }else { setTriggerMode(1); return 0; } if (m_Device-nTLayerType MV_GIGE_DEVICE) { } if(m_Device-nTLayerType MV_USB_DEVICE) { MV_CC_SetImageNodeNum(m_hDevHandle,2); } } //启动相机采集 int HikvisionSDK::startCamera() { int tempValueMV_CC_StartGrabbing(m_hDevHandle); if(tempValue!0) { return -1; }else { return 0; } } //停止相机采集 int HikvisionSDK::stopCamera() { int tempValueMV_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(Mat image) { Mat* getImagenew Mat(); unsigned int nRecvBufSize 0; MVCC_INTVALUE stParam; memset(stParam, 0, sizeof(MVCC_INTVALUE)); int tempValue MV_CC_GetIntValue(m_hDevHandle, PayloadSize, stParam); if (tempValue ! 0) { return -1; } nRecvBufSize stParam.nCurValue; unsigned char* pDate; pDate(unsigned char *)malloc(nRecvBufSize); MV_FRAME_OUT_INFO_EX stImageInfo {0}; tempValue MV_CC_GetOneFrameTimeout(m_hDevHandle, pDate, nRecvBufSize, stImageInfo, 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); bool isMono; switch (stImageInfo.enPixelType) { case PixelType_Gvsp_Mono8: case PixelType_Gvsp_Mono10: case PixelType_Gvsp_Mono10_Packed: case PixelType_Gvsp_Mono12: case PixelType_Gvsp_Mono12_Packed: isMonotrue; break; default: isMonofalse; break; } if(isMono) { *getImageMat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC1,pDate); //imwrite(d:\\测试opencv_Mono.tif, image); } else { //转换图像格式为BGR8 MV_CC_PIXEL_CONVERT_PARAM stConvertParam {0}; memset(stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM)); stConvertParam.nWidth stImageInfo.nWidth; //ch:图像宽 | en:image width stConvertParam.nHeight stImageInfo.nHeight; //ch:图像高 | en:image height //stConvertParam.pSrcData m_pBufForDriver; //ch:输入数据缓存 | en:input data buffer stConvertParam.pSrcData pDate; //ch:输入数据缓存 | en:input data buffer stConvertParam.nSrcDataLen stImageInfo.nFrameLen; //ch:输入数据大小 | en:input data size stConvertParam.enSrcPixelType stImageInfo.enPixelType; //ch:输入像素格式 | en:input pixel format stConvertParam.enDstPixelType PixelType_Gvsp_BGR8_Packed; //ch:输出像素格式 | en:output pixel format 适用于OPENCV的图像格式 //stConvertParam.enDstPixelType PixelType_Gvsp_RGB8_Packed; //ch:输出像素格式 | en:output pixel format stConvertParam.pDstBuffer m_pBufForSaveImage; //ch:输出数据缓存 | en:output data buffer stConvertParam.nDstBufferSize m_nBufSizeForSaveImage; //ch:输出缓存大小 | en:output buffer size MV_CC_ConvertPixelType(m_hDevHandle, stConvertParam); *getImageMat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC3,m_pBufForSaveImage); //imwrite(d:\\测试opencv_Color.tif, image); } (*getImage).copyTo(image); (*getImage).release(); free(pDate); free(m_pBufForSaveImage); return 0; } //获取图像高度值 int HikvisionSDK::getHeight() { MVCC_INTVALUE stParam; memset(stParam, 0, sizeof(MVCC_INTVALUE)); int tempValueMV_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 tempValueMV_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 tempValueMV_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 tempValueMV_CC_SetIntValue(m_hDevHandle, Height, height); if(tempValue!0) { return -1; } else { return 0; } } //设置图像ROI宽度 int HikvisionSDK::setWidth(unsigned int width) { int tempValueMV_CC_SetIntValue(m_hDevHandle, Width, width); if(tempValue!0) { return -1; } else { return 0; } } //设置图像水平偏移OffsetX int HikvisionSDK::setOffsetX(unsigned int offsetX) { int tempValueMV_CC_SetIntValue(m_hDevHandle, OffsetX, offsetX); if(tempValue!0) { return -1; } else { return 0; } } //设置图像竖直偏移OffsetY int HikvisionSDK::setOffsetY(unsigned int offsetY) { int tempValueMV_CC_SetIntValue(m_hDevHandle, OffsetY, offsetY); if(tempValue!0) { return -1; } else { return 0; } } //设置是否为触发模式 int HikvisionSDK::setTriggerMode(unsigned int TriggerModeNum) { //0Off 1On int tempValue MV_CC_SetEnumValue(m_hDevHandle,TriggerMode, TriggerModeNum); if(tempValue!0) { return -1; }else { return 0; } } //设置触发源 int HikvisionSDK::setTriggerSource(unsigned int TriggerSourceNum) { //0Line0 1Line1 7Software int 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) { //心跳时间最小为500ms if(time500) time500; int tempValueMV_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::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(); }先在widget构造里面初始化定时器// 初始化定时器 timer5 new QTimer(this); connect(timer5, QTimer::timeout, this, Widget::captureAndProcess);我是在widget.cpp里面的按钮里面实现连接的通过已修改的相机ID进行连接第二个相机也类似。// 连接相机 if(cameranullptr) { camera new HikvisionSDK(); // 连接相机 int connectResult camera-connectCamera(yzw123); std::cout Connect: connectResult std::endl; // 设置触发模式 std::cout TriggerMode: camera-setTriggerMode(1) std::endl; // 设置触发源为软触发 std::cout TriggerSource: camera-setTriggerSource(7) std::endl; // 设置曝光时间 std::cout SetExposureTime: camera-setExposureTime(40000) std::endl; // 判断 if (connectResult ! 0) { // 连接失败设为红色 ui-label_computer-setStyleSheet(background-color: red;); ui-label_computer-setText(Disconnected); ui-label_computer-setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); delete camera; camera nullptr; //return; } // 开启相机采集 int startResult camera-startCamera(); std::cout Start_LocatCamera: startResult std::endl; if (startResult ! 0) { // 启动采集失败设为红色 ui-label_computer-setStyleSheet(background-color: red;); ui-label_computer-setText(Capture Fail); ui-label_computer-setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); camera-closeCamera(); delete camera; camera nullptr; //return; } // 连接和采集均成功设为绿色 ui-label_computer-setStyleSheet(background-color: green;); ui-label_computer-setText(Connected); ui-label_computer-setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); // 启动定时器50ms间隔 timer5-start(50); }通过定时器触发以及处理调用displayvoid Widget::captureAndProcess() { // 处理第一个相机 if (camera ! nullptr) { Mat* image new Mat(); if (camera-softTrigger() 0 camera-ReadBuffer(*image) 0) { display(image, ui-label1); // 显示到 label1 } delete image; } // 新增处理第二个相机 if (cameraOCR ! nullptr) { Mat* imageOCR new Mat(); if (cameraOCR-softTrigger() 0 cameraOCR-ReadBuffer(*imageOCR) 0) { OCRdisplay(imageOCR); // 显示到 label3label4 } delete imageOCR; } }在void Widget::display(const Mat* imagePtr, QLabel* targetLabel)里面因为图片比较暗就先进行了处理才显示不是原图显示。在这里还有一个保存图像到临时文件可以通过这个对图像进行处理操作比如边缘检测透视变换之类的。std::cout so the camera std::endl; // 调用增强对比度和亮度函数 cv::Mat enhancedImage locat.enhanceContrastAndBrightness(*imagePtr); // 新增保存增强后的图像到 locatimg 文件夹 QString locatDir QCoreApplication::applicationDirPath() /locatimg/; QDir().mkpath(locatDir); // 创建目录 QString timestamp QDateTime::currentDateTime().toString(yyyy.MM.dd.hh.mm); QString locatimgfile locatDir locat_ timestamp .jpg; cv::imwrite(locatimgfile.toStdString(), enhancedImage); // 保存增强后的图像 // 显示增强图像到 label1 QImage* QmyImage new QImage(); if (enhancedImage.channels() 1) { *QmyImage QImage(enhancedImage.data, enhancedImage.cols, enhancedImage.rows, enhancedImage.step, QImage::Format_RGB888).rgbSwapped(); } else { *QmyImage QImage(enhancedImage.data, enhancedImage.cols, enhancedImage.rows, enhancedImage.step, QImage::Format_Grayscale8); } *QmyImage QmyImage-scaled(targetLabel-size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); targetLabel-setPixmap(QPixmap::fromImage(*QmyImage)); delete QmyImage; // 保存原始图像到临时文件 std::string inputPath temp_input.jpg; cv::imwrite(inputPath, *imagePtr);最后在析构函数里面要清除相应的资源Widget::~Widget() { delete ui; if (timer5 ! nullptr) { timer5-stop(); delete timer5; } if (camera ! nullptr) { camera-closeCamera(); delete camera; } // 新增释放第二个相机资源 if (cameraOCR ! nullptr) { cameraOCR-closeCamera(); delete cameraOCR; } // 释放PLC snap7指针资源 if (snap7client ! nullptr) { snap7client-Disconnect(); // 可选确保断开连接 delete snap7client; } }结果出画面如下

相关新闻

AI直接“上手“数据库:电科金仓KES MCP Server落地实操

AI直接“上手“数据库:电科金仓KES MCP Server落地实操

“orders这张表上都有哪些字段?索引是怎么建的?” “帮我看看这条SQL慢在哪里。” “如果给user_id和status加个联合索引,执行计划会变吗?” 这些过去要让DBA或开发人员来回切工具、复制粘贴才能回答的问题,如今在TRAE…

2026/7/16 19:24:40阅读更多 →
【JAVA毕设源码分享】基于Java的停车场管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于Java的停车场管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/16 19:24:40阅读更多 →
【JAVA毕设源码分享】基于JavaWeb的点餐系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于JavaWeb的点餐系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/16 19:24:40阅读更多 →
搜索引擎:Meilisearch、Cellulite、LMDB、Tantivy、Quickwit

搜索引擎:Meilisearch、Cellulite、LMDB、Tantivy、Quickwit

Meilisearch 官网,闪电般快速的开源(GitHub,58.6K Star,2.6K Fork)搜索引擎,专为现代应用设计。提供开箱即用的功能,能够在不到50毫秒内返回搜索结果,支持混合搜索(结合…

2026/7/16 20:19:45阅读更多 →
打造专业级音乐体验:foobox-cn让foobar2000焕然一新

打造专业级音乐体验:foobox-cn让foobar2000焕然一新

打造专业级音乐体验:foobox-cn让foobar2000焕然一新 【免费下载链接】foobox-cn DUI 配置 for foobar2000 项目地址: https://gitcode.com/GitHub_Trending/fo/foobox-cn 还在使用foobar2000那略显单调的默认界面吗?想要一个既美观又功能强大的音…

2026/7/16 20:19:45阅读更多 →
Windows系统环境包使用指南,解决大部分软件无法正常运行的问题

Windows系统环境包使用指南,解决大部分软件无法正常运行的问题

Windows 系统环境包使用指南资源下载:https://lists.120112.xyz/备用高速:https://file.afmax.cn/%E5%A4%87%E7%94%A8%E9%AB%98%E9%80%9F服务器宽带有限,请不要批量下载,单个下载可以触发缓存速度更快,如果下载出错可能…

2026/7/16 20:19:45阅读更多 →
计算机毕业设计之net语言上级考试题库智能化管理系统

计算机毕业设计之net语言上级考试题库智能化管理系统

网络的广泛应用给生活带来了十分的便利。所以把语言上级考试题库智能化管理与现在网络相结合,利用net语言建设语言上级考试题库智能化管理系统,实现语言上级考试题库智能化管理的信息化。则对于进一步提高语言上级考试题库智能化管理发展,丰富…

2026/7/16 20:19:45阅读更多 →
CANN/Ascend C GetStride函数

CANN/Ascend C GetStride函数

GetStride 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode.com/…

2026/7/16 20:19:44阅读更多 →
从0到1理解prettyplease工作原理:Oppen算法的Rust实现详解

从0到1理解prettyplease工作原理:Oppen算法的Rust实现详解

从0到1理解prettyplease工作原理:Oppen算法的Rust实现详解 【免费下载链接】prettyplease A minimal syn syntax tree pretty-printer 项目地址: https://gitcode.com/gh_mirrors/pr/prettyplease prettyplease是一个轻量级的syn语法树格式化工具&#xff0c…

2026/7/16 20:14:44阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/16 8:28:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/16 6:53:04阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/16 12:02:41阅读更多 →
A--10 Codex Review与GitHub PR工作流实战指南:从代码审查到安全合并

A--10 Codex Review与GitHub PR工作流实战指南:从代码审查到安全合并

摘要:本文系统讲解如何利用Codex App的Review功能与GitHub PR工作流,实现从代码修改到安全合并的完整流程。涵盖Review面板深度使用、/review命令实战、GitHub Connector配置、PR描述撰写技巧,以及常见问题排查方法。通过多个实战案例和流程图,帮助开发者建立高效的AI辅助代…

2026/7/16 0:00:38阅读更多 →
遗传算法解5皇后问题:从Hello World到工业优化的进化实验室

遗传算法解5皇后问题:从Hello World到工业优化的进化实验室

1. 项目概述:为什么用遗传算法解5皇后问题,而不是直接回溯?我带过十几届算法课,也给不少初创团队做过AI架构咨询。每次讲到组合优化问题,学生和工程师的第一反应永远是“写个回溯试试”。这没错——55棋盘上找所有合法…

2026/7/16 0:00:38阅读更多 →
5.1V稳压管输出为何只有4.7V?工作电流与负载影响分析

5.1V稳压管输出为何只有4.7V?工作电流与负载影响分析

前几天调试一个简单的电源模块,用到了5.1V稳压管。电路接好,上电测试,万用表一量——输出居然只有4.7V。第一反应是稳压管坏了,换了一个新的,结果还是4.7V。这让我想起很多初学者都会遇到的困惑:明明标称5.…

2026/7/16 0:00:38阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/16 20:13:14阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/16 8:58:42阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/16 17:10:26阅读更多 →