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

使用python进行人员轨迹跟踪

一、系统概述

该系统基于计算机视觉技术,实现对视频或摄像头画面中的人员进行检测、跟踪,并生成轨迹数据。支持透视变换校准(鸟瞰图显示)、多目标跟踪、轨迹存储及视频录制功能,适用于安防监控、行为分析等场景。

二、依赖库

python

运行

import cv2         # 计算机视觉处理(OpenCV库)
import numpy as np # 数值计算
import time        # 时间处理
import os          # 文件与目录操作
from datetime import datetime # 日期时间处理

三、类定义:PersonTracker

3.1 构造函数 __init__

功能

初始化人员跟踪器,配置视频源、输出参数、背景减除器及跟踪参数。

参数说明
参数名类型默认值描述
video_sourceint/str0视频源(0为默认摄像头,或指定视频文件路径)
save_videoboolFalse是否保存处理后的视频
show_warpedboolTrue是否显示透视变换后的鸟瞰图
内部属性
  • 视频源与基础参数
    • cap:视频捕获对象(cv2.VideoCapture实例)
    • frame_width/frame_height:视频帧宽高
    • fps:帧率
  • 输出配置
    • output_folder:输出文件夹(默认output
    • out:视频写入对象(cv2.VideoWriter实例,仅当save_video=True时创建)
  • 背景减除
    • fgbg:使用MOG2算法的背景减除器,支持阴影检测
  • 跟踪参数
    • min_contour_area/max_contour_area:过滤轮廓的面积阈值(单位像素)
    • trajectories:存储轨迹的字典(键为人员 ID,值为轨迹信息)
    • max_disappeared_frames:允许目标消失的最大帧数(超过则删除轨迹)
    • max_distance:轨迹匹配的最大距离(像素)
  • 透视变换
    • perspective_transform:透视变换矩阵(校准后生成)
    • warped_width/warped_height:鸟瞰图尺寸(宽度固定 500,高度与原始帧一致)

3.2 方法列表

3.2.1 calibrate_perspective()
  • 功能:通过鼠标点击选择 4 个点,校准透视变换矩阵,生成鸟瞰图。
  • 操作说明
    1. 显示视频第一帧,按顺序点击左上、右上、右下、左下四个点,形成矩形区域。
    2. q键退出校准。
  • 返回值boolTrue为校准成功,False为取消或失败)
3.2.2 detect_persons(frame)
  • 功能:在输入帧中检测人员,返回检测结果和二值化掩码。
  • 输入frame(BGR 格式图像)
  • 处理流程
    1. 应用背景减除,生成前景掩码。
    2. 形态学操作(开运算 + 闭运算)去除噪声。
    3. 查找轮廓,过滤面积不符合阈值的轮廓。
    4. 计算每个轮廓的中心点和边界框。
  • 返回值(persons, thresh),其中:
    • persons:检测到的人员列表(每个元素为字典,包含bboxcentercontourarea
    • thresh:二值化掩码图像
3.2.3 track_persons(detected_persons)
  • 功能:根据检测结果更新人员轨迹。
  • 输入detected_personsdetect_persons返回的人员列表)
  • 算法逻辑
    1. 计算现有轨迹与新检测的匹配距离(欧氏距离),优先匹配近距离目标。
    2. 未匹配的轨迹:若连续消失超过max_disappeared_frames,则删除。
    3. 未匹配的检测:创建新轨迹,分配唯一 ID。
3.2.4 draw_results(frame, persons, thresh)
  • 功能:在图像上绘制检测框、轨迹、ID 及统计信息,支持鸟瞰图显示。
  • 输入
    • frame:原始帧
    • persons:检测到的人员列表
    • thresh:二值化掩码(未使用,仅保留接口)
  • 输出:绘制后的结果图像(若show_warped=True,则为原始帧与鸟瞰图的横向拼接图)
3.2.5 save_trajectories()
  • 功能:将当前所有轨迹数据保存到文本文件,包含 ID、起始时间、轨迹点坐标等。
  • 存储路径output_folder/trajectories_时间戳.txt
3.2.6 run()
  • 功能:运行跟踪主循环,处理视频流并实时显示结果。
  • 操作说明
    • q键退出程序。
    • s键保存当前轨迹数据。
  • 流程
    1. 调用calibrate_perspective()进行透视校准(可选)。
    2. 逐帧读取视频,检测、跟踪人员,绘制结果。
    3. 释放资源并关闭窗口。

四、主程序入口

python

运行

if __name__ == "__main__":tracker = PersonTracker(video_source=0,       # 0为摄像头,或指定视频文件路径(如"video.mp4")save_video=True,      # 启用视频录制show_warped=True      # 显示鸟瞰图)tracker.run()

五、使用说明

5.1 环境配置

  1. 安装依赖库:

    bash

    pip install opencv-python numpy
    
  2. 确保摄像头或视频文件可用。

5.2 透视校准操作

  1. 运行程序后,会弹出窗口提示选择 4 个点。
  2. 按顺序点击视频中的矩形区域四角(如地面区域),生成鸟瞰图。
  3. 校准完成后,右侧会显示鸟瞰图中的轨迹。

5.3 输出文件

  • 视频文件:若save_video=True,生成output/tracking_时间戳.avi
  • 轨迹文件:按s键生成output/trajectories_时间戳.txt,包含各 ID 的坐标序列。

六、参数调整建议

参数名作用调整场景
min_contour_area过滤小目标(如噪声)目标较小时调小,反之调大
max_contour_area过滤大目标(如多人重叠)目标较大时调大,反之调小
max_disappeared_frames目标消失后保留轨迹的帧数目标运动间隔较长时调大
max_distance轨迹匹配的最大允许距离目标运动速度快时调大
warped_width鸟瞰图宽度显示区域宽窄调整

七、注意事项

  1. 背景减除器MOG2需要一定时间学习背景(前几秒可能检测不稳定)。
  2. 透视校准的四点应选择实际场景中的矩形区域(如地面边框),以确保鸟瞰图坐标准确。
  3. 若视频帧率较低,可尝试降低warped_width或关闭show_warped以减少计算量。

完成代码

import cv2
import numpy as np
import time
import os
from datetime import datetimeclass PersonTracker:def __init__(self, video_source=0, save_video=False, show_warped=True):"""初始化人员跟踪器"""# 视频源设置self.video_source = video_sourceself.cap = cv2.VideoCapture(video_source)if not self.cap.isOpened():raise ValueError("无法打开视频源", video_source)# 获取视频的宽度、高度和帧率self.frame_width = int(self.cap.get(3))self.frame_height = int(self.cap.get(4))self.fps = self.cap.get(cv2.CAP_PROP_FPS)# 输出设置self.save_video = save_videoself.output_folder = "output"self.show_warped = show_warped# 创建输出文件夹if not os.path.exists(self.output_folder):os.makedirs(self.output_folder)# 背景减除器self.fgbg = cv2.createBackgroundSubtractorMOG2(history=500, varThreshold=100, detectShadows=True)# 人员检测参数self.min_contour_area = 1000  # 最小轮廓面积self.max_contour_area = 50000  # 最大轮廓面积# 轨迹存储self.trajectories = {}  # 存储每个人的轨迹self.next_person_id = 1  # 下一个可用的人员IDself.max_disappeared_frames = 10  # 最大消失帧数self.max_distance = 100  # 最大匹配距离# 透视变换参数self.perspective_transform = Noneself.warped_width = 500self.warped_height = self.frame_height  # 与原始帧高度一致# 录制设置self.out = Noneif save_video:timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")output_path = os.path.join(self.output_folder, f"tracking_{timestamp}.avi")fourcc = cv2.VideoWriter_fourcc(*'XVID')self.out = cv2.VideoWriter(output_path, fourcc, self.fps, (self.frame_width, self.frame_height))def calibrate_perspective(self):"""校准透视变换,创建鸟瞰图"""print("请在图像中选择4个点,形成一个矩形区域,用于透视变换")print("按顺序点击:左上、右上、右下、左下")# 读取一帧用于选择点ret, frame = self.cap.read()if not ret:print("无法读取视频帧")return False# 创建窗口并设置鼠标回调cv2.namedWindow("选择透视变换点 (按 'q' 退出)")points = []def click_event(event, x, y, flags, param):if event == cv2.EVENT_LBUTTONDOWN:points.append((x, y))cv2.circle(frame, (x, y), 5, (0, 255, 0), -1)cv2.imshow("选择透视变换点 (按 'q' 退出)", frame)cv2.setMouseCallback("选择透视变换点 (按 'q' 退出)", click_event)# 显示图像并等待点击cv2.imshow("选择透视变换点 (按 'q' 退出)", frame)while len(points) < 4:key = cv2.waitKey(1) & 0xFFif key == ord('q'):cv2.destroyAllWindows()return Falsecv2.destroyAllWindows()# 定义目标矩形src = np.float32(points)dst = np.float32([[0, 0],[self.warped_width, 0],[self.warped_width, self.warped_height],[0, self.warped_height]])# 计算透视变换矩阵self.perspective_transform = cv2.getPerspectiveTransform(src, dst)return Truedef detect_persons(self, frame):"""检测图像中的人物"""# 应用背景减除fgmask = self.fgbg.apply(frame)# 图像预处理_, thresh = cv2.threshold(fgmask, 127, 255, cv2.THRESH_BINARY)kernel = np.ones((5, 5), np.uint8)thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=3)# 查找轮廓contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)persons = []for contour in contours:area = cv2.contourArea(contour)if area < self.min_contour_area or area > self.max_contour_area:continue# 计算边界框x, y, w, h = cv2.boundingRect(contour)center = (int(x + w/2), int(y + h/2))# 计算轮廓的中心点M = cv2.moments(contour)if M["m00"] != 0:cX = int(M["m10"] / M["m00"])cY = int(M["m01"] / M["m00"])center = (cX, cY)persons.append({'bbox': (x, y, w, h),'center': center,'contour': contour,'area': area})return persons, threshdef track_persons(self, detected_persons):"""跟踪检测到的人员"""# 计算当前检测点与现有轨迹的距离unmatched_tracks = list(self.trajectories.keys())unmatched_detections = list(range(len(detected_persons)))matches = []# 计算所有可能的匹配for track_id in self.trajectories:trajectory = self.trajectories[track_id]last_position = trajectory['positions'][-1]min_distance = float('inf')min_index = -1for i, person in enumerate(detected_persons):if i in unmatched_detections:distance = np.sqrt((last_position[0] - person['center'][0])**2 + (last_position[1] - person['center'][1])**2)if distance < min_distance and distance < self.max_distance:min_distance = distancemin_index = i# 如果找到匹配if min_index != -1:matches.append((track_id, min_index, min_distance))# 按距离排序,优先处理距离近的匹配matches.sort(key=lambda x: x[2])# 应用匹配for match in matches:track_id, detection_index, _ = matchif track_id in unmatched_tracks and detection_index in unmatched_detections:# 更新轨迹self.trajectories[track_id]['positions'].append(detected_persons[detection_index]['center'])self.trajectories[track_id]['last_seen'] = 0self.trajectories[track_id]['bbox'] = detected_persons[detection_index]['bbox']# 从待匹配列表中移除unmatched_tracks.remove(track_id)unmatched_detections.remove(detection_index)# 处理未匹配的轨迹for track_id in unmatched_tracks:self.trajectories[track_id]['last_seen'] += 1if self.trajectories[track_id]['last_seen'] > self.max_disappeared_frames:del self.trajectories[track_id]# 处理未匹配的检测结果for detection_index in unmatched_detections:# 创建新轨迹self.trajectories[self.next_person_id] = {'positions': [detected_persons[detection_index]['center']],'last_seen': 0,'bbox': detected_persons[detection_index]['bbox'],'start_time': time.time()}self.next_person_id += 1def draw_results(self, frame, persons, thresh):"""在图像上绘制检测和跟踪结果"""output = frame.copy()# 绘制检测到的人物for person in persons:x, y, w, h = person['bbox']cv2.rectangle(output, (x, y), (x + w, y + h), (0, 255, 0), 2)cv2.circle(output, person['center'], 5, (0, 0, 255), -1)# 绘制轨迹for track_id, trajectory in self.trajectories.items():positions = trajectory['positions']# 绘制轨迹线for i in range(1, len(positions)):cv2.line(output, positions[i-1], positions[i], (255, 0, 0), 2)# 绘制轨迹点for pos in positions:cv2.circle(output, pos, 3, (255, 0, 0), -1)# 绘制ID和轨迹长度if len(positions) > 0:last_pos = positions[-1]cv2.putText(output, f"ID: {track_id}", (last_pos[0] + 10, last_pos[1] - 20),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)cv2.putText(output, f"Points: {len(positions)}", (last_pos[0] + 10, last_pos[1]),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)# 显示统计信息cv2.putText(output, f"Persons: {len(self.trajectories)}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)cv2.putText(output, f"FPS: {int(self.fps)}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)# 创建结果显示窗口if self.show_warped and self.perspective_transform is not None:# 创建鸟瞰图warped = cv2.warpPerspective(output, self.perspective_transform, (self.warped_width, self.warped_height))# 在鸟瞰图上绘制轨迹for track_id, trajectory in self.trajectories.items():positions = trajectory['positions']for i in range(1, len(positions)):# 将原始坐标转换为鸟瞰图坐标pos1 = np.array([[positions[i-1][0], positions[i-1][1]]], dtype=np.float32).reshape(-1, 1, 2)pos2 = np.array([[positions[i][0], positions[i][1]]], dtype=np.float32).reshape(-1, 1, 2)warped_pos1 = cv2.perspectiveTransform(pos1, self.perspective_transform)[0][0]warped_pos2 = cv2.perspectiveTransform(pos2, self.perspective_transform)[0][0]cv2.line(warped, (int(warped_pos1[0]), int(warped_pos1[1])),(int(warped_pos2[0]), int(warped_pos2[1])), (255, 0, 0), 2)# 合并显示combined = np.hstack((output, warped))return combinedreturn outputdef save_trajectories(self):"""保存轨迹数据到文件"""timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")output_path = os.path.join(self.output_folder, f"trajectories_{timestamp}.txt")with open(output_path, 'w') as f:f.write("Person Trajectories\n")f.write(f"Recorded on: {datetime.now()}\n\n")for track_id, trajectory in self.trajectories.items():f.write(f"Person ID: {track_id}\n")f.write(f"Start Time: {time.ctime(trajectory['start_time'])}\n")f.write(f"Duration: {time.time() - trajectory['start_time']:.2f} seconds\n")f.write(f"Trajectory Points: {len(trajectory['positions'])}\n")f.write("Positions:\n")for pos in trajectory['positions']:f.write(f"  ({pos[0]}, {pos[1]})\n")f.write("\n")print(f"轨迹数据已保存到: {output_path}")def run(self):"""运行人员跟踪系统"""# 首先进行透视校准if not self.calibrate_perspective():print("透视校准失败,使用原始视角")print("开始人员跟踪...")print("按 'q' 退出,按 's' 保存轨迹数据")frame_count = 0start_time = time.time()while True:ret, frame = self.cap.read()if not ret:break# 计算实际帧率frame_count += 1if frame_count % 10 == 0:elapsed_time = time.time() - start_timeself.fps = frame_count / elapsed_time# 检测人员persons, thresh = self.detect_persons(frame)# 跟踪人员self.track_persons(persons)# 绘制结果result = self.draw_results(frame, persons, thresh)# 保存视频if self.save_video:self.out.write(result)# 显示结果cv2.imshow("人员轨迹跟踪系统 (按 'q' 退出,按 's' 保存轨迹)", result)# 按键处理key = cv2.waitKey(1) & 0xFFif key == ord('q'):breakelif key == ord('s'):self.save_trajectories()# 释放资源self.cap.release()if self.out:self.out.release()cv2.destroyAllWindows()print("人员跟踪系统已关闭")# 主程序入口
if __name__ == "__main__":# 创建人员跟踪器实例tracker = PersonTracker(video_source=0,  # 0表示默认摄像头,也可以指定视频文件路径save_video=True,  # 是否保存视频show_warped=True  # 是否显示鸟瞰图)# 运行跟踪器tracker.run()    

相关文章:

使用python进行人员轨迹跟踪

一、系统概述 该系统基于计算机视觉技术&#xff0c;实现对视频或摄像头画面中的人员进行检测、跟踪&#xff0c;并生成轨迹数据。支持透视变换校准&#xff08;鸟瞰图显示&#xff09;、多目标跟踪、轨迹存储及视频录制功能&#xff0c;适用于安防监控、行为分析等场景。 二…...

强化学习入门:马尔科夫奖励过程二

文章目录 前言1、动作2、策略总结 前言 最近想开一个关于强化学习专栏&#xff0c;因为DeepSeek-R1很火&#xff0c;但本人对于LLM连门都没入。因此&#xff0c;只是记录一些类似的读书笔记&#xff0c;内容不深&#xff0c;大多数只是一些概念的东西&#xff0c;数学公式也不会…...

JVM 双亲委派机制

一、从 JDK 到 JVM&#xff1a;Java 运行环境的基石 在 Java 开发领域&#xff0c;JDK&#xff08;Java Development Kit&#xff09;是开发者的核心工具包。它不仅包含了编译 Java 代码的工具&#xff08;如 javac&#xff09;&#xff0c;还内置了 JRE&#xff08;Java Run…...

uniapp -- uCharts 仪表盘刻度显示 0.9999999 这样的值问题处理。

文章目录 🍉问题🍉解决方案🍉问题 在仪表盘上,23.8变成了 23.799999999999997 🍉解决方案 formatter格式化问题 1:在 config-ucharts.js 或 config-echarts.js 配置对应的 formatter 方法 formatter: {yAxisDemo1: function (...

BGP团体属性

团体属性&#xff1a; 1、用于限制BGP路由的传递范围 2、类似于IGP协议中的tag值&#xff0c;用于对BGP路由实现标记。 团体属性的分类&#xff1a; 1、公共团体属性&#xff1a; Internet&#xff1a;默认所有路由都有该属性&#xff0c;具有该属性BGP路由发送给所有的BGP邻居…...

Redis——三大策略

过期删除策略 Redis可以对key设置过期时间&#xff0c;因此需要有相应的机制将已过期的键值对删除 设置了过期时间的key会存放在过期字典中&#xff0c;可以用presist命令取消key过期时间 过期字典存储在redisDb结构中&#xff1a; typedef struct redisDb {dict *dict; …...

Windows 操作系统使用 Tcping 命令检查目标主机端口是否开放

检查目标主机端口是否开放的方法已经很多了&#xff0c;网络上也有第三方网页版的检查工具&#xff0c;这篇文章给大家介绍一个实用小工具 Tcping 。 一、下载安装 Tcping 命令 Tcping 非 Windows 自带命令&#xff0c;我们需要下载 Tcping 可执行文件&#xff0c;然后将该文…...

序列化和反序列化:从理论到实践的全方位指南

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…...

PDF Base64格式字符串转换为PDF文件临时文件

需求描述&#xff1a; 在对接电子病历系统与河北CA&#xff0c;进行免密文件签章的时候&#xff0c;两者系统入参不同&#xff0c;前者是pdf文件&#xff0c;base64格式&#xff1b;后者要求File类型的PDF文件。 在业务中间层开发时&#xff0c;则需要接收EMR侧提供的base64格式…...

开源RTOS(实时操作系统):nuttx 编译

开源RTOS&#xff08;实时操作系统&#xff09;&#xff1a;nuttx 编译 手册&#xff1a;Installing — NuttX latest documentation 源码&#xff1a;GitHub - apache/nuttx: Apache NuttX is a mature, real-time embedded operating system (RTOS) Installing The fir…...

python打包exe报错:处理文件时错误:Excel xlsx file; not supported

背景&#xff1a;最近用python写一个excel解析工具&#xff0c;然后打包成exe可执行文件的时候&#xff0c;遇到这样的问题 1.在我自己编译器运行是可以正常将上传后的excel进行解析&#xff0c;但是在打包成exe后&#xff0c;就无法正常解析excel 问题排查&#xff1a; 1.切换…...

VUE3 -综合实践(Mock+Axios+ElementPlus)

目录 前言 目标 1.工程创建 2.Mock 2.1 配置Mock 扩 展 2.2 定义模拟数据 2.3 创建Mock服务器 3.导入ElementPlus 4.表格页面搭建 5.动态路由跳转 6.详情页面的制作 前言 基于前文 VUE3详细入门&#xff0c;我们对VUE3的基本使用有了初步的了解&#xff0c;下…...

NDS3211HV单路H.264/HEVC/HD视频编码器

1产品概述 NDS3211HV单路高清编码器是一款功能强大的音/视频编码设备&#xff0c;支持2组立体声&#xff0c;同时还支持CC(CVBS)字幕。支持多种音频编码方式。该设备配备了多种音/视频输入接口&#xff1a;HD-SDI数字视频输入、HDMI高清输入&#xff08;支持CC&#xff09;、A…...

LeetCode热题100--206.反转链表--简单

1. 题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1] 示例 3&…...

来一个复古的技术FTP

背景 10年前的老代码&#xff0c;需要升级springboot框架&#xff0c;在升级过程中&#xff0c;测试业务流程里&#xff0c;有FTP的下载业务&#xff0c;不管测试环境如何测试&#xff0c;都没有成功&#xff0c;最后只能自己搭建一个FTP服务器&#xff0c;写一个ftp-demo来测试…...

OpenCV CUDA模块中矩阵操作------分布统计类

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 OpenCV 的 CUDA 模块中&#xff0c;meanStdDev 函数用于计算矩阵的平均值&#xff08;Mean&#xff09;和标准差&#xff08;StdDev&#xff…...

OpenWebUI新突破,MCPO框架解锁MCP工具新玩法

大家好&#xff0c;Open WebUI 迎来重要更新&#xff0c;现已正式支持 MCP 工具服务器&#xff0c;但 MCP 工具服务器需由兼容 OpenAPI 的代理作为前端。mcpo 是一款实用代理&#xff0c;经测试&#xff0c;它能让开发者使用 MCP 服务器命令和标准 OpenAPI 服务器工具&#xff…...

go.mod关于go版本异常的处理

​ 1.私有仓库 go.mod 要注意module的配置mod地址&#xff0c;要与下载地址一致。 否则就算下载下来&#xff0c;就会比较后报错。 module test.com/devGroup/devProjectgo 1.22.2 2. 代码中的包引用地址。 要与module中的mod路径一致 package mainimport ("module …...

TRTC实时对话式AI解决方案,助力人机语音交互极致体验

近年来&#xff0c;AI热度持续攀升&#xff0c;无论是融资规模还是用户热度都大幅增长。2023 年&#xff0c;中国 AI 行业融资规模达2631亿人民币&#xff0c;较2022年上升51%&#xff1b;2024年第二季度&#xff0c;全球 AI 初创企业融资规模为 240 亿美金&#xff0c;较第一季…...

Linux安全篇 --firewalld

一、Firewalld 防火墙概述 1、Firewalld 简介 firewalld 的作用是为包过滤机制提供匹配规则(或称为策略)&#xff0c;通过各种不同的规则告诉netfilter 对来自指定源、前往指定目的或具有某些协议特征的数据包采取何种处理方式为了更加方便地组织和管理防火墙,firewalld 提供…...

系分论文《论系统需求分析方法及应用》

系统分析师论文范文系列 【摘要】 2022年6月&#xff0c;我作为系统分析师参与了某金融机构“智能信贷风控系统”的建设项目。该系统旨在通过对业务流程的数字化重构&#xff0c;优化信贷审批效率并降低风险。项目涉及信贷申请、资质审核、风险评估、额度审批等核心流程&#x…...

LIIGO ❤️ RUST: 12 YEARS

LIIGO &#x1f496; RUST: 12 YEARS 今天是RUST语言1.0发布十周年纪念日。十年前的今天&#xff0c;2015年的今天&#xff0c;Rust 1.0 正式发行。这是值得全球Rust支持者隆重纪念的日子。我借此机会衷心感谢Rust语言创始人Graydon Hoare&#xff0c;Mozilla公司&#xff0c;…...

SQL、Oracle 和 SQL Server 的比较与分析

SQL、Oracle 和 SQL Server 的比较与分析 一、基础概念 1. SQL (Structured Query Language) 定义&#xff1a;结构化查询语言&#xff0c;用于管理关系型数据库的标准语言类型&#xff1a; DDL (数据定义语言)&#xff1a;CREATE, ALTER, DROPDML (数据操作语言)&#xff1…...

Trivy:让你时刻掌控的开源安全扫描器

深入了解 Trivy:全面的安全扫描工具 在如今互联网快速发展的时代,软件的安全性显得尤为重要。随着应用程序的复杂性增加,其可能带来的安全漏洞也在不断增多。如何快速、准确地发现这些潜在威胁是每个开发者和运维人员心中的课题。今天,我们将为大家介绍一个开源的安全扫描…...

LlamaIndex 第八篇 MilvusVectorStore

本指南演示了如何使用 LlamaIndex 和 Milvus 构建一个检索增强生成&#xff08;RAG&#xff09;系统。 RAG 系统将检索系统与生成模型相结合&#xff0c;根据给定的提示生成新的文本。该系统首先使用 Milvus 等向量相似性搜索引擎从语料库中检索相关文档&#xff0c;然后使用生…...

2022河南CCPC(前四题)

签到题目 #include <bits/stdc.h> using namespace std; #define int long long #define PII pair<int,int> #define fi first #define se second #define endl \n #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);void solve() {int n;cin>>…...

谷歌浏览器(Google Chrome)136.0.7103.93便携增强版|Win中文|安装教程

软件下载 【名称】&#xff1a;谷歌浏览器&#xff08;Google Chrome&#xff09;136.0.7103.93 【大小】&#xff1a;170M 【语言】&#xff1a;简体中文 【安装环境】&#xff1a;Win10/Win11 【夸克网盘下载链接】&#xff08;务必手机注册&#xff09;&#xff1a; h…...

高可用消息队列实战:AWS SQS 在分布式系统中的核心解决方案

引言&#xff1a;消息队列的“不可替代性” 在微服务架构和分布式系统盛行的今天&#xff0c;消息队列&#xff08;Message Queue&#xff09; 已成为解决系统解耦、流量削峰、异步处理等难题的核心组件。然而&#xff0c;传统的自建消息队列&#xff08;如RabbitMQ、Kafka&am…...

「Mac畅玩AIGC与多模态41」开发篇36 - 用 ArkTS 构建聚合搜索前端页面

一、概述 本篇基于上一节 Python 实现的双通道搜索服务&#xff08;聚合 SearxNG 本地知识库&#xff09;&#xff0c;构建一个完整的 HarmonyOS ArkTS 前端页面。用户可在输入框中输入关键词&#xff0c;实时查询本地服务 http://localhost:5001/search?q...&#xff0c;返…...

springCloud/Alibaba常用中间件之Seata分布式事务

文章目录 SpringCloud Alibaba:依赖版本补充Seata处理分布式事务(AT模式)AT模式介绍核心组件介绍AT的工作流程&#xff1a;两阶段提交&#xff08;**2PC**&#xff09; Seata-AT模式使用Seata(2.0.0)下载、配置和启动Seata案例实战前置代码添加全局注解 GlobalTransactional Sp…...