OpenCV中的透视变换方法详解
文章目录
- 引言
- 1. 什么是透视变换
- 2. 透视变换的数学原理
- 3. OpenCV中的透视变换代码实现
- 3.1 首先定义四个函数
- 3.1.1 cv_show() 函数
- 3.1.2 def resize() 函数
- 3.1.3 order_points() 函数
- 3.1.4 four_point_transform() 函数
- 3.2 读取图片并做预处理
- 3.3 轮廓检测
- 3.4 获取最大轮廓
- 3.5 透视变换矫正
- 3.6 保存矫正后的图片并显示窗口属性
- 4. 结语
引言
透视变换是计算机视觉中一项重要的图像处理技术,它能够将图像从一个视角投影到另一个视角,广泛应用于文档校正、增强现实、视角转换等场景。本文将深入探讨OpenCV中透视变换的原理与实现方法。
1. 什么是透视变换
透视变换(Perspective Transformation)是一种将图像从一个平面投影到另一个平面的变换方式。与仿射变换不同,透视变换能够处理"近大远小"的透视效果,更真实地模拟人眼观察世界的视角变化。
2. 透视变换的数学原理
透视变换可以用一个3×3的变换矩阵表示:
[a11 a12 a13]
[a21 a22 a23]
[a31 a32 a33]
对于原始图像中的点(x,y),变换后的坐标(x’,y’)计算方式为:
x' = (a11*x + a12*y + a13) / (a31*x + a32*y + a33)
y' = (a21*x + a22*y + a23) / (a31*x + a32*y + a33)
3. OpenCV中的透视变换代码实现
3.1 首先定义四个函数
3.1.1 cv_show() 函数
def cv_show(name,img):cv2.imshow(name, img)cv2.waitKey(0)
这段代码是用来输入图像并将其显示出来
3.1.2 def resize() 函数
def resize(image,width=None,height=None,inter=cv2.INTER_AREA):dim = None(h,w)=image.shape[:2]if width is None and height is None:return imageif width is None:r = height/float(h)dim = (int(w*r),height)else:r = width/float(w)dim = (width,int(h*r))resized = cv2.resize(image,dim,interpolation=inter)return resized
这段代码定义了一个名为 resize 的函数,用于调整图像的大小(缩放),同时保持图像的宽高比例(aspect ratio)。它使用 OpenCV(cv2)来实现图像缩放。
函数参数说明:
- image: 输入的图像(NumPy 数组格式,OpenCV 默认读取的图像)。
- width (可选): 目标宽度(如果提供,则按宽度缩放)。
- height (可选): 目标高度(如果提供,则按高度缩放)。
- inter (可选): 插值方法(默认 cv2.INTER_AREA,适用于缩小图像)。
函数逻辑解析
1.获取原始尺寸:
(h, w) = image.shape[:2] # 获取图像的高度和宽度
2.检查是否传入 width 或 height:
- 如果两者都未提供(width is None and height is None),直接返回原图。
- 如果只提供 height(width is None),则按高度缩放,宽度按比例计算:
r = height / float(h) # 计算缩放比例
dim = (int(w * r), height) # 新尺寸:(宽度按比例缩放, 目标高度)
- 如果提供 width(不管 height 是否提供),则按宽度缩放,高度按比例计算:
r = width / float(w) # 计算缩放比例
dim = (width, int(h * r)) # 新尺寸:(目标宽度, 高度按比例缩放)
3.执行缩放:
resized = cv2.resize(image, dim, interpolation=inter) # 使用 OpenCV 进行缩放
4.返回缩放后的图像:
return resized
总结
- 用途:保持宽高比的情况下缩放图像,避免直接 cv2.resize 可能导致的变形。
适用场景:
- 需要固定宽度或高度,但保持比例不变。
- 适用于图像预处理(如深度学习输入尺寸调整)。
注意:
- 如果同时传入 width 和 height,此函数仍然只会按其中一个参数缩放(优先 width)。
- 如果要强制指定宽高(可能变形),直接用 cv2.resize(image, (width, height))
3.1.3 order_points() 函数
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 rect
这段代码定义了一个名为 order_points 的函数,用于对给定的 4个二维坐标点 进行排序,使其按照 左上、右上、右下、左下 的顺序排列。
逐步解析
输入:
pts:一个形状为 (4, 2) 的 NumPy 数组,表示 4 个点的 (x, y) 坐标。例如:
pts = np.array([[x1, y1], [x2, y2], [x3, y3], [x4, y4]])
输出:
rect:排序后的 (4, 2) 数组,顺序为 左上、右上、右下、左下。
排序逻辑
1.初始化存储数组
rect = np.zeros((4, 2), dtype="float32") # 存储排序后的坐标
2.计算 x + y 并找到左上和右下点
- 左上点(rect[0]):x + y 最小的点(因为左上角的 x 和 y 都较小)。
- 右下点(rect[2]):x + y 最大的点(因为右下角的 x 和 y 都较大)。
s = pts.sum(axis=1) # 计算每个点的 x + y
rect[0] = pts[np.argmin(s)] # 左上点
rect[2] = pts[np.argmax(s)] # 右下点
3.计算 y - x 并找到右上和左下点
- 右上点(rect[1]):y - x 最小的点(因为右上角的 y 较小,x 较大)。
- 左下点(rect[3]):y - x 最大的点(因为左下角的 y 较大,x 较小)。
diff = np.diff(pts, axis=1) # 计算 y - x
rect[1] = pts[np.argmin(diff)] # 右上点
rect[3] = pts[np.argmax(diff)] # 左下点
4.返回排序后的坐标
return rect
注意事项
- 输入必须是 4 个点,否则会报错。
- 适用于凸四边形,如果点排列异常(如交叉),可能排序错误。
- 如果 4 个点本身是 旋转的矩形(如 45° 倾斜),该方法仍然有效。
3.1.4 four_point_transform() 函数
def 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
这段代码定义了一个名为 four_point_transform 的函数,用于对图像进行 透视变换(Perspective Transformation),将图像中的任意四边形区域 矫正为一个 矩形。
代码解析
输入参数
- image:输入的图像(OpenCV 格式,即 NumPy 数组)。
- pts:一个形状为 (4, 2) 的 NumPy 数组,表示待矫正的 4 个角点坐标(顺序任意)。
输出
- warped:矫正后的图像(矩形视角)。
执行步骤
1.对 4 个点进行排序(使用 order_points 确保顺序为 左上、右上、右下、左下):
rect = order_points(pts) # 排序后的 4 个点:[tl, tr, br, bl]
(tl, tr, br, bl) = rect # tl: 左上, tr: 右上, br: 右下, bl: 左下
2.计算矫正后的目标宽度 maxWidth:
计算底边宽度(br 到 bl 的距离):
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
计算顶边宽度(tr 到 tl 的距离):
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
取最大值作为最终宽度:
maxWidth = max(int(widthA), int(widthB))
3.计算矫正后的目标高度 maxHeight:
计算右侧高度(tr 到 br 的距离):
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
计算左侧高度(tl 到 bl 的距离):
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
取最大值作为最终高度:
maxHeight = max(int(heightA), int(heightB))
4.定义目标矩形坐标 dst:
dst = np.array([[0, 0], # 左上[maxWidth - 1, 0], # 右上[maxWidth - 1, maxHeight - 1], # 右下[0, maxHeight - 1] # 左下
], dtype="float32")
5.计算透视变换矩阵 M:
M = cv2.getPerspectiveTransform(rect, dst)
- rect:原始 4 个点(四边形)。
- dst:目标 4 个点(矩形)。
6.执行透视变换:
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
- image:输入图像。
- M:透视变换矩阵。
- (maxWidth, maxHeight):输出图像的尺寸。
7.返回矫正后的图像:
return warped
总结
four_point_transform 的作用是:
- 1.对 4 个点进行排序(order_points)。
- 2.计算目标矩形的尺寸(maxWidth 和 maxHeight)
- 3.计算透视变换矩阵(cv2.getPerspectiveTransform)
- 4.执行透视变换(cv2.warpPerspective),将任意四边形矫正为矩形
这样,我们就可以将 倾斜拍摄的物体 转换为 正面视角,便于后续处理。
3.2 读取图片并做预处理
#读取输入
image = cv2.imread('fapiao.jpg')
cv_show('image',image)#图片过大,进行缩小处理
ratio = image.shape[0] / 500.0 #计算最小比率
orig = image.copy()
image = resize(orig,height=500)
cv_show('1',image)
读取一张发票图片,并进行缩小处理。
图片如下:
3.3 轮廓检测
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)edged = cv2.threshold(gray,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cnts= cv2.findContours(edged.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[-2]
image_contours = cv2.drawContours(image.copy(),cnts,-1,(0,0,255),1)
cv_show('image_contours',image_contours)
这段代码的作用是 对输入图像进行边缘检测并绘制轮廓,以下是逐步解析:
1. 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
- 功能:将彩色图像(BGR格式)转换为灰度图(单通道)。
- 为什么需要:简化后续处理,减少计算量。
2.二值化处理(阈值分割
edged = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
功能:使用 Otsu算法 自动计算最佳阈值,将灰度图转换为黑白二值图。
- cv2.THRESH_BINARY:二值化(大于阈值的设为255,否则为0)。
- cv2.THRESH_OTSU:自动确定最佳阈值(适合双峰直方图的图像)。
输出:edged 是一个二值图像,白色(255)代表目标,黑色(0)代表背景。
3. 查找轮廓
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2]
功能:在二值图像中查找所有轮廓。
- edged.copy():确保不修改原始二值图像。
- cv2.RETR_LIST:检测所有轮廓,不建立层级关系。
- cv2.CHAIN_APPROX_SIMPLE:压缩轮廓点(例如直线只保留端点)。
返回值:cnts 是一个列表,每个元素是一个轮廓(点的集合)。
4. 绘制轮廓
image_contours = cv2.drawContours(image.copy(), cnts, -1, (0, 0, 255), 1)
功能:在原图的副本上绘制所有轮廓。
- image.copy():避免修改原图。
- -1:绘制所有轮廓(若为 0 则只绘制第一个轮廓)。
- (0, 0, 255):轮廓颜色(红色,BGR格式)。
- 1:轮廓线宽(像素)。
5. 显示结果
cv_show('image_contours', image_contours)
功能:显示带轮廓的图像(假设 cv_show 是自定义的显示函数,等同于 cv2.imshow + cv2.waitKey)。
3.4 获取最大轮廓
screenCnt = sorted(cnts,key=cv2.contourArea,reverse=True)[0]peri = cv2.arcLength(screenCnt,True) #计算轮廓周长
screenCnt = cv2.approxPolyDP(screenCnt,0.05 * peri,True) #轮廓近似
print(screenCnt.shape)
image_contours = cv2.drawContours(image.copy(),[screenCnt],-1,(0,255,0),2)cv2.imshow("image_contours",image_contours)
cv2.waitKey(0)
这段代码的作用是从所有检测到的轮廓中筛选出面积最大的轮廓,并进行多边形近似,最终绘制出这个近似后的轮廓。以下是逐步解析:
1. 筛选面积最大的轮廓
screenCnt = sorted(cnts, key=cv2.contourArea, reverse=True)[0]
功能:对轮廓列表 cnts 按面积从大到小排序,并选择面积最大的一个。
- cv2.contourArea:计算轮廓的面积。
- reverse=True:降序排列。
- [0]:取第一个(即最大轮廓)。
用途:假设图像中只有一个主要目标,直接取最大轮廓可排除噪声。
2. 计算轮廓周长
peri = cv2.arcLength(screenCnt, True)
功能:计算轮廓的周长。
- screenCnt:输入的轮廓点集。
- True:表示轮廓是闭合的(首尾相连)。
3.多边形近似(轮廓简化)
screenCnt = cv2.approxPolyDP(screenCnt, 0.05 * peri, True)
功能:用更少的点近似轮廓,减少冗余点(如将弯曲边缘近似为直线)。
- screenCnt:原始轮廓点集。
- 0.05 * peri:近似精度(周长的5%作为阈值,值越小越接近原始形状)。
- True:轮廓闭合。
输出:近似后的轮廓点集(如果是矩形,会返回4个角点)。
示例:
- 输入:复杂轮廓(如几十个点组成的弯曲边缘)。
- 输出:简化后的多边形(如4个点组成的矩形)。
4.检查近似结果
print(screenCnt.shape)
用途:打印近似后轮廓的形状(如 (4, 1, 2) 表示4个点,每个点是 (x, y) 坐标)。
典型输出:
- 矩形:(4, 1, 2)
- 三角形:(3, 1, 2)
- 若点数过多(如 (10, 1, 2)),可能需要调整 0.05 参数。
5.绘制近似后的轮廓
image_contours = cv2.drawContours(image.copy(), [screenCnt], -1, (0, 255, 0), 2)
功能:在原图的副本上绘制绿色(BGR格式 (0,255,0))的近似轮廓。
- [screenCnt]:将轮廓包装为列表(因 drawContours 接受列表输入)。
- -1:绘制所有轮廓(此处只有一个)。
- 2:线宽(像素)。
6.显示结果
cv2.imshow("image_contours", image_contours)
cv2.waitKey(0)
效果:显示带绿色轮廓的图像,标识出检测到的主要目标。
完整流程总结
- 输入:所有检测到的轮廓 cnts(来自 cv2.findContours)。
- 筛选:选择面积最大的轮廓。
- 简化:用多边形近似轮廓(如提取矩形角点)。
- 绘制:在原图上标出简化后的轮廓。
- 输出:可视化结果。
3.5 透视变换矫正
warped = four_point_transform(orig,screenCnt.reshape(4,2) * ratio)
功能:将原始图像 orig 中的四边形区域(screenCnt)矫正为正面视角的矩形。
- screenCnt.reshape(4, 2):将轮廓点从 (4, 1, 2) 转换为 (4, 2) 格式(4个点的x,y坐标)。
- ratio:如果预处理时图像被缩小过(如为了加速轮廓检测),需通过比例 ratio 将坐标映射回原始图像尺寸。
- four_point_transform:自定义函数(基于 cv2.getPerspectiveTransform 和
cv2.warpPerspective)。
3.6 保存矫正后的图片并显示窗口属性
cv2.imwrite('invoice_new.jpg', warped)
cv2.namedWindow('xx',cv2.WINDOW_NORMAL)
cv2.resizeWindow('xx',800,600)cv_show('xx',warped)
cv2.waitKey(0)
cv2.destroyAllWindows()
代码解析:
cv2.imwrite('invoice_new.jpg', warped)
功能:将矫正后的图像 warped 保存为 invoice_new.jpg。
用途:持久化处理结果,便于后续使用(如OCR识别、打印等)。
cv2.namedWindow('xx', cv2.WINDOW_NORMAL)
cv2.resizeWindow('xx', 800, 600)
功能:创建一个可调整大小的窗口,并设置初始尺寸为 800x600 像素。
- cv2.WINDOW_NORMAL:允许手动调整窗口大小(默认是固定大小的 cv2.WINDOW_AUTOSIZE)。
适用场景:当图像较大时,可通过缩放窗口查看完整内容。
cv2.imshow('xx', warped)
cv2.waitKey(0)
功能:在窗口 ‘xx’ 中显示矫正后的图像 warped,并等待用户按键关闭窗口。
注意:cv_show 可能是封装好的函数,若未定义需替换为 cv2.imshow + cv2.waitKey。
4. 结语
本篇博客到这里就结束啦,希望能帮助大家更好的理解和和使用OpenCV中的透视变换方法。其实方法并不难,只要我们能沉下心来慢慢学习,一定会有收获的。我一直坚信,努力会让我们收获一个更好的自己,加油!!!
相关文章:
OpenCV中的透视变换方法详解
文章目录 引言1. 什么是透视变换2. 透视变换的数学原理3. OpenCV中的透视变换代码实现3.1 首先定义四个函数 3.1.1 cv_show() 函数 3.1.2 def resize() 函数 3.1.3 order_points() 函数 3.1.4 four_point_transform() 函数 3.2 读取图片并做预处理3.3 轮廓检测3.4 获取最大…...
基于DeepSeek的网络爬虫技术创新与实践应用
摘要 在人工智能迅猛发展的时代背景下,网络爬虫技术正经历着深刻变革。本文聚焦于融合DeepSeek大模型的开源爬虫框架Crawl4AI,深入探讨其在网络数据抓取与分析领域的技术原理、功能特性、应用实践及未来发展趋势。通过对Crawl4AI的异步操作、动态内容处理…...
Python基于语音识别的智能垃圾分类系统【附源码、文档说明】
博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…...
关于RPC
1.什么是RPC RPC(Remote Procedure Call),即远程过程调用(协议)。它允许像调用本地服务一样调用远程服务,用于实现分布式系统中跨网络进行通信 的技术,是一种计算机通信协议。 RPC是一种服务器…...
前端频繁调用后端接口问题思考
针对前端频繁调用后端接口的问题,以下是一套分步解决方案,结合Java后端技术栈: 1. 实时数据场景:WebSocket/SSE 适用场景:实时股票行情、即时聊天、监控仪表盘 // Spring WebSocket 配置示例 Configuration EnableW…...
Mujoco robosuite 机器人模型
import ctypes import os# 获取当前脚本所在的目录 script_dir os.path.dirname(os.path.abspath(__file__))# 构建库文件的相对路径 lib_relative_path os.path.join(dynamic_models, UR5e, Jb.so)# 拼接成完整的路径 lib_path os.path.join(script_dir, lib_relative_path…...
进阶篇 第 7 篇 (终章):融会贯通 - 多变量、模型选择与未来之路
进阶篇 第 7 篇 (终章):融会贯通 - 多变量、模型选择与未来之路 (图片来源: Pixabay on Pexels) 我们已经一起走过了时间序列分析的进阶之旅!从深入经典统计模型 ETS、ARIMA、SARIMA,到探索现代利器 Prophet,再到拥抱机器学习和初…...
网络安全·第五天·TCP协议安全分析
一、传输层协议概述 1、功能 传输层负责建立端到端的连接,即应用进程之间的通信,负责数据在端到端之间的传输。与网络层不同的是,网络层负责主机与主机之间的通信。 同时,传输层还要对收到的报文进行差错检测(首部和…...
LX10-MDK的使用技巧
MDK5的使用技巧 查找匹配花括号 Ctrle table键的妙用 一次右缩进4个(个人偏好设置)空格shiftenter取消,即左缩进 快速注释/取消注释 先选代码→ 快速编辑一列 按住ALT键选择一列编辑(实用性极强) 窗口拆分 倒数第一个:按列拆分倒数第二个:按行拆分 查找与替换(一个超级…...
IDEA创建Gradle项目然后删除报错解决方法
根据错误信息,你的项目目录中缺少Gradle构建必需的核心文件(如settings.gradle/build.gradle),且IDEA可能残留了Gradle的配置。以下是具体解决方案: 一、问题根源分析 残留Gradle配置 你通过IDEA先创建了Gradle子模块…...
JavaScript性能优化实战(2):DOM操作优化策略
浏览器渲染原理与重排重绘机制 浏览器将HTML和CSS转换为用户可见页面的过程是前端开发的基础知识,也是理解DOM性能优化的关键。这个渲染过程大致可分为以下几个步骤: 渲染过程的核心步骤 解析HTML构建DOM树:浏览器解析HTML标记,转换为DOM树(Document Object Model),表…...
乐视系列玩机---乐视1s x500 x501 x502等系列线刷救砖以及刷写第三方twrp 卡刷第三方固件步骤解析
乐视乐1S(X500 x501 x502 等)采用联发科 Helio X10(MT6795T)Turbo 64位8核处理器 通过博文了解💝💝💝 1💝💝💝-----详细解析乐视1s x500 x501x502等系列黑砖线刷救砖的步骤 2💝💝💝----官方两种更新卡刷步骤以及刷写第三方twrp过程与资源 3💝💝…...
Spark-Streaming(1)
Spark Streaming概述: 用于流式计算,处理实时数据流。 数据流以DStream(Discretized Stream)形式表示,内部由一系列RDD组成。 Spark Streaming特点: 易用、容错、易整合到spark体系。 易用性:…...
【Git】Git Revert 命令详解
Git Revert 命令详解 1. Git Revert 的基本概念 Git Revert 是一个用于撤销特定提交的命令。与 Git Reset 不同,Git Revert 不会更改提交历史,而是会创建一个新的提交来撤销指定提交的更改。这意味着,使用 Git Revert 后,项目的…...
SpringClound 微服务分布式Nacos学习笔记
一、基本概述 在实际项目中,选择哪种架构需要根据具体的需求、团队能力和技术栈等因素综合考虑。 单体架构(Monolithic Architecture) 单体架构是一种传统的软件架构风格,将整个应用程序构建为一个单一的、不可分割的单元。在这…...
PageIndex:构建无需切块向量化的 Agentic RAG
引言 你是否对长篇专业文档的向量数据库检索准确性感到失望?传统的基于向量的RAG系统依赖于语义相似性而非真正的相关性。但在检索中,我们真正需要的是相关性——这需要推理能力。当处理需要领域专业知识和多步推理的专业文档时,相似度搜索常…...
使用Java调用TensorFlow与PyTorch模型:DJL框架的应用探索
在现代机器学习的应用场景中,Python早已成为广泛使用的语言,尤其是在深度学习框架TensorFlow和PyTorch的开发和应用中。尽管Java在许多企业级应用中占据一席之地,但因为缺乏直接使用深度学习框架的能力,往往使得Java开发者对机器学…...
nodejs的包管理工具介绍,npm的介绍和安装,npm的初始化包 ,搜索包,下载安装包
nodejs的包管理工具介绍,npm的介绍和安装,npm的初始化包 ,搜索包,下载安装包 🧰 一、Node.js 的包管理工具有哪些? 工具简介是否默认特点npmNode.js 官方的包管理工具(Node Package Manager&am…...
LeetCode 热题 100_分割等和子集(89_416_中等_C++)(动态规划)
LeetCode 热题 100_分割等和子集(89_416) 题目描述:输入输出样例:题解:解题思路:思路一(动态规划): 代码实现代码实现(思路一(动态规划࿰…...
EasyCVR视频智能分析平台助力智慧园区:全场景视频监控摄像头融合解决方案
一、方案背景 在智慧园区建设的浪潮下,设备融合、数据整合与智能联动已成为核心诉求。视频监控作为智慧园区的“视觉中枢”,其高效整合直接影响园区的管理效能与安全水平。然而,园区内繁杂的视频监控设备生态——不同品牌、型号、制式的摄像…...
《剥开卷积神经网络CNN的 “千层酥”:从基础架构到核心算法》
文章目录 前言卷积神经网络(Convolutional Neural Network,CNN)是一种专门用于处理网格结构数据(如图像、视频、音频)的深度学习模型。它在计算机视觉任务(如图像分类、目标检测)中表现尤为出色…...
win10中打开python的交互模式
不是输入python3,输入python,不知道和安装python版本有没有关系。做个简单记录,不想记笔记了...
技术与情感交织的一生 (七)
目录 出师 大三 MVP 首战 TYMIS はじめまして 辣子鸡丁 报价 日本人 致命失误 大佬 包围 品质保障 扩军 唯快不破 闪电战 毕业 总攻 Hold On 出师 大三 大三的学习生活,能认认真真的上一天课的时候很少,甚至经常因为客户的 “传呼”…...
ElasticSearch深入解析(一):Elastic Stack全景
一、Elastic Stack的发展 过去和现在: Elastic数据平台在搜索、地理位置、内部日志、数据指标、安全监控和APM应用性能管理等场景中的应用颇具亮点。 APM(Application Performance Management,应用性能管理)是一种用于监控和管理…...
CAD在线查看免费,可以支持DWG/GLB/GLTF/doc/wps/pdf/psd/eml/zip, rar/MP3/MP4/svg/OBJ/FBX格式
CAD在线查看免费,可以支持DWG/GLB/GLTF/doc/wps/pdf/psd/eml/zip, rar/MP3/MP4/svg/OBJ/FBX格式 m.gszh.xyz m.gszh.xyz 免费支持以下格式文件在线查看类型 支持 doc, docx, xls, xlsx, xlsm, ppt, pptx, csv, tsv, dotm, xlt, xltm, dot, dotx, xlam, xla, pages …...
【机器学习案列-21】基于 LightGBM 的智能手机用户行为分类
🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...
多路转接poll服务器
目录 函数原型 poll服务器 对比select的优点 关于select的详解,可查看多路转接select服务器-CSDN博客 函数原型 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout); poll作为多路转接的实现方案,与select要解决的问…...
全本地化智能数字人
🌟EdgePersona- 全本地化智能数字人 完全离线 | 隐私无忧 | 轻量高效 |笔记本友好 测试效果:【纯本地部署的电子魅魔!笔记本也能离线,隐私性拉满】 https://www.bilibili.com/video/BV1jydeYTETD/?share_sourcecopy_web&v…...
第6次课 贪心算法 A
向日葵朝着太阳转动,时刻追求自身成长的最大可能。 贪心策略在一轮轮的简单选择中,逐步导向最佳答案。 课堂学习 引入 贪心算法(英语:greedy algorithm),是用计算机来模拟一个「贪心」的人做出决策的过程…...
Docker 部署 PostgreSQL 数据库
Docker 部署 PostgreSQL 数据库 基于 Docker 部署 PostgreSQL 数据库一、拉取 PostgreSQL 镜像二、运行 PostgreSQL 容器三、运行命令参数详解四、查看容器运行状态 基于 Docker 部署 PostgreSQL 数据库 一、拉取 PostgreSQL 镜像 首先,确保你的 Docker 环境已正确…...
Android如何通过aspectj打造一个无侵入式动态权限申请框架
目录 一,背景 二,通过Aspectj管理所有的注解 三,配置注解 四,通过空白Activity完成真正的权限申请 五,引入依赖配置 一,背景 在Activity或者fragment中,写在几个方法写一些注释,用来表示权限申请成功,申请失败,多次拒绝。…...
Flink介绍——实时计算核心论文之Dataflow论文详解
引入 在过去的几篇文章里,我们看到了大数据的流式处理系统是如何一步一步进化的。从最早出现的S4,到能够做到“至少一次”处理的Storm,最后是能够做到“正好一次”数据处理的MillWheel。我们会发现,这些流式处理框架,…...
浅克隆(--depth 1)后如何获取完整的历史记录
如果远程remote为origin,则origin可以不写,如不是,则必须要写 获取全部分支 git fetch origin refs/heads/*:refs/remotes/origin/* 单独获取master分支 git fetch origin refs/heads/master:refs/remotes/origin/master 获取全部历史…...
安宝特案例 | 某知名日系汽车制造厂,借助AR实现智慧化转型
案例介绍 在全球制造业加速数字化的背景下,工厂的生产管理与设备维护效率愈发重要。 某知名日系汽车制造厂当前面临着设备的实时监控、故障维护,以及跨地域的管理协作等挑战,由于场地分散和突发状况的不可预知性,传统方式已无法…...
Feign 深度解析:Java 声明式 HTTP 客户端的终极指南
Feign 深度解析:Java 声明式 HTTP 客户端的终极指南 Feign 是由 Netflix 开源的 声明式 HTTP 客户端,后成为 Spring Cloud 生态的核心组件(现由 OpenFeign 维护)。它通过注解和接口定义简化了服务间 RESTful 通信,并…...
WPS Office安卓版云文档同步速度与PDF转换体验测评
WPS Office安卓版是很多人常用的移动办公软件。它支持在线编辑、文档同步、格式转换等功能,适合手机和平板用户随时处理文档。我们用它配合谷歌浏览器打开网页文档时,也可以将内容快速保存到云端或转换成PDF格式使用。 先说云文档同步。在打开WPS Office…...
ARM汇编的LDM和STM指令
批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据.LDM 为加载多个寄存器,STM 为存储多个寄存器.允许一条指令传送 16 个寄存器的任何子集或所有寄存器.指令格式如下: LDM{cond}<模式> Rn{!},reglist{^} STM{cond}<模式> Rn{!}…...
Python-27:游戏英雄升级潜力评估
问题描述 小U在一款挂机游戏中拥有n个英雄。游戏中有一种历练升级机制,每天可以选择两个英雄进行历练,如果两位英雄的等级相同,则他们的等级都不会改变。如果英雄等级不同,那么等级较高的英雄会增加1级,而等级较低的英…...
【基于SprintBoot+Mybatis+Mysql】电脑商城项目之显示勾选的购物车数据和创建订单
🧸安清h:个人主页 🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 目录 🚀1.显示勾选的购物…...
AWS Lambda 架构深入探究
AWS Lambda 是现代云架构中最受欢迎的服务之一,因其能够在完全托管的无服务器环境中运行代码而广受认可。然而,尽管 Lambda 广受欢迎,许多开发者和架构师对它的底层运作机制却知之甚少,常常将其视为“编写能够在云端神奇运行的代码…...
信奥赛CSP-J复赛集训(DP专题)(19):P3399 丝绸之路
信奥赛CSP-J复赛集训(DP专题)(19):P3399 丝绸之路 题目背景 张骞于公元前 138 年曾历尽艰险出使过西域。加强了汉朝与西域各国的友好往来。从那以后,一队队骆驼商队在这漫长的商贸大道上行进,他…...
网络NAT类型测试
免费收录PCDN、GPU算力网站_算力收录站需要专业的PCDN、GPU算力网站收录服务吗?算力收录站为您提供高效、可信赖的收录服务,提升您的网站能见度。https://www.cdngpu.com/ 什么是 NAT:NAT代表网络地址转换,允许多个内网设备共享一…...
Postman下载安装与使用汉化版教程
简介: Postman 是一款常用的 API 测试工具,可以方便地进行接口测试、调试和文档编写。本文将详细介绍如何下载安装 Postman 并汉化,包括每个步骤的详细说明。 Postman 是一款常用的 API 测试工具,可以方便地进行接口测试、调试和…...
使用Python+OpenCV对视频抽帧保存为JPG图像
使用PythonOpenCV对视频抽帧保存为JPG图像 import os import cv2 import time#视频文件夹路径,可修改 videoPath D:\\video\\ #保存的图片文件夹路径,可修改 savePath D:\\images\\ videolist os.listdir(videoPath) if not os.path.exists(savePath…...
Java的反射机制(曼波超易懂图文版)
(✪▽✪)曼波~~~~!好的呀~让曼波用最可爱的姿势为你讲解Java反射机制吧! 🌟反射机制核心概念 曼波觉得反射就像编程世界的"魔法镜"(◕ᴗ◕✿) 可以让我们在运行时动态获取类的信息并操作类对象! // 举个栗子&#…...
【DeepSeek 学习推理】Llumnix: Dynamic Scheduling for Large Language Model Serving实验部分
6.1 实验设置 测试平台。我们使用阿里云上的16-GPU集群(包含4个GPU虚拟机,类型为ecs.gn7i-c32g1.32xlarge)。每台虚拟机配备4个NVIDIA A10(24 GB)GPU(通过PCI-e 4.0连接)、128个vCPU、752 GB内…...
运行neo4j.bat console 报错无法识别为脚本,PowerShell 教程:查看语言模式并通过注册表修改受限模式
无法将“D:\neo4j-community-4.4.38-windows\bin\Neo4j-Management\Get-Args.ps1”项识别为cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 前提配置好环境变量之后依然报上面的错…...
AI写代码之GO+Python写个爬虫系统
下面我们我们来利用AI,来用GOPython写个爬虫系统。 帮我写一个Python语言爬取数据写入Mysql的案例,信息如下: 1、Mysql数据库地址是:192.168.1.20 ,mysql用户名是:root, Mysql密码是࿱…...
【FAQ】如何配置PCoIP零客户端AWI能访问
应用场景 在安全性要求较高的环境中,禁用 AWI 并使用 PCoIP 管理控制台配置端点,建议隐藏 OSD 以提高安全性。 通过OSD和AWI: 阻止 PCoIP 管理工具管理 PCoIP 零客户端。禁用对 Tera2 PCoIP Zero Client 的 AWI 的管理访问。下次访问 AWI 或 OSD 时强…...
RAGFlow:构建高效检索增强生成流程的技术解析
引言 在当今信息爆炸的时代,如何从海量数据中快速准确地获取所需信息并生成高质量内容已成为人工智能领域的重要挑战。检索增强生成(Retrieval-Augmented Generation, RAG)技术应运而生,它将信息检索与大型语言模型(L…...