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

Opencv第十一章——视频处理

1. 读取并显示摄像头视频

1.1 VideoCapture类

VideoCapture类提供了构造方法VideoCapture(),用于完成摄像头的初始化工作,其语法格式如下:

capture = cv2.VideoCapture(index)

参数说明:

capture:要打开的摄像头视频。

index:摄像头设备索引。

对于Win11而言,index=0时表示要打开笔记本内置摄像头。

capture = cv2.VideoCapture(0)

 对于Win11而言,index=1时表示要打开连接笔记本的外置摄像头。

capture = cv2.VideoCapture(1)

 为了检验摄像头初始化是否成功,VIdeoCapture类提供了isOpened()方法,其语法格式如下

retaval = cv2.VideoCapture.isOpened()

参数说明:

retval:若初始化成功,则值为True,否则值为False.。

retaval = cv2.VideoCapture.isOpened()
# retval = capture.isOpened()

 摄像头初始化后,就可以从摄像头中读取帧了,VideoCapture类提供了read()方法,其语法格式如下:

retval,image = cv2.VideoCapture.read() #可以简写为retval, image = capture.read()

参数说明:

retval:读取到帧,则返回True,反之,则返回False。

image:读取到的帧,即图像。

retval,image = cv2.VideoCapture.read() 
#retval, image = capture.read()

VideoCapture类提供了release()方法 关闭摄像头。

cv2.VideoCapture.release()
#capture.release()

1.2 如何使用VideoCapture类

1.2.1 读取并显示摄像头视频

 操作示例代码:

import cv2capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)  # 打开笔记本内置摄像头
while capture.isOpened():  # 笔记本内置摄像头被打开后retval, image = capture.read()  # 从摄像头中实时读取视频cv2.imshow("Video", image)  # 在窗口中显示读取到的视频key = cv2.waitKey(1)  # 窗口的图像刷新时间为1毫秒if key == 32:  # 如果按下空格键break
capture.release()  # 关闭笔记本内置摄像头
cv2.destroyAllWindows()  # 销毁显示摄像头视频的窗口

操作效果图像:

1.2.2 将摄像头视频由彩色转化为灰度视频

操作代码示例:

import cv2capture = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开笔记本内置摄像头
while (capture.isOpened()): # 笔记本内置摄像头被打开后retval, image = capture.read() # 从摄像头中实时读取视频# 把彩色视频转换为灰度视频image_Gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)if retval == True: # 读取到摄像头视频后cv2.imshow("Video", image) # 在窗口中显示彩色视频cv2.imshow("Video_Gray", image_Gray) # 在窗口中显示灰度视频key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒if key == 32: # 如果按下空格键break
capture.release() # 关闭笔记本内置摄像头
cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口

操作效果图像:

1.2.3 显示并保存摄像头视频某一时刻图像

操作代码示例:

import cv2cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开笔记本内置摄像头
while (cap.isOpened()): # 笔记本内置摄像头被打开后ret, frame = cap.read() # 从摄像头中实时读取视频cv2.imshow("Video", frame) # 在窗口中显示视频k = cv2.waitKey(1) # 图像的刷新时间为1毫秒if k == 32: # 按下空格键cap.release() # 关闭笔记本内置摄像头cv2.destroyWindow("Video") # 销毁名为Video的窗口cv2.imwrite("A:/copy.png", frame) # 保存按下空格键时摄像头视频中的图像cv2.imshow('img', frame) # 显示按下空格键时摄像头视频中的图像cv2.waitKey() # 刷新图像break
cv2.destroyAllWindows() # 销毁显示图像的窗口

保存的图像:

1.2.4 读取并显示两个摄像头视频

操作示例代码:

import cv2cap_Inner = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开笔记本内置摄像头
cap_Outer = cv2.VideoCapture(1, cv2.CAP_DSHOW) # 打开一个连接笔记本的外置摄像头
while (cap_Inner.isOpened() & cap_Outer.isOpened()): # 两个摄像头都被打开后retval, img_Inner = cap_Inner.read() # 从笔记本内置摄像头中实时读取视频ret, img_Outer = cap_Outer.read() # 从连接笔记本的外置摄像头中实时读取视频# 在窗口中显示笔记本内置摄像头读取到的视频cv2.imshow("Video_Inner", img_Inner)# 在窗口中显示连接笔记本的外置摄像头读取到的视频cv2.imshow("Video_Outer", img_Outer)key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒if key == 32: # 如果按下空格键break
cap_Inner.release() # 关闭笔记本内置摄像头
cap_Outer.release() # 关闭连接笔记本的外置摄像头
cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口

操作效果图像:

2. 播放视频文件

2.1 读取并显示视频文件

VideoCapture类的构造方法VideoCapture()不仅能够用于完成摄像头的初始化工作,还能够用于完成视频文件的初始化工作,此时,其语法格式如下:

video = cv2.VideoCapture(filename)

参数说明:

video:要打开的视频

filename:打开的视频文件名

2.1.1 读取并显示视频文件

操作示例代码:

import cv2video = cv2.VideoCapture(r"C:\Users\cgs\Desktop\pictures\csdn1.mp4") # 打开视频文件
while (video.isOpened()): # 视频文件被打开后retval, image = video.read() # 读取视频文件# 设置“Video”窗口的宽为420,高为700cv2.namedWindow("Video", 0)cv2.resizeWindow("Video", 420, 700)if retval == True: # 读取到视频文件后cv2.imshow("Video", image) # 在窗口中显示读取到的视频文件else: # 没有读取到视频文件breakkey = cv2.waitKey(10) # 窗口的图像刷新时间为1毫秒if key == 27: # 如果按下Esc键break
video.release() # 关闭视频文件
cv2.destroyAllWindows() # 销毁显示视频文件的窗口

操作效果:

2.1.2 将视频文件由彩色视频转换为灰度视频

操作代码示例:

import cv2video = cv2.VideoCapture(r"C:\Users\cgs\Desktop\pictures\csdn1.mp4") # 打开视频文件
while (video.isOpened()): # 视频文件被打开后retval, img_Color = video.read() # 读取视频文件# 设置“Video”窗口的宽为420,高为700cv2.namedWindow("Gray", 0)cv2.resizeWindow("Gray", 420, 700)if retval == True: # 读取到视频文件后# 由彩色视频转换为灰度视频img_Gray = cv2.cvtColor(img_Color, cv2.COLOR_BGR2GRAY)cv2.imshow("Gray", img_Gray) # 在窗口中显示读取到的视频文件else: # 没有读取到视频文件breakkey = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒if key == 27: # 如果按下Esc键break
video.release() # 关闭视频文件
cv2.destroyAllWindows() # 销毁显示视频文件的窗口

操作效果:

2.2 视频的暂停播放和继续播放

操作代码示例:空格键实现暂停和继续播放,Esc关闭视频文件。

import cv2video = cv2.VideoCapture(r"C:\Users\cgs\Desktop\pictures\csdn2.mp4") # 打开视频文件
while (video.isOpened()): # 视频文件被打开后retval, image = video.read() # 读取视频文件# 设置“Video”窗口的宽为420,高为300cv2.namedWindow("Video", 0)cv2.resizeWindow("Video", 420, 300)if retval == True: # 读取到视频文件后cv2.imshow("Video", image) # 在窗口中显示读取到的视频文件else: # 没有读取到视频文件breakkey = cv2.waitKey(50) # 窗口的图像刷新时间为50毫秒if key == 32: # 如果按下空格键cv2.waitKey(0) # 不刷新图像,实现暂停效果continue # 再按一次空格键,继续播放if key == 27: # 如果按下Esc键break
video.release() # 关闭视频文件
cv2.destroyAllWindows() # 销毁显示视频文件的窗口

2.3 获取视频文件的属性

VideoCapture类提供了get()方法来获取视频文件的属性,其语法格式如下:

retval = cv2.VideoCapture.get(propId)

参数说明:

retval:获取到与propId对应的属性值。

propId:视频文件的属性值。

VideoCapture类提供视频文件的属性值及其含义如下表: 

2.3.1 获取并输出视频文件的指定属性值

操作示例代码:

import cv2video = cv2.VideoCapture(r"C:\Users\cgs\Desktop\pictures\csdn2.mp4") # 打开视频文件
fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
frame_Count = video.get(cv2.CAP_PROP_FRAME_COUNT) # 获取视频文件的帧数
frame_Width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) # 获取视频文件的帧宽度
frame_Height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 获取视频文件的帧高度
# 输出获取到的属性值
print("帧速率:", fps)
print("帧数:", frame_Count)
print("帧宽度:", frame_Width)
print("帧高度:", frame_Height)

操作结果:

找一个视频来试试吧!!!

2.3.2 动态显示视频文件的属性值

操作代码示例:

import cv2video = cv2.VideoCapture(r"C:\Users\cgs\Desktop\pictures\csdn2.mp4") # 打开视频文件
fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
frame_Num = 1 # 用于记录第几幅图像(即第几帧),初始值为1(即第1幅图像)
while (video.isOpened()): # 视频文件被打开后retval, frame = video.read() # 读取视频文件# 设置“Video”窗口的宽为420,高为300cv2.namedWindow("Video", 0)cv2.resizeWindow("Video", 420, 700)if retval == True: # 读取到视频文件后# 当前视频播放到第几帧cv2.putText(frame, "frame: " + str(frame_Num), (0, 50),cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 255), 2)# 该帧对应着视频的第几秒cv2.putText(frame, "second: " + str(round(frame_Num / fps, 2)) + "s",(0, 100), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 255), 2)cv2.putText(frame, "width: 610", (0, 150),cv2.CAP_PROP_FRAME_WIDTH, 2, (255, 255, 0), 2)cv2.putText(frame, "height: 1030", (0, 200),cv2.CAP_PROP_FRAME_HEIGHT, 2, (255, 0, 0), 2)cv2.imshow("Video", frame) # 在窗口中显示读取到的视频文件else: # 没有读取到视频文件breakkey = cv2.waitKey(20) # 窗口的图像刷新时间为50毫秒frame_Num += 1 #if key == 27: # 如果按下Esc键break
video.release() # 关闭视频文件
cv2.destroyAllWindows() # 销毁显示视频文件的窗口

操作效果展示:

3. 保存视频文件

3.1 VideoWriter类

VideoWriter类中的常用方法包括VideoWeiter类的构造方法、write()方法()和release()方法。其中,VideoWriter类的构造方法用于创建VideoCapture类对象,其语法格式如下:

<VideoWriter boject> = cv2.VideoWriter(filename,fourcc,fps,framSize)

参数说明:

VideoWriter object:VideoWriter类对象。

filename:保存视频时的路径。

fourcc:用四个字符表示的视频编码格式。

fps:帧速率。

frameSize:每一帧的大小。

                                                   常用的视频编码格式

 下面是Windows操作系统下创建一个VideoWriter类对象的示例

fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D') # 确定视频被保存后的编码格式
output = cv2.VideoWriter("output.avi", fourcc, 20, (640, 480)) # 创建VideoWriter类对象

为了保存一段视频,处理需要使用VideoCapture类的构造方法外,还需要使用到VideoCapture类提供的writer()方法。其作用是在创建好的VideoCapture类对象中下入读取到的帧 。语法格式如下:

cv2.VideoWriter.write(frame)

参数说明:

frame:读取到的帧。

当不需要使用VideoWriter类对象时,需要将其释放掉,为此VideoWriter类提供了release()方法,其语法格式如下:

cv2.VideoWriter.release()

3.2 如何使用VideoWriter类

3.2.1 保存一段视像头视频

操作代码示例:

import cv2capture = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开笔记本内置摄像头
fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D') # 确定视频被保存后的编码格式
output = cv2.VideoWriter("dmsj.avi", fourcc, 20, (640, 480)) # 创建VideoWriter类对象
while (capture.isOpened()): # 笔记本内置摄像头被打开后retval, frame = capture.read() # 从摄像头中实时读取视频if retval == True: # 读取到摄像头视频后output.write(frame) # 在VideoWriter类对象中写入读取到的帧cv2.imshow("frame", frame) # 在窗口中显示摄像头视频key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒if key == 27: # 如果按下Esc键break
capture.release() # 关闭笔记本内置摄像头
output.release() # 释放VideoWriter类对象
cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口

操作结果显示:

3.2.2 保存一段指定时长的摄像头视频

操作代码示例:

import cv2capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)  # 打开笔记本内置摄像头
fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', 'V')  # 确定视频被保存后的编码格式
fps = 20  # 帧速率
# 创建VideoWriter类对象
output = cv2.VideoWriter("dmsj.mp4", fourcc, fps, (640, 480))
frame_Num = 13 * fps  # 时长为13秒的摄像头视频含有的帧数
# 笔记本内置摄像头被打开且时长为13秒的摄像头视频含有的帧数大于0
while capture.isOpened() and frame_Num > 0:retval, frame = capture.read()  # 从摄像头中实时读取视频if retval == True:  # 读取到摄像头视频后output.write(frame)  # 在VideoWriter类对象中写入读取到的帧cv2.imshow("frame", frame)  # 在窗口中显示摄像头视频key = cv2.waitKey(1)  # 窗口的图像刷新时间为1毫秒frame_Num -= 1  # 时长为10秒的摄像头视频含有的帧数减少一帧
capture.release()  # 关闭笔记本内置摄像头
output.release()  # 释放VideoWriter类对象
cv2.destroyAllWindows()  # 销毁显示摄像头视频的窗口

操作效果展示:

3.2.3 保存视频文件

操作代码示例:

import cv2video = cv2.VideoCapture(r"C:\Users\cgs\Desktop\pictures\csdn2.mp4") # 打开视频文件
fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
# 获取视频文件的帧大小
size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)),int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', 'V') # 确定视频被保存后的编码格式
output = cv2.VideoWriter("cgs.mp4", fourcc, fps, size) # 创建VideoWriter类对象
while (video.isOpened()): # 视频文件被打开后retval, frame = video.read() # 读取视频文件if retval == True: # 读取到视频文件后output.write(frame) # 在VideoWriter类对象中写入读取到的帧else:break
print("视频已保存") # 控制台输出提示信息
video.release() # 关闭视频文件
output.release() # 释放VideoWriter类对象

3.2.4 保存视频文件中的前10秒视频

操作代码示例:

import cv2video = cv2.VideoCapture(r"C:\Users\cgs\Desktop\pictures\csdn2.mp4") # 打开视频文件
fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
# 获取视频文件的帧大小
size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)),int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D') # 确定视频被保存后的编码格式
output = cv2.VideoWriter("ten_Seconds.avi", fourcc, fps, size) # 创建VideoWriter类对象
frame_Num = 10 * fps # 视频文件的前10秒视频含有的帧数
# 视频文件被打开后且视频文件的前10秒视频含有的帧数大于0
while (video.isOpened() and frame_Num > 0):retval, frame = video.read() # 读取视频文件if retval == True: # 读取到视频文件后output.write(frame) # 在VideoWriter类对象中写入读取到的帧frame_Num -= 1 # 视频文件的前10秒视频含有的帧数减少一帧
# 控制台输出提示信息
print("已保存10秒视频!")
video.release() # 关闭视频文件
output.release() # 释放VideoWriter类对象

操作效果展示:

本章节的内容就到这里了,欢迎大家继续关注!!!

相关文章:

Opencv第十一章——视频处理

1. 读取并显示摄像头视频 1.1 VideoCapture类 VideoCapture类提供了构造方法VideoCapture(),用于完成摄像头的初始化工作&#xff0c;其语法格式如下&#xff1a; capture cv2.VideoCapture(index) 参数说明&#xff1a; capture:要打开的摄像头视频。 index:摄像头设备索引。…...

Flutter 3.24 AAPT: error: resource android:attr/lStar not found.

在Android build,gradle下面&#xff0c;添加右边红框的代码&#xff1a; subprojects {afterEvaluate { project ->if (project.plugins.hasPlugin("com.android.application") ||project.plugins.hasPlugin("com.android.library")) {project.androi…...

C++——输入一个2*3的矩阵, 将这个矩阵向左旋转90度后输出。(要求:使用指针完成。)

没注释的源代码 #include <iostream> using namespace std; int main() { int a[2][3]; cout<<"请输入一个2*3的矩阵:"<<endl; for(int i0;i<2;i) { for(int j0;j<3;j) { cin>>a[i][j…...

AI芯片WT2605C赋能厨房家电,在线对话操控,引领智能烹饪新体验:尽享高效便捷生活

在智能家居的蓬勃发展中&#xff0c;智能厨电作为连接科技与生活的桥梁&#xff0c;正逐步渗透到每一个现代家庭的厨房中。蒸烤箱作为智能厨电的代表&#xff0c;以其丰富的功能和高效的性能&#xff0c;满足了人们对美食的多样化追求。然而&#xff0c;面对众多复杂的操作功能…...

详解调用钉钉AI助理消息API发送钉钉消息卡片给指定单聊用户

文章目录 前言准备工作1、在钉钉开发者后台创建一个钉钉企业内部应用&#xff1b;2、创建并保存好应用的appKey和appSecret&#xff0c;后面用于获取调用API的请求token&#xff1b;3、了解AI助理主动发送消息API&#xff1a;4、应用中配置好所需权限&#xff1a;4.1、权限点4.…...

57 长短期记忆网络(LSTM)_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录长短期记忆网络&#xff08;LSTM&#xff09;门控记忆元输入门、忘记门和输出门候选记忆元 (相当于RNN中计算 H t H_t Ht​)记忆元隐状态 从零开始实现初始化模型参数定义模型训练和预测 简洁实现小结练习 长短期记忆网络&#xff08;LSTM&a…...

Linux系统安装教程

Linux安装流程 一、前置准备工作二、开始安装Linux 一、前置准备工作 安装好VMWare虚拟机&#xff0c;并下载Linux系统的安装包&#xff1b; Linux安装包路径为&#xff1a;安装包链接 &#xff0c; 提取码为&#xff1a;4tiM 二、开始安装Linux...

Redis: Sentinel工作原理和故障迁移流程

Sentinel 哨兵几个核心概念 1 ) 定时任务 Sentinel 它是如何工作的&#xff0c;是如何感知到其他的 Sentinel 节点以及 Master/Slave节点的就是通过它的一系列定时任务来做到的&#xff0c;它内部有三个定时任务 第一个就是每一秒每个 Sentinel 对其他 Sentinel 和 Redis 节点…...

通信工程学习:什么是IGMP因特网组管理协议

IGMP&#xff1a;因特网组管理协议 IGMP&#xff08;Internet Group Management Protocol&#xff0c;因特网组管理协议&#xff09;是TCP/IP协议簇中负责组播成员管理的协议。它主要用于在用户主机和与其直接相连的组播路由器之间建立和维护组播组成员关系。以下是关于IGMP协议…...

高效批量导入多个SQL文件至SQL Server数据库的实用方法

当需要批量导入多个SQL文件到SQL Server数据库时&#xff0c;可以通过以下几种方法来实现&#xff1a; 方法一&#xff1a;使用SQLCMD命令行工具&#xff08;亲测可用&#xff09; 准备SQL文件&#xff1a;确保所有的SQL文件都位于同一个文件夹内&#xff0c;并且文件扩展名为…...

【树莓派系列】树莓派wiringPi库详解,官方外设开发

树莓派wiringPi库详解&#xff0c;官方外设开发 文章目录 树莓派wiringPi库详解&#xff0c;官方外设开发一、安装wiringPi库二、wiringPi库API大全1.硬件初始化函数2.通用GPIO控制函数3.时间控制函数4.串口通信串口API串口通信配置多串口通信配置串口自发自收测试串口间通信测…...

前端模块化CommonJs、ESM、AMD总结

前端开发模式进化史 前端工程化正是为了应对这些演化中出现的挑战和需求而发展起来的&#xff1a; 前后端混合&#xff1a;服务端渲染&#xff0c;javascript仅实现交互前后端分离&#xff1a;借助 ajax 实现前后端分离、单页应用(SPA)等新模式模块化开发&#xff1a;npm 管理…...

JavaWeb - 8 - 请求响应 分层解耦

请求响应 请求&#xff08;HttpServletRequest&#xff09;&#xff1a;获取请求数据 响应&#xff08;HttpServletResponse&#xff09;&#xff1a;设置响应数据 BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程…...

1G,2G,3G,4G,5G各代通信技术的关键技术,联系和区别

目录 1G2G3G4G5G各代通信技术的联系和区别联系区别 1G 1G的主要特点是无线移动化。关键技术为蜂窝组网&#xff0c;支持频率复用和移动切换&#xff0c;可以实现个人和个人移动状态下不间断的语音通信。 1G通信系统现已关闭&#xff0c;其主要缺点是串好和盗号。 2G 数字化…...

【宽搜】2. leetcode 102 二叉树的层序遍历

题目描述 题目链接&#xff1a;二叉树的层序遍历 根据上一篇文章的模板可以直接写代码&#xff0c;需要改变的就是将N叉树的child改为二叉树的left和right。 代码 class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector&…...

Go语言实现长连接并发框架 - 请求分发器

文章目录 前言接口结构体接口实现项目地址最后 前言 你好&#xff0c;我是醉墨居士&#xff0c;我们上篇博客实现了任务管理器的功能&#xff0c;接下来这篇博客我们将要实现请求分发模块的开发 接口 trait/dispatcher.go type Dispatcher interface {Start()Dispatch(conn…...

Redis: 集群测试和集群原理

集群测试 1 ) SET/GET 命令 测试 set 和 get 因为其他命令也基本相似&#xff0c;我们在 101 节点上尝试连接 103 $ /usr/local/redis/bin/redis-cli -c -a 123456 -h 192.168.10.103 -p 6376我们在插入或读取一个 key的时候&#xff0c;会对这个key做一个hash运算&#xff0c…...

问题解决实录 | bash 中 tmux 颜色显示不全

点我进入博客 如下图&#xff0c;tmux 中颜色显示不全: echo $TERM输出的是 screen 但在 bash 里面输出的是 xterm-256 color 在 bash 里面输入&#xff1a; touch ~/.tmux.conf vim ~/.tmux.conf set -g default-terminal "xterm-256color"使之生效 source …...

古典舞在线交流平台:SpringBoot设计与实现详解

摘 要 随着互联网技术的发展&#xff0c;各类网站应运而生&#xff0c;网站具有新颖、展现全面的特点。因此&#xff0c;为了满足用户古典舞在线交流的需求&#xff0c;特开发了本古典舞在线交流平台。 本古典舞在线交流平台应用Java技术&#xff0c;MYSQL数据库存储数据&#…...

五子棋双人对战项目(6)——对战模块(解读代码)

目录 一、约定前后端交互接口的参数 1、房间准备就绪 &#xff08;1&#xff09;配置 websocket 连接路径 &#xff08;2&#xff09;构造 游戏就绪 的 响应对象 2、“落子” 的请求和响应 &#xff08;1&#xff09;“落子” 请求对象 &#xff08;2&#xff09;“落子…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

Linux-进程间的通信

1、IPC&#xff1a; Inter Process Communication&#xff08;进程间通信&#xff09;&#xff1a; 由于每个进程在操作系统中有独立的地址空间&#xff0c;它们不能像线程那样直接访问彼此的内存&#xff0c;所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...

LangChain【6】之输出解析器:结构化LLM响应的关键工具

文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器&#xff1f;1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...