- 博客(504)
- 收藏
- 关注
原创 【openCV】图像缩放,翻转,旋转,视频文件/摄像头读取/保存
cv::resize 是 OpenCV 中用来改变图像尺寸(放大或缩小)的函数。你可以指定目标图像的宽高,也可以给定缩放比例,还能选择不同的插值算法来控制缩放时的像素计算方式。参数解释如果 dsize = Size(),那么就会根据 fx 和 fy 自动计算目标尺寸。只有当 dsize 为Size()时,这两个参数才起作用。(INTER_NEAREST):直接取离目标像素最近的原始像素的值,速度最快,但放大后会有明显锯齿,适合二值图像或需要保留硬边缘的场合。
2026-05-25 21:15:57
510
原创 【openCV】鼠标操作,像素类型转换与归一化
如果你不想改变箭头的方向,只是想比较不同箭头的方向,就需要把所有的箭头都“拉长或缩短”到单位长度(长度 = 1)。之后,你在这个窗口上的每一次鼠标点击、移动或释放,系统都会自动调用这个函数,让你的程序能“看到”并响应鼠标的动作。下面是一个完整的例子:鼠标左键按下时确定圆心,拖动鼠标时实时显示一个半径不断变化的圆(圆心到鼠标当前点的距离),松开左键后这个圆就固定在图像上。它的主要作用是在不同的数值类型之间转换,比如把 CV_8U(0~255 的 uint8)转换为 CV_32F(浮点数),或者反过来。
2026-05-25 14:08:49
485
原创 【openCV】像素值统计,几何形状绘制,随机数,多边形绘制/填充
的基本数据结构,cv::Point 有两个公开成员:x 和 y(顺序是列、行,即 (x, y) 对应图像坐标中的 (width, height))。简单来说,当你用像素点阵显示一条斜线或曲线时,由于像素是方形的小格子,边缘会呈现出明显的阶梯状,就像“楼梯”一样,这种现象称为。一张数字图像由成千上万个像素组成,每个像素都有一个或几个数值(灰度图是一个 0~255 的数,彩色图是三个通道的数)。的含义是:创建一个矩形,其左上角位于图像坐标 (100, 200) 处,宽度为 100 像素,高度为 80 像素。
2026-05-25 09:53:31
487
原创 【openCV】键盘响应,像素逻辑操作,通道分离合并,抠像
cv::waitKey 是 OpenCV 中等待用户按键的函数,主要用于:让窗口保持显示,否则窗口会一闪而过。获取用户按下的键盘按键(用于交互控制)。函数原型参数 delay:等待时间,单位毫秒。返回值:int 类型,表示按下的键的 ASCII 码。如果没有按键(超时),返回 -1。我们看一个例子我们必须先将键盘焦点给到这个图像窗口,而不是控制台基于这个现象,我们可以来做一个测试我们按下a我们按下b我们按下c。
2026-05-24 16:05:28
527
原创 【openCV】cv::Mat的创建和赋值,图像像素的读写,算术操作
cv::Mat::zeros 的最后一个参数是 type,它指定了矩阵(或图像)的数据类型和通道数。CV_<位数><数据类型符号>C<通道数>或者针对浮点数:CV_<位数>F<通道数>(F 表示 float 或 double)。类型宏位数数据类型通道数元素取值范围典型用途CV_8UC1810~255灰度图、二值掩膜CV_8UC3830~255(每个通道)彩色图像(BGR 顺序)CV_8UC484带透明通道的图像CV_8SC181-128~127梯度或带符号的8位数据。
2026-05-23 20:42:26
521
原创 【openCV】图像显示,色彩空间转换
显示的图片窗口标题出现乱码,是因为 OpenCV 在 Windows 上默认使用 ANSI(本地编码,如 GBK)来处理字符串,而你的源代码文件(例如 VS 中新建的 .cpp 文件)很可能使用的是 UTF-8 编码(无 BOM)。你可以在 Photoshop 里打开一个带透明区域的 PNG 图片,然后切换到“通道”面板,就会看到四个通道:红、绿、蓝、以及一个叫“Alpha”的通道。:很多网站的 Logo、图标(比如微信的绿色对话气泡图标)背景是透明的,这样无论放到什么背景色上都不会有一个白色方块框住它。
2026-05-22 21:22:44
527
原创 【微服务即时通讯项目】用Docker部署服务端
注意:我们这里是使用Docker来进行一键部署的,所以,没有安装Docker的,请去安装好了,再来完成下面这些事情。
2026-05-08 21:23:30
496
1
原创 【微服务即时通讯】登录注册界面设计
我们在客户端收到服务器的响应,并更新完数据之后,会发出一个信号,我们给这个信号配置一个槽函数,槽函数非常简单,就是弹出一个弹窗,打印下面这些内容。这里是进行了注册/登录双模态的设计,那么我们就有必要去根据这个登录/注册标志位来判断当前是注册还是登录状态。至于这个登录按钮,按下去后,客户端会向服务器发送登录请求,如果登录成功,就会切换到主界面。这个就涉及到来注册和登录模式的一种切换了,这个是借助于一个标志位来进行实现的。在我们这里,有4个按钮。事实上,在我们的槽函数的设计里面,我们还会需要下面这2个成员。
2026-05-05 16:09:41
471
原创 【微服务即时通讯】客户端数据中心
其实有的数据在我们的服务端和客户端进行流通的,我们客户端本地就需要保存好一些信息。首先,我们需要存储用户信息,我们在客户端这边不使用protobuf生成好的那个UserInfo数据结构,我们选择自己另外定义一个新的类,然后我们这个类还支持将protobuf里面的UserInfo数据来进行传输。public:// 用户编号// 用户昵称// 用户签名// 邮箱号码// 用户头像// 从 protobuffer 的 UserInfo 对象, 转成当前代码的 UserInfo 对象。
2026-04-28 22:27:41
487
原创 【微服务即时通讯】客户端通信连接
我们的客户端终究是需要和我们的服务器进行通信连接的。我们知道,我们客户端往这个服务器发送请求的时候其实是分成下面两种情况的那么我们就势必需要使用到下面3个组件那么我们从服务端获取的数据存放到哪里呢?我们其实是存放到我们的数据中心里面啊。这个数据中心其实是我们自己写的好了,那么现在我们就聚齐了我们客户端的通信连接类所必须的一些东西有了这几个成员,我们才能写出下面这些函数。
2026-04-28 22:26:53
457
原创 【LangChain】快速上手
安装OPENAI包接下来我们定义我们的大模型如果我们使用的是ChatGPT的API接口,那么它应该就是下面这样子写的有人可能就会问了,为什么这里不需要写这个API KEY呢?事实上这个ChatOpenAI 函数默认会去读取一个叫 OPENAI_API_KEY的环境变量,这个环境变量里面存储的就是我们的API KEY。但是我们为了方便,我们这里选择使用DeepSeek的模型# 1. 定义大模型实例 —— 改为 DeepSeek 配置。
2026-04-26 21:28:12
530
原创 【LangChain】LangChain简介
Vibe Coding(氛围编程)是一种以人工智能为核心的计算机编程实践。其核心机制是:开发者使用自然语言提示(Prompt)向经过代码优化的的大语言模型(LLM)描述问题,由 LLM 生成软件代码,从而使程序员从繁琐的编写和调试底层代码的工作中解放出来。该术语由 OpenAI 联合创始人、特斯拉前人工智能主管于 2025 年 2 月首次提出,并迅速成为一种备受关注的编码方式。
2026-04-25 16:58:27
597
原创 【LangChain】大模型介绍
什么是LangChain?我们在使用deepseek的时候,可能会去下面这个网站进行提问其实我们也可以调用deepseek的接口去进行提问一是直接访问官网的对话页面进行提问二是通过调用 DeepSeek 提供的 API 接口来实现程序化调用。但直接调用 API 接口时,开发者很容易犯错——比如处理不好请求格式、认证、超时、重试、错误解析等细节,稍有不慎就会导致请求失败或程序崩溃。这时,LangChain就像一个可靠的“缓冲区”或“代理层”。
2026-04-25 12:35:06
515
原创 【微服务即时通讯】入口网关子服务
网关服务器本身不处理具体业务逻辑,而是接收客户端的所有请求,并将其转发至对应的业务子服务节点进行处理。待业务子服务返回结果后,网关再将响应回传至客户端,从而实现接入层与业务层的解耦。网关负责对客户端进行身份验证,确保请求来源合法,并根据权限控制对后续请求进行访问管理。网关还承担与客户端之间的主动通信职责,通过推送机制将关键事件及时通知到相关客户端。在会话管理方面,客户端登录成功后,网关会为其创建一个登录会话,并将会话标识(会话ID)返回给客户端。
2026-03-31 10:22:36
515
2
原创 【微服务即时通讯】好友管理子服务2
那么我们现在就来定义我们的RPC服务。我们好友管理子服务里面一共9个RPC服务– 获取当前用户的好友列表。– 删除指定的好友关系。FriendAdd– 向目标用户发送好友申请。– 处理好友申请(同意或拒绝)。– 根据关键字搜索用户(模糊匹配用户名)。– 获取当前用户的所有聊天会话列表(单聊和群聊)。– 创建一个新的聊天会话(单聊或群聊)。– 获取指定会话的所有成员信息。– 获取当前用户收到的、未处理的好友申请列表。那么我们这里定义了// 好友列表获取// 请求:获取当前用户的好友列表。
2026-03-28 22:04:46
427
原创 【微服务即时通讯】好友管理子服务1
那么我们每一个用户,都有加好友的权力,那么我们就有必要将这个好友关系给存储到我们的数据库里面,因此,我们就借助这个odb来实现我们的friend_relation.hxx,将我们的好友关系表给定义出来有了这么一个表,我们在使用过程中,我们还是会经常的往里面增加数据,删除数据,查询数据。我们就有必要将这些操作给二次封装起来,方便我们进行使用。我们这里需要特别注意:好友关系是双向的因此,我们就编写出了这么一个mysql_friend_relation.hpp这个类封装了对数据库中“好友关系表”的常见操作。
2026-03-28 10:30:31
729
原创 【微服务即时通讯】消息存储子服务2
这里实现了3个RPC服务这个 protobuf 文件定义了一个消息存储服务获取历史消息:允许客户端根据时间区间拉取指定会话的消息记录,适用于“查看更多历史消息”或按日期翻页的场景。获取最近消息:允许客户端指定数量,获取某个会话中最新的一批消息,适用于聊天窗口初始加载或下拉刷新。消息搜索:允许客户端在指定会话中根据关键词检索消息内容,帮助用户快速定位包含特定文字的聊天记录。这三个接口共同构成了完整的消息存取能力,支持客户端灵活地加载、浏览和搜索聊天历史。我们先看看获取历史消息。
2026-03-26 22:09:46
513
原创 【微服务即时通讯】消息存储子服务1
首先我们的消息是分成4大类型的纯文本消息图片消息文件消息语音消息// 消息类型枚举,定义不同类型的消息内容STRING = 0;// 纯文本消息IMAGE = 1;// 图片消息FILE = 2;// 文件消息SPEECH = 3;// 语音消息这4种消息的内容是需要不同的数据结构来进行存储的,所以我们就必须需要先将它们定义出来。// 纯文本消息的具体内容// 文字聊天内容// 图片消息的具体内容。
2026-03-25 21:17:28
652
3
原创 【微服务即时通讯】消息转发子服务
还记得我们之前的聊天设计思路吗?多人聊天会话在后台系统中,所有聊天消息都需要被持久化保存,通常通过数据库中的消息存储表来实现。每条消息都必须明确记录其来源与去向,即消息由谁发出、最终要送达给谁。在单聊场景中,这种设计是可行的,因为每一条消息只涉及发送方和接收方两个明确的用户ID。然而,在群聊场景中,同一消息需要送达给多个用户,如果仍在单条消息中记录所有接收者,则面临存储结构上的难题——一条消息难以合理承载多个用户ID,这样的设计既不灵活,也不符合数据库规范。为此,我们引入了“聊天会话”这一中间概念。
2026-03-24 21:18:16
434
原创 【微服务即时通讯】用户管理子服务2
用户名注册:用户使用昵称和密码进行注册,可选验证码验证。用户名登录:用户使用昵称和密码登录,可选验证码验证,成功返回会话 ID。获取邮箱验证码:向指定邮箱发送验证码,返回验证码 ID 用于后续验证。邮箱注册:用户通过邮箱和验证码完成注册,无需密码。邮箱登录:用户通过邮箱和验证码登录(免密登录),成功返回会话 ID。获取当前用户信息:根据会话 ID 或用户 ID 获取登录用户的详细信息。批量获取用户信息:内部接口,根据用户 ID 列表批量查询多个用户的详细信息。修改头像:上传图片数据更新当前登录用户的头像。
2026-03-22 23:35:25
483
原创 【微服务即时通讯】用户管理子服务1
还记得我们整个项目的服务架构吗?当语音识别子服务启动后,其首要任务是:子服务实例(包括服务名称、版本、协议、对外访问地址和端口)为了确保注册信息的准确性和实时性,通常会设置一个租约(lease)并定期续约,这样一旦服务实例崩溃或网络分区,etcd能够自动将过期实例从注册表中移除。注册完成后,该服务实例便成为服务发现体系中的一个可用节点。:子服务后台会启动一个心跳任务,周期性地向etcd刷新租约,告知注册中心自己依然存活。同时,etcd可以配置健康检查机制,主动探测服务实例的状态,进一步增强系统的可靠性。
2026-03-22 11:58:16
784
1
原创 【微服务即时通讯】环境搭建10——Curl实现邮件通知服务
本来我们可以使用短信验证的,但是由于国家政策,个人无法再使用这个短信业务,只有企业才有短信服务资质这样子的话,我们就不能使用短信来进行这个验证了。因此,我们这里采用了邮件来发送我们的验证码。
2026-03-20 18:08:21
497
原创 【微服务即时通讯】文件存储子服务
文件服务主要负责系统中各类文件资源的上传与下载操作,支持单文件与多文件两种处理方式,适用于后台管理端及客户端的不同业务场景。其核心职责包括接收文件数据、调用存储子服务进行持久化处理,以及根据文件标识获取并返回文件内容。功能详细说明1. 文件上传该接口主要用于后台管理场景,例如用户上传头像、发送图片或文件消息等。系统接收到文件数据后,将其转发至文件存储子服务进行保存,并生成对应的文件标识供后续访问使用。适用于后台批量处理场景,例如一次性上传多张图片或多份文档。
2026-03-19 17:31:14
516
原创 【微服务即时通讯】语音识别子服务
我们的数据传输都是借助于我们的protobuf来进行序列化和反序列化首先我们需要定义好,我们的语言识别子服务的speech.proto文件//请求ID//语音数据//用户ID , optional表示这个字段是可选的//登录会话ID -- 网关进行身份鉴权 , optional表示这个字段是可选的//请求ID//请求处理结果标志//失败原因 , optional表示这个字段是可选的//识别后的文字数据 , optional表示这个字段是可选的//语音识别Rpc服务及接口的定义。
2026-03-18 18:08:37
526
原创 【即时通讯项目】环境搭建9——语言平台
无论您是将已有的各种格式音频文件(如 MP3、WAV、AAC 等)转换为符合百度接口规范的 PCM 文件,还是从麦克风实时采集声音并编码为指定格式,FFmpeg 都能通过简洁的命令行操作快速完成,极大地简化音频数据的预处理流程。在您创建完毕应用后,平台将会分配给您此应用的相关凭证,主要为AppID、API Key、 Secret Key。首先我们需要将我们的这个下载的sdk放到我们项目的专门放置第三方库的位置这里来。我们实名认证之后,百度云会赠送我们一定额度的免费资源。是不是和我说的是一模一样的。
2026-03-17 17:33:01
560
原创 【即时通讯项目】环境搭建8——RabbitMQ,AMQP-CPP
RabbitMQRabbitMQ 是一个消息中间件,你可以把它理解成一个专门负责接收、存储和转发消息的程序。它让不同的软件系统或者同一个系统的不同模块之间可以相互通信,但不需要直接连接对方。它的工作方式很简单:有一个发送消息的程序,我们叫它“生产者”。生产者把消息发给 RabbitMQ。RabbitMQ 收到消息后,会把消息保存在一个叫“队列”的地方。另一个接收消息的程序,我们叫它“消费者”。消费者从 RabbitMQ 的队列里取走消息进行处理。解耦。
2026-03-16 21:22:04
994
原创 【即时通讯系统】环境搭建7——ODB
那么在下面的练习中,我们都会把他们放到一个test.hxx文件里面加上我们的测试代码然后我们去编译这个hxx文件然后就会生成一个test.sql文件,我们去里面看看。
2026-03-15 18:28:12
539
原创 【即时通讯系统】环境搭建5——httplib,websocketpp
httplib 是一个轻量级的 C++ 库,用于创建 HTTP 服务器和客户端。它的设计简单而灵活,非常容易设置。只需在代码中包含 httplib.h 文件即可!使得开发者能够在自己的 C++ 项目中轻松地实现基本的 HTTP 通信功能。特性说明简单易用的接口httplib 提供了简单易用的接口,使得创建 HTTP 服务器和客户端变得非常容易。通过少量的代码,你就能够建立起一个功能完善的 HTTP 服务器或客户端。支持主要 HTTP 方法。
2026-03-13 21:52:51
837
原创 【即时通讯系统】环境搭建4——Elasticsearch(ES)
Elasticsearch 是一个分布式搜索和分析引擎,简单来说,它是一个专门用来快速搜索、分析和探索大量数据的工具。想象一下:传统数据库(比如MySQL)就像图书馆的藏书目录,可以帮你找到某本书,但如果想搜索书里的某个词,或者分析所有书的内容趋势,就比较吃力。Elasticsearch 则像给图书馆的每一本书的每一页都做了索引,你可以瞬间搜索到包含某个词的所有页面,还能快速统计哪些词出现最多、哪些作者最常写某个主题等。先从你日常遇到的情况说起场景1:你在淘宝买东西你在搜索框输入“白色运动鞋”
2026-03-13 17:22:56
600
原创 【即时通信系统】环境搭建3——brpc
1. 什么是 RPC?—— brpc 的“主心骨”要理解 brpc,首先要理解RPC。RPC 的全称是 Remote Procedure Call,翻译过来就是“远程过程调用”。什么是“过程调用”?在你的日常编程中,你经常会调用一个函数或一个方法。比如,你在代码里写add(1, 2),这就是一个本地过程调用,意思是“在当前程序里,执行一个叫add的操作,并把结果返回给我”。什么是“远程”?随着互联网的发展,一个复杂的软件系统往往不是由一台机器完成的。
2026-03-10 20:55:04
428
原创 【即时通讯系统】环境搭建2——etcd
etcd 是一个分布式、高可用的键值存储系统,主要用于在分布式系统中可靠地存储和管理关键数据(如配置信息、元数据、服务发现地址),并为其提供强一致性的数据访问保证。接下来,我们从几个关键层面来分解这个定义。键值存储这是它的数据模型,非常简单。你可以把它想象成一个可以远程访问的“字典”或“Map”。你通过一个唯一的“键”(Key)来存放或读取对应的“值”(Value)。例如,键可以是,值可以是。它还支持按“目录”结构组织键,方便管理,例如所有数据库配置都放在目录下。分布式一个 etcd 服务通常由。
2026-03-08 11:36:09
592
原创 【即时通讯系统】环境搭建1——gflags,spdlog
gflags 提供了一系列宏来定义不同类型的命令行参数:1.布尔类型DEFINE_bool(参数名, 默认值, "帮助信息");示例DEFINE_bool(enable_debug, false, "是否启用调试模式");// 使用:--enable_debug 或 --enable_debug=true// 关闭:--noenable_debug 或 --enable_debug=false2.整数类型DEFINE_int32(参数名, 默认值, "帮助信息");// 32位整数。
2026-03-07 10:32:12
793
原创 【即时通讯系统】项目框架与微服务拆分设计
微服务是一种软件架构风格。它将一个大型的、复杂的单体应用程序,按照业务功能或领域,拆分成一组小型独立自治的服务。微:强调的是服务的粒度,即每个服务的职责范围小、功能集中。服务:强调的是每个拆分后的单元都是一个独立的、通过网络接口(通常是HTTP API或RPC)对外提供能力的进程。核心思想:与单体架构的对比要理解微服务,最简单的方式是看它解决了什么问题,即对比传统的单体架构。特性单体架构微服务架构应用结构一个巨大的、包含所有功能的代码库和进程。多个小的、独立的服务进程。
2026-03-07 10:31:08
1035
5
原创 【消息队列项目】自定义网络通信协议模块
protobuf 只帮我们定义了消息正文里应该包含哪些字段(比如请求ID、方法名、参数等),以及如何将这段正文序列化成二进制数据。但序列化后的二进制数据只是“消息正文”,还不能直接扔给TCP发送——因为TCP是流式传输,接收方无法知道一条消息从哪里开始、到哪里结束。这个时候我们就需要制定出我们的自定义网络通信协议来:在实际的网络传输中,TCP协议本身只负责传输字节流,并不关心消息的边界,因此容易出现粘包问题。解决这个问题的关键在于应用层协议的设计,即通过对消息格式的明确定义,来规范数据的封装与解析。
2026-03-02 18:00:48
693
原创 【C++STL】哈希表(HashTable)
什么是哈希表?哈希表是一种通过键(Key)来直接访问值(Value)的数据结构,它利用一个叫做哈希函数的魔法公式,把任意大小的键(比如一个字符串、一个数字或一个对象)转换成一个固定大小的数字,这个数字被称为哈希值或哈希码。然后,用这个哈希值作为数组的索引,将值存储在这个索引对应的数组位置上。这个过程就像给每个键分配一个唯一的座位号(哈希值),然后告诉它:你的数据就放在这个号码的座位上。当你想找这个数据时,只需要用同样的规则再算一次座位号,就能直接走过去拿到它,而不用一个个座位去问。
2026-02-21 10:58:41
1528
原创 【C++STL】红黑树(RBTree)
红⿊树(简称RBT),也是⼀棵二叉搜索树。它是在搜索树的基础上,使每个结点上增加⼀个存储位表⽰ 结点的颜⾊,可以是Red或者Black,通过对任意⼀条从根到叶⼦的路径上各个结点着⾊⽅式的限 制,确保没有⼀条路径会⽐其他路径⻓出2倍,因⽽是⼀棵接近平衡的二叉搜索树。1. 每个结点要么是红⾊要么是⿊⾊;2.根节点和叶⼦结点这⾥的叶⼦结点不是常规意义上的叶⼦结点,⽽是空结点,如下图中的NIL)是⿊⾊的;3. 如果⼀个结点是红⾊的,则它的两个孩⼦结点必须是⿊⾊的,也就是说任意⼀条路径不会有连续的红⾊结点;
2026-02-20 15:02:17
794
原创 【C++STL】平衡二叉树(AVL树)
AVL树是一棵二叉搜索树。为了保证二叉搜索树的性能,规定在插入和删除节点时,要保证任意节点的左、右子树高度差的绝对值不超过1,这样的二叉搜索树称为平衡二叉树(简称AVL树)。
2026-02-17 14:36:25
920
原创 【C++STL】二叉搜索树(BST)
如果cur是父节点的左孩子,那么直接让cur的父节点的左孩子指针指向cur的右节点。如果cur是父节点的右孩子,那么直接让cur的父节点的右孩子指针指向cur的右节点。如果cur是父节点的左孩子,那么直接让cur的父节点的左孩子指针指向cur的左节点。如果cur是父节点的右孩子,那么直接让cur的父节点的右孩子指针指向cur的左节点。的意思是将当前节点替换为它的右孩子。当递归到节点 5 时,root 指向节点 5(即 root 的值是节点 5 的地址),同时 root 就是父节点(10)的左指针的引用。
2026-02-14 14:11:52
685
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅