当前位置: 首页 > news >正文

机器视觉开发教程——C#如何封装海康工业相机SDK调用OpenCV/YOLO/VisionPro/Halcon算法

目录

  • 引言
  • 前期准备
    • Step1 创建工程
    • Step2 创建接口
      • 2.1定义操作相机实例接口方法
      • 2.2定义设置相机参数接口方法(部分)
    • Step3 创建基类
      • 3.1定义操作相机实例&&设置相机参数的抽象层
      • 3.2定义操作相机实例&&设置相机参数的公用方法
        • 1.获取当前帧图片
        • 2.软触发获取图像
        • 3.获取和设置相机参数
    • Step4 添加海康SDK
      • 4.1在工程文件中创建ref文件夹
      • 4.2解决方案添加引用
    • Step5 实现海康SDK的操作相机实例和设置相机参数接口方法
      • 5.1 获取相机SN枚举(枚举相机)
      • 5.2初始化相机(创建相机实例打开相机)
      • 5.3 回调函数(图像采集Event)
    • Step6 调用封装的DLL实现取图
      • 6.1创建工程并引用DLL
      • 6.2设计演示窗口
      • 6.3演示窗口代码
      • 6.4效果展示

引言

机器视觉实际应用场景广泛,连接的相机品牌多样化,本教程旨在演示如何利用C#语言中类的继承与多态的特性实现多种工业相机的SDK调用快速封装,可适用于海康威视/Basler/Cognex/华睿科技/迈德威视等各种品牌。

本教程先演示如何封装海康工业相机。

前期准备

下载并安装海康工业相机客户端MVS

Step1 创建工程

利用Visual Studio创建.NET6.0工程

根据实际情况选择.NET/.NET Framework/WPF

在这里插入图片描述

Step2 创建接口

创建相机接口ICamera
在这里插入图片描述

2.1定义操作相机实例接口方法

接口传参说明
List< string > GetListEnum()/获取相机SN枚举
bool InitDevice(string SN, object Handle = null)相机SN && 窗口句柄初始化相机
bool CloseDevice()/关闭相机
bool StartBySoftTriggerModel()/相机开始采集并设置为软触发模式
bool StartByHardTriggerModel(TriggerSource triggerSource = TriggerSource.Line0)触发源相机开始采集并设置为硬触发模式
bool SoftTrigger()/软触发一次

2.2定义设置相机参数接口方法(部分)

接口传参说明
bool SetTriggerMode(TriggerMode mode, TriggerSource source = TriggerSource.Line0)触发模式&&触发源设置触发模式及触发源
bool SetExpouseTime(double value)曝光时长设置曝光时长

Step3 创建基类

这里涉及到类的继承与多态,读者不了解可自行扩展学习
之所以定义相机基类是为了规范该接口适用于其他品牌相机的SDK例如巴斯勒/康耐视/华睿/迈德威视等

3.1定义操作相机实例&&设置相机参数的抽象层

接口传参说明
public abstract List< string > GetListEnum()/获取相机SN枚举
public abstract bool InitDevice(string SN, object Handle = null)相机SN && 窗口句柄初始化相机
public abstract bool CloseDevice()/关闭相机
public abstract bool StartBySoftTriggerModel()/相机开始采集并设置为软触发模式
public abstract bool StartByHardTriggerModel(TriggerSource triggerSource = TriggerSource.Line0)触发源相机开始采集并设置为硬触发模式
public abstract bool SoftTrigger()/软触发一次
public abstract bool SetTriggerMode(TriggerMode mode, TriggerSource source = TriggerSource.Line0)触发模式&&触发源设置触发模式及触发源
public abstract bool SetExpouseTime(double value)曝光时长设置曝光时长

3.2定义操作相机实例&&设置相机参数的公用方法

1.获取当前帧图片

所有的相机取图都通过回调的方式获取
通过获取相机回调的CallBackImg来实现
该方法不能用于实时取图存在多线程问题

/// <summary>
/// 获取当前帧图像
/// </summary>
/// <param name="bitmap"></param>
/// <param name="outtime"></param>
/// <returns></returns>
public bool GetImage(out Bitmap bitmap, int outtime = 50)
{bitmap = null;if (CallBackImg == null)return false;lock (CallBackImg){//bitmap = this.CallBackImg.Clone() as Bitmap;bitmap = CallBackImg;Bitmap = bitmap;//必须清空CallBackImgCallBackImg = null;return true;}
}

在相机的图像回调函数中需要将当前帧取图的结果暂存在CallBackImg变量中,具体解释可见Step5-5.3 回调函数
在这里插入图片描述

2.软触发获取图像

软触发取图前将暂存原触发方式在本地便于硬触发工况下取图测试
实际操作为发送一次软触发指令通过获取回调返回的单帧图像

/// <summary>
/// 软触发获取图像
/// </summary>
/// <param name="bitmap"></param>
/// <param name="outtime"></param>
/// <returns></returns>
public bool GetImageWithSoftTrigger(out Bitmap bitmap, int outtime = 3000)
{if (!isGrabbing)StartGrabbing();// 开始时间DateTime startTime = DateTime.Now; // 当前时间// 设置超时时间DateTime lastTime = startTime.AddMilliseconds(outtime);// 判断是否超时while (lastTime > DateTime.Now)// 设置超时时间为 3 秒{if (isGrabbing)break;}GetTriggerMode(out TriggerMode triggerMode, out TriggerSource triggerSource);SetTriggerMode(TriggerMode.On, TriggerSource.Software);bitmap = null;// 开始时间startTime = DateTime.Now; // 当前时间// 设置超时时间lastTime = startTime.AddMilliseconds(outtime);if (!SoftTrigger()) return false;// 判断是否超时while (lastTime > DateTime.Now)// 设置超时时间为 3 秒{GetImage(out bitmap, outtime);if (bitmap != null)break;}if (triggerMode == TriggerMode.On)SetTriggerMode(triggerMode, triggerSource);return (bitmap != null);
}
3.获取和设置相机参数
public void SetCamConfig(CameraConfig config)
{SetTriggerMode(config.TriggerMode, config.TriggerSource);SetTriggerPolarity(config.TriggerPolarity);SetTriggerDelay(config.TriggerDelay);SetTriggerFliter(config.TriggerFilter);SetExpouseTime(config.ExpouseTime);SetGain(config.Gain);
}public void GetCamConfig(out CameraConfig config)
{string SN = this.SN;CameraBrand Brand = this.Brand;GetTriggerMode(out TriggerMode triggerMode, out TriggerSource triggerSource);GetTriggerPolarity(out TriggerPolarity triggerPolarity);GetTriggerFliter(out double triggerfilter);GetTriggerDelay(out double triggerdelay);GetExpouseTime(out double expouseTime);GetGain(out double gain);config = new CameraConfig(){CameraSN = SN,Brand = Brand,TriggerMode = triggerMode,TriggerSource = triggerSource,TriggerPolarity = triggerPolarity,TriggerFilter = triggerfilter,TriggerDelay = triggerdelay,ExpouseTime = expouseTime,Gain = gain};
}

Step4 添加海康SDK

4.1在工程文件中创建ref文件夹

在这里插入图片描述
拷贝成功后在解决方案资源管理器中ref下会有对于的dll(没有则手动添加)
在这里插入图片描述

4.2解决方案添加引用

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

程序集下有MVSDK即代表添加DLL完成

Step5 实现海康SDK的操作相机实例和设置相机参数接口方法

所有相机厂家的SDK都会有接口文档提供,海康工业相机SDK的接口文档路径如下,下面会介绍如何通过接口文档实现自己的接口方法

在这里插入图片描述
在这里插入图片描述

5.1 获取相机SN枚举(枚举相机)

在这里插入图片描述

参考SDK接口文档的选项1枚举相机,返回相机SN队列List< string >

public override List<string> GetListEnum()
{List<string> deviceList = new List<string>();foreach (var item in GetListInfoEnum()){IDeviceInfo deviceInfo = item;if (deviceInfo.UserDefinedName != "")deviceList.Add(deviceInfo.SerialNumber);elsedeviceList.Add(deviceInfo.SerialNumber);}return deviceList;
}private List<IDeviceInfo> GetListInfoEnum()
{System.GC.Collect();deviceInfoList.Clear();// ch:创建设备列表 | en:Create Device Listint nRet = DeviceEnumerator.EnumDevices(enumTLayerType, out deviceInfoList);if (nRet != MvError.MV_OK){ShowErrorMsg("Enumerate devices fail!", nRet);return new List<IDeviceInfo>();}return deviceInfoList;
}

IDeviceInfo中包含了相机的SerialNumber序列号(SN)
为了方便调用只将相机的SN进行了返回

5.2初始化相机(创建相机实例打开相机)

在这里插入图片描述

创建相机实例也就是打开相机并且占用相机资源

public override bool InitDevice(string CamSN, object handle = null)
{try{int nRet;if (string.IsNullOrEmpty(CamSN)) return false;var infolist = GetListInfoEnum();if (infolist.Count < 1) return false;IDeviceInfo deviceInfo = infolist[0];bool selectSNflag = false;foreach (var item in infolist){if (item.SerialNumber.Equals(CamSN)){deviceInfo = item;selectSNflag = true;break;}}if (!selectSNflag) return false;try{// ch:打开设备 | en:Open devicedevice = DeviceFactory.CreateDevice(deviceInfo);}catch (Exception ex){MessageBox.Show("Create Device fail!" + ex.Message);return false;}nRet = device.Open();if (nRet != MvError.MV_OK){ShowErrorMsg("Open Device fail!", nRet);return false;}// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)if (device is IGigEDevice){int packetSize;nRet = (device as IGigEDevice).GetOptimalPacketSize(out packetSize);if (packetSize > 0){nRet = device.Parameters.SetIntValue("GevSCPSPacketSize", packetSize);if (nRet != MvError.MV_OK)Console.WriteLine("Warning: Set Packet Size failed {0:x8}", nRet);elseConsole.WriteLine("Set PacketSize to {0}", packetSize);}elseConsole.WriteLine("Warning: Get Packet Size failed {0:x8}", nRet);}// ch:设置触发模式为On || en:set trigger mode as On// 设置为Off会一直触发回调SetTriggerMode(TriggerMode.On, TriggerSource.Software);device.Parameters.SetEnumValueByString("AcquisitionMode", "Continuous");// ch:注册回调函数 | en:Register image callback// 注册回调函数操作应放在打开采集流操作之前device.StreamGrabber.FrameGrabedEvent += CallBackEventHandler;if (nRet != MvError.MV_OK){Console.WriteLine("Set TriggerMode failed:{0:x8}", nRet);return false;}if (!StartGrabbing()){Console.WriteLine("开始采集失败");return false;}//ch: 设置合适的缓存节点数量 | en: Setting the appropriate number of image nodesdevice.StreamGrabber.SetImageNodeNum(5);SN = CamSN;Brand = CameraBrand.HikCamera;return true;}catch { return false; }
}

1.初始化相机最主要的就是SN,通过枚举相机匹配到对应相机的IDeviceInfo
2.创建并打开相机后进行设备参数配置和图像采集绑定Event
3.设备参数配置将设置为软触发模式
4.图像采集绑定Event订阅了CallBackEventHandler函数
5.相机开始采集成功确认SN与品牌

5.3 回调函数(图像采集Event)

在这里插入图片描述

被事件订阅的回调函数在每次帧结束后被触发

/// <summary>
/// 回调函数(不要在内部增加耗时操作)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CallBackEventHandler(object sender, FrameGrabbedEventArgs e)
{try{int nRet;Console.WriteLine("Get Image Buffer: Width[{0}] , Height[{1}] , FrameNum[{2}]", e.FrameOut.Image.Width, e.FrameOut.Image.Height, e.FrameOut.FrameNum);IImage inputImage = e.FrameOut.Image;IImage outImage = inputImage;MvGvspPixelType dstPixelType = MvGvspPixelType.PixelType_Gvsp_Undefined;if (IsColorPixelFormat(e.FrameOut.Image.PixelType)){dstPixelType = MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;}else if (IsMonoPixelFormat(e.FrameOut.Image.PixelType)){dstPixelType = MvGvspPixelType.PixelType_Gvsp_Mono8;}else{Console.WriteLine("Don't need to convert!");}if (dstPixelType != MvGvspPixelType.PixelType_Gvsp_Undefined){// ch:像素格式转换 | en:Pixel type convert nRet = device.PixelTypeConverter.ConvertPixelType(inputImage, out outImage, dstPixelType);if (nRet != MvError.MV_OK){Console.WriteLine("Image Convert failed:{0:x8}", nRet);return;}Console.WriteLine("Image Convert success!");}//ch: 释放图像缓存 | en: Release image bufferdevice.StreamGrabber.FreeImageBuffer(e.FrameOut);if (outImage.ToBitmap() == null) return;CallBackImg = outImage.ToBitmap();if (this.ImageGrabbed != null)this.ImageGrabbed(this, new CameraEventArgs(SN, CallBackImg));}catch { }
}

1.BaseCamera基类中定义了事件public EventHandler< CameraEventArgs > ImageGrabbed = delegate { };
2.CameraEventArgs含有取图完成的相机SN与单帧图片等信息可自由扩展
3.回调的图片存储在CallBackImg变量中可用于软触发回调
4.返回的图片统一为Bitmap格式通用性强

Step6 调用封装的DLL实现取图

6.1创建工程并引用DLL

创建TestTCameras工程,引用TCameras工程生成的.dll
在这里插入图片描述

6.2设计演示窗口

演示窗口只包含了最基础的操作:
1、(Form1_Load)打开窗体时显示可用相机到combox1中
2、(button1_Click)点击button1连接相机
3、(button2_Click)点击button2软触发取图
4、(Form1_FormClosing)关闭窗口前断开已连接的相机

在这里插入图片描述

picturbox的SizeMode属性需要设置为Zoom否则无法显示完整

在这里插入图片描述

6.3演示窗口代码

using System.Xml.Linq;
using TCameras;namespace TestTCameras
{public partial class Form1 : Form{public Form1(){InitializeComponent();}BaseCamera camera = new HikCamera();private void Form1_Load(object sender, EventArgs e){List<string> lstSN = camera.GetListEnum();comboBox1.Items.Clear();foreach (var sn in lstSN)comboBox1.Items.Add(sn);}private void Form1_FormClosing(object sender, FormClosingEventArgs e){if (camera != null || camera.isGrabbing)camera.Dispose();}private void button1_Click(object sender, EventArgs e){if (camera != null && camera.isGrabbing){camera.CloseDevice();camera = new HikCamera();}string sn = comboBox1.Text;if (camera.InitDevice(sn, this.Handle)){camera.GetExpouseTime(out float exp);camera.GetGain(out float gain);textBox1.Text = exp.ToString();textBox2.Text = gain.ToString();MessageBox.Show($"[{sn}]连接成功");}}private void button2_Click(object sender, EventArgs e){if (camera == null || !camera.isGrabbing){MessageBox.Show($"相机未连接");return;}if (float.TryParse(textBox1.Text, out float exp) && float.TryParse(textBox2.Text, out float gain)){camera.SetExpouseTime(exp);camera.SetGain(gain);if (camera.GetImageWithSoftTrigger(out Bitmap bitmap)){pictureBox1.Image = bitmap;}elseMessageBox.Show($"获取图像失败");}}}
}

6.4效果展示

相机SDK封装取图

相关文章:

机器视觉开发教程——C#如何封装海康工业相机SDK调用OpenCV/YOLO/VisionPro/Halcon算法

目录 引言前期准备Step1 创建工程Step2 创建接口2.1定义操作相机实例接口方法2.2定义设置相机参数接口方法&#xff08;部分&#xff09; Step3 创建基类3.1定义操作相机实例&&设置相机参数的抽象层3.2定义操作相机实例&&设置相机参数的公用方法1.获取当前帧图…...

c++STL-string的模拟实现

cSTL-string的模拟实现 string的模拟实现string的模拟线性表的实现构造函数析构函数获取长度&#xff08;size&#xff09;和获取容量&#xff08;capacity&#xff09;访问 [] 和c_str迭代器&#xff08;iterator&#xff09;交换swap拷贝构造函数赋值重载&#xff08;&#x…...

HTTP 和 WebSocket 的区别

✅ 一、定义对比 协议简要定义HTTP一种基于请求-响应模式的、无状态的应用层协议&#xff0c;通常用于客户端与服务器之间的数据通信。WebSocket一种全双工通信协议&#xff0c;可以在客户端和服务器之间建立持久连接&#xff0c;实现实时、低延迟的数据传输。 ✅ 二、通信方式…...

【Tools】Visual Studio使用经验介绍(包括基本功能、远程调试、引入第三方库等等)

这里写目录标题 1. VS基本使用1.1. 快捷键1.2. 查看变量地址1.3. 查看代码汇编1.4. visual studio 热重载功能的使用1.5. vs远程服务器调试1.6. 引入第三方库VLD1.7. release debug模式 1. VS基本使用 1.1. 快捷键 ctrl c :复制光标所在行 注意&#xff1a;只需要光标在这…...

一周内学完计算机网络课程之二:计算机网络物理层的理解

消失人口回归&#xff0c;重新开始学习新知识。再次伟大。 物理层详解 需要理解的几个概念&#xff1a; 曼彻斯特编码、差分曼彻斯特编码 码元&#xff1a;构成信号的基本单元 调制&#xff1a; 通信中的调制是一种将原始信号&#xff08;如音频、视频、数据等&#xff09;转…...

Python OpenCV性能优化与部署实战指南

在计算机视觉领域&#xff0c;OpenCV作为开源视觉库的标杆&#xff0c;其性能表现直接影响着从工业检测到AI模型推理的各类应用场景。本文结合最新技术趋势与生产实践&#xff0c;系统性梳理Python环境下OpenCV的性能优化策略与部署方案。 一、性能优化核心技术矩阵 1.1 内存…...

深度解析:可视化如何重塑销售策略制定与执行

为什么你的销售策略总是“听起来挺对&#xff0c;做起来却没用”&#xff1f; 你有没有遇到过这样的情况&#xff1a; 销售团队天天跑客户&#xff0c;但业绩还是上不去&#xff1b;市场部说数据在增长&#xff0c;销售部却觉得“根本没转化”&#xff1b;高层开会时信心满满…...

opencv关键点检测

python 使用opencv进行图片关键点检测 功能&#xff1a; 在一张图片中裁剪出一块小图 使用cv2中 cv2.SIFT_create() SIFT检测器检测关键点 匹配原图和小图的关键点 import cv2 import numpy as np # 读取图像 img1 cv2.imread(rE:\234947.jpg, cv2.IMREAD_GRAYSCALE) img…...

C#游戏开发中的注意事项

目录 一、性能优化:提升游戏运行效率 1. 避免不必要的循环和迭代 2. 减少字符串拼接 3. 利用Unity的生命周期函数 4. 使用对象池(Object Pooling) 二、内存管理:避免内存泄漏和资源浪费 1. 及时释放非托管资源 2. 避免空引用异常 3. 合理使用引用类型和值类型 4. …...

MySQL的锁

锁 概述&#xff1a;锁是计算机协调多个线程或进程并发访问某一资源的机制。如何保证数据库中并发的一致性&#xff0c;有效性&#xff0c;这就是锁的作用。 分类&#xff1a; 全局锁 对数据库实例加锁&#xff0c;加锁之后&#xff0c;处于只读状态&#xff0c;后续的DML语句…...

学习黑客5 分钟小白弄懂Windows Desktop GUI

5 分钟小白弄懂Windows Desktop GUI &#x1f5a5;️ 大家好&#xff01;今天我们将深入浅出地探索Windows桌面图形用户界面(GUI)——这是我们每天与计算机交互的"门面"。无论你是刚开始接触计算机&#xff0c;还是想在TryHackMe等平台上提升安全技能&#xff0c;理…...

机器人运动控制原理浅析-UC Berkeley超视觉模态模型

加州伯克利发布的超视觉多感知模态融合(FuSe, Fuse Heterogeneous Sensory Data)模型&#xff0c;基于视觉、触觉、听觉、本体及语言等模态&#xff0c;利用自然语言跨模态对齐(Cross-Modal Grounding)优调视觉语言动作等通用模型&#xff0c;提高模型任务成功率。 总体框架 …...

【计算机网络】网络IP层

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 上篇文章&#xff1a;传输层协议TCP 下篇文章&#xff1a;数据链路层 文章摘要&#xff1…...

Nginx重写功能

目录 一 . 简介 二. if指令 2.1基本语法 2.2 举例说明 2.3 配置实例 三. return 3.1 基本语法 3.2 配置实例 四. set指令 4.1 基本语法 4.2 举例说明 4.3 配置实例 五.break指令 5.1 作用 5.2 举例说明 5.3 配置实例 六.rewrite指令 6.1 基本语法 6.2 配…...

2025-05-11 项目绩效域记忆逻辑管理

好的&#xff0c;我们可以用一个故事来帮助记忆这些规划绩效域的要素&#xff0c;同时通过逻辑关系来串联它们。以下是一个故事化的版本&#xff1a; 《项目管理的奇幻之旅》 在一个遥远的王国里&#xff0c;有一个勇敢的项目经理名叫小K。小K被国王赋予了一个艰巨的任务&…...

全模态具身智能:从 VLM 到 MLLM

写在前面 人工智能的感知边界正在以前所未有的速度扩展。最初,我们惊叹于大型语言模型(LLM)对文本的深刻理解和流畅生成。很快,视觉语言模型(Vision-Language Models, VLM) 登场,让 AI 第一次真正“看见”了世界,能够理解图像内容并将其与语言关联,实现了“看图说话”…...

C++入门小馆: 二叉搜索树

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…...

C++.IP协议通信

C++IP协议通信 1. TCP协议通信1.1 服务端实现创建套接字绑定地址监听连接接受连接数据传输关闭连接1.2 客户端实现创建套接字连接服务器数据传输关闭连接1.3 示例代码服务端代码示例客户端代码示例绑定地址接收数据发送数据关闭套接字2.2 客户端实现创建套接字发送数据接收数据…...

虚幻引擎5-Unreal Engine笔记之UE编辑器退出时的保存弹框

虚幻引擎5-Unreal Engine笔记之UE编辑器退出时的保存弹框 code review! 文章目录 虚幻引擎5-Unreal Engine笔记之UE编辑器退出时的保存弹框1. 退出编辑器时弹出的“Save Content”窗口2. File 菜单中的保存选项3. 区别总结 1. 退出编辑器时弹出的“Save Content”窗口 退出时…...

【KEIL】更新AC6编译器

看过部分的文章&#xff0c;Arm Compiler 6&#xff08;AC6&#xff09;编译器&#xff0c;相比AC5在编译速度和代码优化上提升了。因此&#xff0c;笔者决定升级到AC6的最新版本。可以更新keil5到最新版本&#xff0c;上面集成AC6编译器的版本&#xff0c;与最新版相差不远。假…...

Mosquitto MQTT库实战指南

目录 1. MQTT协议简介2. Mosquitto概述3. 开源MQTT实现对比4. 为什么选择Mosquitto5. Mosquitto的交叉编译6. MQTT发布订阅实战7. 进阶应用与最佳实践8. 总结 1. MQTT协议简介 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种基于发布/订阅模式的轻…...

C语音学习---函数指针

目录 1. 函数指针解析 2. 自定义实现&#xff08;函数指针赋值&#xff09; 利用下面一段例子来解析&#xff1a; int (*set_slave)(modbus_t *ctx, int slave); 1. 函数指针解析 set_slave 是一个 函数指针&#xff0c;指向一个函数。 该函数接受两个参数&#xff1a; mo…...

04.three官方示例+编辑器+AI快速学习webgl_animation_skinning_additive_blending

本实例主要讲解内容 这个示例展示了Three.js中**骨骼动画的叠加混合(Additive Animation Blending)**技术。通过加载一个机器人模型&#xff0c;演示了如何在基础动画(如站立、行走、跑步)之上叠加额外的动画效果(如潜行姿态、悲伤表情、点头同意等)&#xff0c;实现更丰富的角…...

WSL配置docker启动nacos容器load derby-schema.sql error.问题解决方案

nacos配置问题 问题再现查看错误logsQWEN的解答不挂载/data结论 问题再现 本来想要本地跑一下nacos,之前都是直接在Linux环境下面&#xff0c;现在就使用windows的wsl跑一下nacos,之前是需要先配置/conf文件下面的porperties文件以及构建对应的nacos-config数据库。所以我使用…...

游戏引擎学习第272天:显式移动转换

回顾并为今天的内容铺垫背景 我们刚开始为游戏主角编写一些程序逻辑&#xff0c;因为我们之前已经完成了大部分引擎方面的开发&#xff0c;现在可以专注在角色身上。这个角色的移动方式会有些特别&#xff0c;与大多数游戏角色的运动机制不太一样。我们当前正在实现的控制方式…...

AVL树解析

插入操作 // 插入操作 bool insert(const pair<K, V>& kv) {// 若树为空&#xff0c;直接构造&#xff0c;new一个if (_root nullptr) {_root new Node(kv);return true;}// 用于遍历树的当前节点Node* cur _root;// 用于记录当前节点的父节点Node* parent n…...

vue 中的数据代理

在 Vue 中&#xff0c;数据代理&#xff08;Data Proxy&#xff09; 是 Vue 实现 MVVM 模式 的关键技术之一。Vue 使用数据代理让你可以通过 this.message 访问 data.message&#xff0c;而不需要写 this.data.message —— 这大大简化了模板和逻辑代码。 我们来深入理解它的本…...

Linux共享内存深度解析:从内核机制到云原生应用

引言&#xff1a;超越进程边界的内存魔术 在Linux系统的进程间通信&#xff08;IPC&#xff09;领域&#xff0c;共享内存&#xff08;Shared Memory&#xff09;如同魔法镜子般的存在——不同进程透过它看到相同的内存镜像。这种机制摒弃了数据拷贝&#xff0c;直击性能瓶颈&…...

Vue Router全局拦截

Vue Router全局拦截全攻略 一、为什么需要全局拦截&#xff1f; 最近在开发后台管理系统时&#xff0c;突然发现所有页面都需要登录才能访问。如果每个页面都手动检查登录状态&#xff0c;那代码简直要写成意大利面条了。这时候&#xff0c;Vue Router的全局拦截功能就像个贴…...

从0开始学linux韦东山教程第三章问题小结(3)

本人从0开始学习linux&#xff0c;使用的是韦东山的教程&#xff0c;在跟着课程学习的情况下的所遇到的问题的总结,理论虽枯燥但是是基础。说实在的越看视频越感觉他讲的有点乱后续将以他的新版PDF手册为中心&#xff0c;视频作为辅助理解的工具。参考手册为嵌入式Linux应用开发…...

【前端】【css】【总复习】三万字详解CSS 知识体系

🌈 CSS 知识体系目录大纲 一、基础知识入门 1. CSS 简介与作用 CSS(Cascading Style Sheets,层叠样式表)是一种用于给 HTML 页面添加样式的语言,作用是让网页更美观、结构更清晰、布局更灵活。 核心作用: 控制网页元素的 颜色、字体、间距、边框、背景布局网页元素位置…...

Linux 进程等待

1、进程等待 僵尸进程 是一个比较麻烦的问题&#xff0c;如果不对其做出处理&#xff0c;僵尸进程 就会越来越多&#xff0c;导致 内存泄漏 和 标识符 占用问题 进程一旦变成僵尸状态&#xff0c;那就刀枪不入&#xff0c;“杀人不眨眼”的kill -9 也无能为力&#xff0c;因为…...

轻量服务器与宝塔

因为访问宝塔面板是需要在安全组设置一下开放端口&#xff0c;比如这里是42450 但是我们用的轻量服务器是把安全组这种功能削减了的&#xff0c;所以我就去尝试修改了一下防火墙设置 然后就可以访问了...

深入理解AMBA总线(六)AHB-lite Slave响应和其它控制信号

上一篇文章给大家介绍了AHB-lite的一些控制信号&#xff0c;重点是通过这些控制信号去理解AHB-lite为什么这么设计&#xff0c;采用这些控制信号有什么好处。这节课给大家带来剩余的一些控制信号介绍。 ** 1、Slave Response Signaling ** 1.1、Slave Transfer Responses …...

app加固

1、什么是加固? 我们之前讲的逆向,大多数都是用加密算法去加密一些明文字符串,然后把得到的结果用 Base64、Hex等进行编码后提交。加固其实也一样&#xff0c;只不过他通常加密的是 dex文件而已。但是 dex 文件加密以后&#xff0c;安卓系统是没法直接运行的。所以加固的核心&…...

Linux架构篇、第三章_2_Linux服务器监控与NGINX优化

Linux_架构篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a; 版本号: 1.0,0 作者: 老王要学习 日期: 2025.05.11 适用环境: Centos7 文档说明 本文围绕 Linux 服务器监控与 NGINX 优化展开。介绍了 sysst…...

第26节:卷积神经网络(CNN)-数据增强技术(PyTorch)

1. 引言 在深度学习领域,数据增强(Data Augmentation)是提升卷积神经网络(CNN)性能的关键技术之一。通过人为地扩展训练数据集,数据增强能够有效提高模型的泛化能力,防止过拟合,特别是在训练数据有限的情况下。本文将全面介绍PyTorch框架下的数据增强技术,包括基本原理、…...

架构思维:通用架构模式_怀疑下游的设计思路与最佳实践

文章目录 1. 引言2. 为什么要“怀疑下游”3. 三大类下游依赖及应对方案3.1 对其他微服务的依赖3.1.1 分布式事务简易补偿方案3.2 对数据库的依赖3.3 对消息中间件的依赖 4. 分布式事务实战案例5. 小结 1. 引言 在 架构思维&#xff1a;通用架构模式_从设计到代码构建稳如磐石的…...

[Java实战]Spring Boot 中Starter机制与自定义Starter实战(九)

[Java实战]Spring Boot 中Starter机制与自定义Starter实战&#xff08;九&#xff09; 引言 Spring Boot 的 Starter 是其“约定优于配置”理念的核心体现&#xff0c;通过简化依赖管理和自动配置&#xff0c;极大提升了开发效率。本文将深入剖析 Starter 的设计思想、实现原…...

C++23 views::repeat (P2474R2) 深入解析

文章目录 引言C20 Ranges库回顾什么是Rangesstd::views的作用 views::repeat概述基本概念原型定义工作原理应用场景初始化容器模拟测试数据 总结 引言 在C的发展历程中&#xff0c;每一个新版本都会带来一系列令人期待的新特性&#xff0c;这些特性不仅提升了语言的性能和表达…...

【第三十五周】Janus-pro 技术报告阅读笔记

Janus-Pro 摘要Abstract文章信息引言方法Janus 架构Janus 训练Janus-Pro 的改进 实验结果总结 摘要 本篇博客介绍了Janus-Pro&#xff0c;这是一个突破性的多模态理解与生成统一模型&#xff0c;其核心思想是通过解耦双路径视觉编码架构解决传统方法中语义理解与像素生成的任务…...

基于Qt的app开发第七天

写在前面 笔者是大一下计科生&#xff0c;标题这个项目是笔者这个学期的课设&#xff0c;与学长共创&#xff0c;我负责客户端部分&#xff0c;现在已经实现了待办板块的新建、修改。 这个项目目前已经走上正轨了&#xff0c;博主也实现了主要功能的从无到有&#xff…...

第二十二节:图像金字塔-拉普拉斯金字塔

在数字图像处理的奇幻世界中,存在着一种能够连接不同视觉维度的神秘阶梯——图像金字塔。这种独特的结构让计算机视觉算法能够在不同尺度下观察和理解图像特征,而其中的拉普拉斯金字塔更是隐藏着图像细节重构的终极奥秘。 一、金字塔的数学基础:从高斯到拉普拉斯 1.1 高斯金…...

Flutter基础()

导航栏 appBar: AppBar() title: const Text(搜索) //标题 backgroundColor: Colors.blue //背景颜色 centerTitle: true //标题居中leading 属性 作用&#xff1a; 放置在应用栏左侧的控件&#xff0c;通常是一个图标按钮&#xff0c;用于导航或打开菜单。 AppBar(le…...

ES面试题系列「一」

1、Elasticsearch 是什么&#xff1f;它与传统数据库有什么区别&#xff1f; 答案&#xff1a;Elasticsearch 是一个基于 Lucene 的分布式、开源的搜索和分析引擎&#xff0c;主要用于处理大量的文本数据&#xff0c;提供快速的搜索和分析功能。与传统数据库相比&#xff0c;E…...

Oracle 通过 ROWID 批量更新表

Oracle 通过 ROWID 批量更新表 在 Oracle 数据库中&#xff0c;使用 ROWID 进行批量更新是一种高效的更新方法&#xff0c;因为它直接定位到物理行位置&#xff0c;避免了通过索引查找的开销。 ROWID 基本概念 ROWID 是 Oracle 数据库中每一行的唯一物理地址标识符&#xff…...

罗技无线鼠标的配对方法

罗技鼠标的配对方法&#xff1a; 重新连接鼠标 请按照以下步骤将鼠标与 USB 接收器重新配对。 1.将USB接收器插入计算机。 2.将鼠标关闭电源。 3.按住并持续按住向右按钮&#xff0c;直到操作结束。 4.切换鼠标电源。 5. 单击一次左侧按钮。 6. 单击一次中间按钮。 7.全部松开&…...

移动应用开发的六大设计原则

在移动应用开发中&#xff0c;遵循设计原则能大幅提升代码的可维护性和扩展性。本文以一个简单的学生管理系统为例&#xff0c;解析六大核心设计原则的实践方法。 1. 单一职责原则 优点&#xff1a; 提高可维护性&#xff1a;一个类只负责一项职责&#xff0c;代码的功能会更…...

LLM初识

从零到一&#xff1a;用 Python 和 LLM 构建你的专属本地知识库问答机器人 摘要&#xff1a; 随着大型语言模型&#xff08;LLM&#xff09;的兴起&#xff0c;构建智能问答系统变得前所未有的简单。本文将详细介绍如何使用 Python&#xff0c;结合开源的 LLM 和向量数据库技…...

【CTF】Linux Shell RCE绕过(bypass)技术总结

在Linux环境下&#xff0c;远程代码执行&#xff08;RCE&#xff0c;Remote Code Execution&#xff09;是一种常见的攻击手段。然而&#xff0c;许多系统会对命令注入进行过滤或限制&#xff0c;例如禁止特定关键字&#xff08;如system&#xff09;、斜杠&#xff08;/&#…...