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

基于OpenCV的实时文档扫描与矫正技术

文章目录

    • 引言
    • 一、系统概述
    • 二、核心代码解析
      • 1. 导入必要库
      • 2. 辅助函数定义
      • 3. 坐标点排序函数
      • 4. 透视变换函数
      • 5. 主程序流程
    • 三、完整代码
    • 四、结语

引言

在日常工作和学习中,我们经常需要将纸质文档数字化。手动拍摄文档照片常常会出现角度倾斜、透视变形等问题,影响后续使用。本文将介绍如何使用Python和OpenCV构建一个实时文档扫描与矫正系统,能够通过摄像头自动检测文档边缘并进行透视变换矫正。

一、系统概述

该系统主要实现以下功能:

  1. 实时摄像头捕获图像
  2. 边缘检测和轮廓查找
  3. 文档轮廓识别
  4. 透视变换矫正文档
  5. 二值化处理增强可读性

二、核心代码解析

1. 导入必要库

import numpy as np
import cv2

我们主要使用NumPy进行数值计算,OpenCV进行图像处理。

2. 辅助函数定义

首先定义了一个简单的图像显示函数,方便调试:

def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(10)

3. 坐标点排序函数

order_points函数用于将检测到的文档四个角点按顺序排列(左上、右上、右下、左下):

def order_points(pts):rect = np.zeros((4,2),dtype="float32")s = pts.sum(axis=1)rect[0] = pts[np.argmin(s)]  # 左上点(x+y最小)rect[2] = pts[np.argmax(s)]  # 右下点(x+y最大)diff = np.diff(pts,axis=1)rect[1] = pts[np.argmin(diff)]  # 右上点(y-x最小)rect[3] = pts[np.argmax(diff)]  # 左下点(y-x最大)return rect

这个函数的作用是对给定的4个二维坐标点进行排序,使其按照左上、右上、右下、左下的顺序排列。这在文档扫描、图像矫正等应用中非常重要,因为我们需要知道每个角点的确切位置才能正确地进行透视变换。

函数详细解析

(1)排序逻辑说明

  1. 左上点(rect[0]):选择x+y值最小的点

    • 因为左上角在坐标系中 x 和 y 值都较小,相加结果最小
  2. 右下点(rect[2]):选择x+y值最大的点

    • 因为右下角在坐标系中 x 和 y 值都较大,相加结果最大
  3. 右上点(rect[1]):选择y-x值最小的点

    • 右上角的特点是 y 相对较小而 x 相对较大,所以 y-x 值最小
  4. 左下点(rect[3]):选择y-x值最大的点

    • 左下角的特点是 y 相对较大而 x 相对较小,所以 y-x 值最大

(2)示例

假设有4个点:

	A(10, 20)  # 假设是左上B(50, 20)  # 右上C(50, 60)  # 右下D(10, 60)  # 左下

计算过程:

  1. x+y值:[30, 70, 110, 70]

    • 最小30 → A(左上)
    • 最大110 → C(右下)
  2. y-x值:[10, -30, 10, 50]

    • 最小-30 → B(右上)
    • 最大50 → D(左下)

最终排序结果:[A, B, C, D] 即 [左上, 右上, 右下, 左下]

(3)为什么这种方法有效

这种方法利用了二维坐标点的几何特性:

  • 在标准坐标系中,左上角的x和y值都较小
  • 右下角的x和y值都较大
  • 右上角的x较大而y较小
  • 左下角的x较小而y较大

通过简单的加减运算就能可靠地区分出各个角点,不需要复杂的几何计算。

4. 透视变换函数

four_point_transform函数实现了文档矫正的核心功能:

def four_point_transform(image,pts):rect = order_points(pts)(tl,tr,br,bl) = rect# 计算变换后的宽度和高度widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))maxWidth = max(int(widthA),int(widthB))heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))maxHeight = max(int(heightA),int(heightB))# 定义目标图像坐标dst = np.array([[0,0],[maxWidth - 1,0],[maxWidth - 1,maxHeight - 1],[0,maxHeight - 1]],dtype="float32")# 计算透视变换矩阵并应用M = cv2.getPerspectiveTransform(rect,dst)warped = cv2.warpPerspective(image,M,(maxWidth,maxHeight))return warped

这个函数实现了透视变换(Perspective Transformation),用于将图像中的任意四边形区域矫正为一个矩形(即"去透视"效果)。

函数详细解析

  1. 输入参数
def four_point_transform(image, pts):
  • image: 原始图像
  • pts: 包含4个点的数组,表示要转换的四边形区域
  1. 坐标点排序
rect = order_points(pts)
(tl, tr, br, bl) = rect  # 分解为左上(top-left)、右上(top-right)、右下(bottom-right)、左下(bottom-left)

使用之前介绍的order_points函数将4个点按顺序排列

  1. 计算输出图像的宽度
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))  # 底边长度
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))  # 顶边长度
maxWidth = max(int(widthA), int(widthB))  # 取最大值作为输出图像宽度

计算四边形底部和顶部的边长,选择较长的作为输出宽度

  1. 计算输出图像的高度
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))  # 右边高度
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))  # 左边高度
maxHeight = max(int(heightA), int(heightB))  # 取最大值作为输出图像高度

计算四边形右侧和左侧的边长,选择较长的作为输出高度

  1. 定义目标矩形坐标
dst = np.array([[0, 0],  # 左上[maxWidth - 1, 0],  # 右上[maxWidth - 1, maxHeight - 1],  # 右下[0, maxHeight - 1]  # 左下
], dtype="float32")

定义变换后的矩形角点坐标(从(0,0)开始的正矩形)

  1. 计算透视变换矩阵并应用
M = cv2.getPerspectiveTransform(rect, dst)  # 计算变换矩阵
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))  # 应用变换
  • getPerspectiveTransform: 计算从原始四边形到目标矩形的3x3变换矩阵
  • warpPerspective: 应用这个变换矩阵到原始图像
  1. 返回结果
return warped

返回矫正后的矩形图像

  1. 透视变换原理图示
原始图像中的四边形               变换后的矩形tl--------tr                    0--------maxWidth\        /                      |        |\      /                       |        |bl----br                       maxHeight
  1. 为什么需要这样计算宽度和高度?

取最大值的原因

  • 原始四边形可能有透视变形,两条对边长度可能不等
  • 选择较大的值可以确保所有内容都能包含在输出图像中

减1的原因

  • 图像坐标从0开始,所以宽度为maxWidth的图像,最大x坐标是maxWidth-1

5. 主程序流程

主程序实现了实时文档检测和矫正的完整流程:

  1. 初始化摄像头
cap = cv2.VideoCapture(0)
if not cap.isOpened():print("Cannot open camera")exit()
  1. 实时处理循环
while True:flag = 0ret,image = cap.read()orig = image.copy()if not ret:print("不能读取摄像头")break
  1. 图像预处理
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(5,5),0)  # 高斯滤波降噪
edged = cv2.Canny(gray,75,200)  # Canny边缘检测
  1. 轮廓检测与筛选
cnts = cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]
cnts = sorted(cnts,key=cv2.contourArea,reverse=True)[:3]  # 取面积最大的3个轮廓for c in cnts:peri = cv2.arcLength(c,True)  # 计算轮廓周长approx = cv2.approxPolyDP(c,0.05 * peri,True)  # 多边形近似area = cv2.contourArea(approx)# 筛选四边形且面积足够大的轮廓if area > 20000 and len(approx) == 4:screenCnt = approxflag = 1break
  1. 文档矫正与显示
if flag == 1:# 绘制轮廓image_contours = cv2.drawContours(image,[screenCnt],0,(0,255,0),2)# 透视变换warped = four_point_transform(orig,screenCnt.reshape(4,2))# 二值化处理warped = cv2.cvtColor(warped,cv2.COLOR_BGR2GRAY)ref = cv2.threshold(warped,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

三、完整代码

# 导入工具包
import numpy as np
import cv2def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(10)
def order_points(pts):# 一共4个坐标点rect = np.zeros((4,2),dtype="float32") # 用来存储排序之后的坐标位置# 按顺序找到对应坐标0123分别是 左上、右上、右下、左下s = pts.sum(axis=1) #对pts矩阵的每一行进行求和操作,(x+y)rect[0] = pts[np.argmin(s)]rect[2] = pts[np.argmax(s)]diff = np.diff(pts,axis=1) #对pts矩阵的每一行进行求差操作,(y-x)rect[1] = pts[np.argmin(diff)]rect[3] = pts[np.argmax(diff)]return rectdef four_point_transform(image,pts):# 获取输入坐标点rect = order_points(pts)(tl,tr,br,bl) = rect# 计算输入的w和h值widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))maxWidth = max(int(widthA),int(widthB))heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))maxHeight = max(int(heightA),int(heightB))# 变换后对应坐标位置dst = np.array([[0,0],[maxWidth - 1,0],[maxWidth - 1,maxHeight - 1],[0,maxHeight - 1]],dtype="float32")M = cv2.getPerspectiveTransform(rect,dst)warped = cv2.warpPerspective(image,M,(maxWidth,maxHeight))# 返回变换后的结果return warped# 读取输入
import cv2
cap = cv2.VideoCapture(0)  # 确保摄像头是可以启动的状态
if not cap.isOpened():   #打开失败print("Cannot open camera")exit()while True:flag = 0 # 用于标时 当前是否检测到文档ret,image = cap.read()  # 如果正确读取帧,ret为Trueorig = image.copy()if not ret: #读取失败,则退出循环print("不能读取摄像头")breakcv_show("image",image)gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)# 预处理gray = cv2.GaussianBlur(gray,(5,5),0) # 高斯滤波edged = cv2.Canny(gray,75,200)cv_show('1',edged)# 轮廓检测cnts = cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]cnts = sorted(cnts,key=cv2.contourArea,reverse=True)[:3]image_contours = cv2.drawContours(image,cnts,-1,(0,255,0),2)cv_show("image_contours",image_contours)# 遍历轮廓for c in cnts:# 计算轮廓近似peri = cv2.arcLength(c,True) # 计算轮廓的周长# C 表示输入的点集# epsilon表示从原始轮廓到近似轮廓的最大距离,它是一个准确度参数# True表示封闭的approx = cv2.approxPolyDP(c,0.05 * peri,True) # 轮廓近似area = cv2.contourArea(approx)# 4个点的时候就拿出来if area > 20000 and len(approx) == 4:screenCnt = approxflag = 1print(peri,area)print("检测到文档")breakif flag == 1:# 展示结果# print("STEP 2: 获取轮廓")image_contours = cv2.drawContours(image,[screenCnt],0,(0,255,0),2)cv_show("image",image_contours)# 透视变换warped = four_point_transform(orig,screenCnt.reshape(4,2))cv_show("warped",warped)# 二值处理warped = cv2.cvtColor(warped,cv2.COLOR_BGR2GRAY)# ref = cv2.threshold(warped,220,255,cv2.THRESH_BINARY)[1]ref = cv2.threshold(warped,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]cv_show("ref",ref)
cap.release() # 释放捕捉器
cv2.destroyAllWindows() #关闭图像窗口

四、结语

本文介绍了一个基于OpenCV的实时文档扫描与矫正系统,通过边缘检测、轮廓分析和透视变换等技术,实现了文档的自动检测和矫正。该系统可以方便地应用于日常文档数字化工作,提高工作效率。

完整代码已在上文中给出,读者可以根据自己的需求进行修改和扩展。OpenCV提供了强大的图像处理能力,结合Python的简洁语法,使得开发这样的实用系统变得简单高效。

相关文章:

基于OpenCV的实时文档扫描与矫正技术

文章目录 引言一、系统概述二、核心代码解析1. 导入必要库2. 辅助函数定义3. 坐标点排序函数4. 透视变换函数5. 主程序流程 三、完整代码四、结语 引言 在日常工作和学习中,我们经常需要将纸质文档数字化。手动拍摄文档照片常常会出现角度倾斜、透视变形等问题&…...

基于STM32F103与Marvell88W8686的WIFI无线监控视频传输系统研发(论文)

基于STM32F103与Marvell88W8686的WIFI无线监控视频传输系统研发 中文摘要 在当今社会信息化进程不断加速的时代背景下,众多领域对于监控系统的需求日益增长,像车内安全监控、电梯运行监控等场景都离不开监控系统的支持。过去,不少领域普遍采用…...

华为云Astro中各种变量与参数的区别与用法

目录 🧠 华为云 Astro 各类变量与参数详解 🧩 一、变量与参数的核心作用是什么? 🖼️ 二、整体分类与结构图 📘 三、逐一详细解析 + 类比说明 + 使用建议 🔹 1. 输入参数(Input Parameter) 🔹 2. 输出参数(Output Parameter) 🔹 3. 变量(本地变量)…...

数字人技术的核心:AI与动作捕捉的双引擎驱动(210)

**摘要:**数字人技术从静态建模迈向动态交互,AI与动作捕捉技术的深度融合推动其智能化发展。尽管面临表情僵硬、动作脱节、交互机械等技术瓶颈,但通过多模态融合技术、轻量化动捕方案等创新,数字人正逐步实现自然交互与情感表达。…...

华为云Astro轻应用创建业务对象(BO)的概念梳理

目录 一、业务对象(BO)是什么?——【详细概念解释】 二、形象理解业务对象(BO) 🍱 类比方式: 📦 举个具体例子:以做一个“智能烟雾报警系统”应用 三、为什么使用BO很重要? 四、小结: 一、业务对象(BO)是什么?——【详细概念解释】 在华为云Astro轻应用…...

MySQL开发规范

目录 一、建表规约 二、索引规约 三、SQL语句 四、 ORM映射 一、建表规约 强制: 1、表达是与否概念的字段,必须使用is_xxx的方式命名(PoJo中不加is前缀),数据类型是unsigned tinyint(1表示是&#xf…...

K8s入门教程(一)

Kubernetes(K8s)入门教程:从零开始掌握容器编排 目录 Kubernetes(K8s)入门教程:从零开始掌握容器编排 1. Kubernetes 简介 1.1 什么是 Kubernetes? 1.2 核心功能 2. 环境搭建与 Minikube 安装 2.1 安装 Minikube 安装步骤(以 macOS 为例): 安装 kubectl(Kub…...

k8s备份namespace

在 Kubernetes 中备份 Namespace 有多种方法&#xff0c;以下是几种常见的备份方式&#xff1a; 1.使用 kubectl 命令备份 通过 kubectl 命令可以导出指定 Namespace 中的资源&#xff0c;生成 YAML 文件进行备份。 备份所有资源&#xff1a; kubectl -n <namespace> ge…...

前端动画库 Anime.js 的V4 版本,兼容 Vue、React

前端动画库 Anime.js 更新了 V4 版本&#xff0c;并对其官网进行了全面更新&#xff0c;增加了许多令人惊艳的效果&#xff0c;尤其是时间轴动画效果&#xff0c;让开发者可以更精确地控制动画节奏。 这一版本的发布不仅带来了全新的模块化 API 和显著的性能提升&#xff0c;还…...

OpenHarmony外设驱动使用 (四),Face_auth

OpenHarmony外设驱动使用 &#xff08;四&#xff09; Face_auth 概述 功能简介 人脸识别功能是端侧设备不可或缺的一部分&#xff0c;为设备提供一种用户认证能力&#xff0c;可应用于设备解锁、支付、应用登录等身份认证场景。它是基于人的脸部特征信息进行身份识别的一种…...

【Java ee初阶】jvm(1)

一、JVM Java虚拟机 面试中相关的问题有三块&#xff1a; 1.JVM内存区域划分 2.JVM的类加载机制 3.JVM的垃圾回收机制 JDK、JRE 和 JVM 的关系 JDK&#xff08;Java Development Kit&#xff09;是 Java 开发工具包&#xff0c;包含了编写、编译和调试 Java 程序所需的所…...

【Java ee初阶】jvm(2)

类加载机制&#xff1a; JVM从最开始的读取.class文件&#xff0c;到最终构造完成 类 对象的整个过程&#xff0c;也就是把 类 从硬盘 加载到内存中的机制。 Java的类加载机制主要分为五个步骤&#xff1a;加载、验证、准备、解析和初始化。 步骤一 加载&#xff08;Loading…...

Django 项目创建全攻略

目录 一、环境准备​ 1. 安装 Python​ 2. 安装虚拟环境&#xff08;可选但推荐&#xff09;​ 3. 安装 Django​ 二、创建 Django 项目​ 1. 使用命令创建项目​ 2. 运行开发服务器​ 三、创建 Django 应用​ 1. 创建应用​ 2. 注册应用​ 四、配置项目​ 1. 数据…...

windows11 安装好后右键没有 git bash 命令

win键 R 键&#xff0c;输出 regedit&#xff0c;打开注册表 找到 \HKEY_CLASSES_ROOT\Directory\Background\shell 新建项 git-bash 然后在 git-bash 下在新建项 Command&#xff0c;默认值设为 "C:\Program Files\Git\git-bash.exe" --cd"%v." 在 …...

Java八股文——Java基础篇

目录 1、你是怎样理解OOP面向对象2、重载和重写的区别3、接口与抽象类的区别4、深拷贝与浅拷贝的理解5、sleep和wait区别主要区别 6、什么是自动拆装箱&#xff0c;int和Integer有什么区别自动拆装箱int和Integer的区别Integer缓存机制 7、和equals区别String特殊情况 8、Strin…...

蓝桥杯19682 完全背包

问题描述 有 N 件物品和一个体积为 M 的背包。第 i 个物品的体积为 vi​&#xff0c;价值为 wi​。每件物品可以使用无限次。 请问可以通过什么样的方式选择物品&#xff0c;使得物品总体积不超过 M 的情况下总价值最大&#xff0c;输出这个最大价值即可。 输入格式 第一行…...

2025年- H27-Lc135- 239.滑动窗口最大值(自定义双端队列)---java版

1.题目描述 2.思路 &#xff08;1&#xff09;双端队列可以移除最左边的元素&#xff0c;也可以移除最右边的元素&#xff08;两端移除&#xff09; &#xff08;2&#xff09;在最右边插入元素&#xff08;右边加入&#xff09; &#xff08;3&#xff09;队列单调性&#xf…...

EKS 工作节点的集群网络架构

AWS EKS&#xff08;弹性 Kubernetes 服务&#xff09;是亚马逊提供的托管 Kubernetes 服务&#xff0c;一旦配置完成&#xff0c;即可像变魔术一样运行。但这通常是 EKS 的默认设置。如果您打算根据组织的设计、合规性标准和隐私要求进行自定义&#xff0c;该怎么办&#xff1…...

【技海登峰】Kafka漫谈系列(十一)SpringBoot整合Kafka之消费者Consumer

【技海登峰】Kafka漫谈系列(十一)SpringBoot整合Kafka之消费者Consumer spring-kafka官方文档: https://docs.spring.io/spring-kafka/docs/2.8.10/reference/pdf/spring-kafka-reference.pdf KafkaTemplate API: https://docs.spring.io/spring-kafka/api/org/springframe…...

Python字符串格式化(一):三种经典格式化方法

文章目录 一、% operator&#xff1a;C语言风格的初代格式化方案&#xff08;Python 2.0引入&#xff09;1. 语法核心&#xff1a;占位符与类型码2. 进阶用法&#xff1a;格式修饰符3. 致命缺陷&#xff1a;类型严格匹配的陷阱4. 适用场景&#xff1a;旧代码维护的兼容性选择 二…...

浅谈无服务器WebSocket的优势

实际上&#xff0c;一个实用的解决方案是将构建业务关键型实时平台的复杂性卸载到专门的云服务中。 完全托管的无服务器 WebSocket 解决方案为事件驱动的消息传递提供了基础结构;它使底层基础设施成为一种商品。客户端使用提供程序服务发送/接收低延迟消息&#xff0c;并专注于…...

10.7 LangChain v0.3架构大升级:模块化设计+多阶段混合检索,开发效率飙升3倍!

LangChain v0.3 技术生态与未来发展 关键词:LangChain Chains, Agents 架构, Retrieval Strategy, LangGraph, 模块化设计 3. LangChain 项目:Chains, Agents, Retrieval Strategy LangChain v0.3 通过 Chains-Agents-Retrieval 三位一体的技术栈,构建起完整的大模型应用开…...

GLPK(GNU线性规划工具包)中建模语言MathProg的使用

GNU MathProg是一种用于描述线性数学规划模型的建模语言。用GNU MathProg语言编写的模型描述由一组语句和数据块组成。 在MathProg中&#xff0c;模型以集合、参数、变量、约束和目标(sets, parameters, variables, constraints, objectives称为模型对象)的形式进行描述。 在Ma…...

系统思考:IT企业项目困境分析

最近遇到一家快速发展的IT技术公司&#xff0c;遭遇了项目进度滞后、团队沟通不畅和资源分配不合理等一系列挑战。虽然他们拥有一支技术强大的团队&#xff0c;但在项目管理和团队协作上却显得力不从心。结果&#xff0c;多个项目超预算、交期延迟&#xff0c;客户满意度直线下…...

计算机网络 - 2.基础协议

1.TCP协议 1.TCP(Transmission Control Protocol):传输控制协议2.TCP协议是一种面向连接的、可靠的、 基于字节流的传输层通信协议 1.面向连接:两个使用TCP协议的应用(通常一个客户和一个服务器)在彼此交换数据包之前必须先建立一个TCP连接2.可靠的 1.数据传输之前都要建立…...

go语法大赏

前些日子单机房稳定性下降&#xff0c;找了好一会才找到真正的原因。这里面涉及到不少go语法细节&#xff0c;正好大家一起看一下。 一、仿真代码 这是仿真之后的代码 package mainimport ("fmt""go.uber.org/atomic""time" )type StopSignal…...

运行vscode编辑器源码

距离上次二次开发vscode已经是三年前的事了&#xff0c;当时是1.60.0版本&#xff0c;目前vscode已升级到了1.99.2版本&#xff0c;里面改动很大&#xff0c;最近下载下来了新版源码跑起来看看 准备node、python 源码里面node版本做了限制 2025-01-27 09:53:00.450 [info] Fo…...

ShenNiusModularity项目源码学习(26:ShenNius.Admin.Mvc项目分析-11)

本文学习并分析ShenNiusModularity项目中商城系统模块的小程序用户页面、用户收货地址页面。 1、小程序用户页面 小程序用户页面用于检索、浏览使用商城系统的用户数据&#xff08;保存在shop_appuser表内&#xff0c;系统用户保存在sys_user表内&#xff09;&#xff0c;该页…...

C#中的成员常量:编译时的静态魔法

在C#编程中&#xff0c;常量(const)是一个强大而特殊的语言特性&#xff0c;特别是当它们作为类的成员时。本文将深入探讨成员常量的特性、使用场景以及与静态量的区别。 成员常量的基本特性 成员常量是声明在类内部的常量&#xff0c;具有以下核心特点&#xff1a; 声明位置…...

C# 深入理解类(成员常量)

成员常量 成员常量类似前一章所述的局部常量&#xff0c;只是它们被声明在类声明中而不是方法内&#xff0c;如下面的 示例&#xff1a; 与局部常量类似&#xff0c;用于初始化成员肯量的值在编译时必须是可计算的&#xff0c;而且通常是一个预定 义简单类型或由它们组成的表达…...

服务端HttpServletRequest、HttpServletResponse、HttpSession

一、概述 在JavaWeb 开发中&#xff0c;获取客户端传递的参数至关重要。http请求是客户端向服务端发起数据传输协议&#xff0c;主要包含包含请求行、请求头、空行和请求体四个部分&#xff0c;在这四部分中分别携带客户端传递到服务端的数据。常见的http请求方式有get、post、…...

有哪些GIF图片转换的开源工具

以下是关于GIF图片转换的开源工具的详细总结,涵盖功能特点、适用场景及用户评价: 1. FFmpeg 功能特点: 作为开源命令行工具,FFmpeg支持视频转GIF、调整帧率、分辨率、截取片段等操作,可通过脚本批量处理。适用场景: 适合开发者或技术用户进行高效批处理,常用于服务器端自…...

Vue.js教学第五章:计算属性与侦听器详解

Vue.js 之计算属性与侦听器详解 一、计算属性 (一)概念 计算属性(Computed Properties)是 Vue.js 中的一个核心概念。它允许我们基于一个或多个数据属性来定义一个新的属性,该属性的值会根据其依赖的数据属性的变化而自动更新。这就好像是一个 “智能” 属性,它的值不是…...

第三章:UI 系统架构拆解与动态界面管理实录

还记得我们第二章刚跑通主场景&#xff0c;那时候是不是觉得“终于见到界面了”&#xff1f;但请等等&#xff0c;你看到的只是冰山一角&#xff0c;下面藏着的是 UIManager 的地狱之门。 本章我们将深入探讨&#xff1a; UI 界面如何加载&#xff08;Prefab 动态加载机制&…...

第四章:WebSocket 通信机制全解与客户端发包实录

如果你以为一个游戏启动后只靠本地逻辑运转&#xff0c;那你真是低估了网络通信的存在感。在互动组件项目里&#xff0c;WebSocket 才是真正的灵魂通道——UI 再好看&#xff0c;没包发出去也等于白搭。 本章我们深入讲解 WebSocket 在安卓前端项目中的应用&#xff0c;从封装结…...

pnpm项目内网迁移

pnpm项目内网迁移 文章目录 pnpm项目内网迁移0.前言1.基础环境安装2.构建pnpm离线安装包3.使用pnpm重新安装项目依赖4.项目迁移参考链接&#xff1a; 0.前言 要将一个依赖pnpm的项目迁移到内网离线环境下进行开发。 1.基础环境安装 要保证NodeJS版本一致&#xff0c;否则执行…...

C++23 放宽范围适配器以允许仅移动类型(P2494R2)

文章目录 引言背景与动机提案内容与实现细节提案 P2494R2实现细节编译器支持 对开发者的影响提高灵活性简化代码向后兼容性 示例代码总结 引言 C23 标准中引入了许多重要的改进&#xff0c;其中一项值得关注的特性是放宽范围适配器&#xff08;range adaptors&#xff09;以允…...

[ctfshow web入门] web119

信息收集 import requestsurl "http://51a7e437-2e66-4742-bbfe-e4cce44e360b.challenge.ctf.show/" for i in range(255):data {"code": f"{chr(i)}"}response requests.post(url, datadata)# print(len(response.text))# print(response.t…...

vector--OJ3

链接: [link](链接: link) class Solution { public: vector<string> str{ "","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };void CB(string& …...

第6章 实战案例:基于 STEVAL-IDB011V1 板级 CI/CD 全流程

在前五章中,我们完成了嵌入式 CI/CD 从环境搭建、编译自动化、测试自动化、发布分发到监控回归的全技术链条。本章将以 STEVAL-IDB011V1(搭载 BlueNRG-355)评估板为实战载体,手把手演示如何在 GitLab CI(或 Jenkins)上,构建一条从 Git Push → 编译 → 测试 → 刷写 → …...

逆变器的输出外特性分析

VSG 并网状态下&#xff0c;考虑到弱电网下线路阻抗不能忽略&#xff0c;VSG 的功率传输模型可以表示为 VSG 的输出电压经过线路阻抗后串联至电网&#xff08;考虑滤波电感&#xff0c;且忽略滤波电容作用&#xff09;。设 U 为 VSG 输出电压的幅值&#xff0c;Ug为电网电压的幅…...

如何给PSCAD添加库文件

1、点击Options 2、选择蓝色的选项 3、查看Intel(R) Visual Fortran Compiler XE 的版本 4、打开原文件的Library 5、打开 6、点击这个文件的右键 7、然后选择第一项project setting 9、先把第8步中link里面原有的路径删除&#xff0c;再点browes[A1] &#xff0c;然后选择 [A…...

基于simulink搭建的模块化多电平MMC仿真模型

1. 模块化多电平换流器的运行原理 1.1模块化多电平换流器的拓扑结构 MMC共由6个桥臂构成。其中每个桥臂由若干个串联且结构相同的子模块(Sub-Module, SM)与一个电抗器L串联…...

基于simulink的LCC-HVDC输电模型

1.本模型基于simulink搭建常规直流输电模型&#xff0c;运行稳定。 有需要交流或者模型的可在CSDN上留言...

PWM整流器双闭环PI参数的整定

1. 整流侧电路拓扑图 整流电路由交流侧电源、线路电阻、线路电抗、整流器、滤波电容以及负载组成。整体电路图如图1所示。 图 1 整流电路拓扑图 其中&#xff0c;IGBT的开关状函数如下式所示 根据图 1 列出 KVL 公式如下&#xff0c;电流的正方向是从左到右 对于每一相的IGBT相…...

柔性直流输电系统介绍及simulink模型的搭建

​​​​​​1. 柔性直流输电的运行原理 柔性直流输电系统由电压源型换流器与直流输电线路构成, 图 1‑1所示为单端电压源型换流器原理图。柔性直流输电系统的功率可以双向流动,即换流器既可以作为整流站将从交流系统接收的功率通过直流线路输送出去,也可以作为逆变站将通过直流…...

matlab求矩阵的逆、行列式、秩、转置

inv - 计算矩阵的逆 用途&#xff1a;计算一个可逆矩阵的逆矩阵。 D [1, 2; 3, 4]; % 定义一个2x2矩阵 D_inv inv(D); % 计算矩阵D的逆 disp(D_inv);det - 计算矩阵的行列式 用途&#xff1a;计算方阵的行列式。 E [1, 2; 3, 4]; determinant det(E); % 计算行列式 disp…...

如何在纷杂的环境当中保持保持独立思考能力?

引言 当你在人群当中时&#xff0c;你是否经常容易受到身边人的干扰&#xff0c;而丢失自己原有的想法&#xff0c;其实在环境纷杂当中&#xff0c;我们很容易产生“从众效应”而丢失了自己对这件事独立思考的能力。拥有不受外界影响&#xff0c;独立思考的能力可以让我们更加…...

Linux:计算机的层状结构

1.冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本、台式机。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系结构。 CPU&#xff1a;运算器和控制器组成。运算器主要工作是做算术运算和逻辑运算。控制器主要工作是协调设备之间信息流动的…...

注册表设置windows背景护眼色

方法一&#xff1a; CtrlR&#xff0c;输入regedit打开注册表 HKEY_CURRENT_USER\Control Panel\Colors 右侧窗口Windows键值由255 255 255改为202 234 206。 方法二&#xff1a; 还是注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\DefaultColo…...