【2】图像视频的加载和显示
文章目录
- 【2】图像视频的加载和显示
- 一、代码在哪写
- 二、创建和显示窗口
- (一)导入OpenCV的包`cv2`
- (二)创建窗口
- (三)更改窗口大小 & 显示窗口
- (四)等待用户输入
- 补充:ord()函数来返回ASCII值
- (五)销毁窗口
- (※)完整代码
- 二、加载显示图片
- (一)cv2.imread()返回值
- (二)用matplotlib显示图片
- (三)用OpenCV显示图片
- (1)封装函数
- (2)封装外部.py文件
- (四)保存图片
- 三、视频采集和录制
- (一)视频采集
- (二)视频录制
- 四、控制鼠标
- 五、TrackBar控件
【2】图像视频的加载和显示
一、代码在哪写
注:上一节中已经创建好了虚拟环境。
打开Anaconda Prompt,切换到我们已经创建好的opencv虚拟环境下。

我们使用jupyter notebook来写代码。(输入jupyter notebook)

之后,就弹出一个控制台页面。

弹出的这些东西就不太对了。
为什么会弹出这一堆东西,原因在于:你在哪个目录下执行的jupyter notebook命令,它就会以哪个目录作为根目录。

可见,此时这一堆东西都是我的C:\Users\11202目录下的文件,这些文件肯定都是不能动的,我们也不应该以这里作为我们写代码的目录。
也就是说,上述是一个错误的演示。
正确的应该怎么做呢?如下。
如果是继续刚才的命令往下写,那么需要按两下ctrl+C把刚才打开的jupyter notebook先退出。
如果是关掉,又新打开的Anaconda Prompt,则不要忘了使用activate opencv先跳转到需要的虚拟环境下。
然后我们使用cd命令,打开到我们想要作为根目录的路径(我的是D:\ANACONDA\dirs\test2409),然后再使用命令jupyter notebook。

注意:从C盘跳转到D盘时,不要写成cd D:,而是直接输入D:。之后,跳转到D盘后,再使用cd去打开对应文件夹。
这时,再跳转到的控制页面就是我们想要的了。之后我们可以在里面新建一个notebook,就可以写代码了。


二、创建和显示窗口
namedWindow()创建命名窗口imshow()显示窗口destroyAllwindows()摧毁窗口resizeWindow()改变窗口大小waitKey()等待用户输入
我们依次试一下其效果。
(一)导入OpenCV的包cv2
注意:OpenCV名字虽然叫OpenCV,但是在导包的时候,导入的包叫作cv2。(这是个历史遗留问题,很早的时候它就叫cv,之后进行了重构,于是又叫cv2了,并沿用至今)

运行没有报错,说明正确导入此包。说明我们之前的环境配置、包的安装等操作都是顺利的。
(二)创建窗口

注意:光标放在函数上,按shift+tab可以显示对该函数用法的说明(按一下是简洁版说明,按两下是详细版说明)。这个功能也是使用jupyter notebook所带来的一个好处。
注意:如果发现按
shift+tab无效,则首先检查一下是否执行过import cv2代码,因为有时候你刚打开这个文件直接就去shift+tab,发现显示不出说明。实际上是因为没有导入cv2的包,导致它不认识这个函数,自然也就不会给出说明。
这个函数的用法是,括号的内的第一个参数,是窗口名字(注意,应当是一个字符串)。后面的参数是窗口标记(可以从函数用法说明中阅读到具体介绍)。

可见,不同的窗口标记,可以使窗口以不同的风格进行显示;以及如果不注明窗口标记,则会有一个默认值。
注意:如果想要设置flag这一参数,仅仅输入对应标记名是不够的,还要在前面加上cv2.,如cv2.WINDOW_AUTOSIZE。(注意标记名不要写错)

运行后,的确会出现一个窗口,说明代码没问题,但是是未响应状态,这是因为我们写的不是一个规范的写法。
注意:我们把
import cv2与创建窗口代码写在两个不同的代码框中,此时,务必要保证先运行了import cv2之后,再去运行创建窗口代码,否则会报错(报错原因是找不到cv2这个包)。或者你就把所有代码都写在同一个框里。
(三)更改窗口大小 & 显示窗口
cv2.resizeWindow()的第一个参数为要修改大小的窗口名,后两个参数为窗口大小尺寸。
cv2.imshow()的第一个参数为要显示的窗口名,第二个参数为要显示的图片。此处我们没有什么要显示的图片,因此第二个参数设置为0。
此外,需要注意的是,对于我们创建窗口时设置的窗口标记,若设置的是cv2.WINDOW_AUTOSIZE(根据内容自动调节窗口尺寸),那么你修改窗口大小是没有效果的。
注意,注释单行代码的快捷键:
ctrl+/。

(四)等待用户输入
cv2.waitKey()的作用是,等待接收用户按键,并返回该按键对应的ASCII码值。
其中参数设置为0,表示一直等待、接收任意按键。如果设置其他的整数,表示等待按键的时间(单位是毫秒)。比如设置为cv2.waitKey(5000),就表示它会等你5秒,在5秒之内你按键才有用,过了5秒就不等你了。

注意,此时观察左侧,是In [*],是星号说明这段代码正在运行中,还没有运行结束。
实际上,cv2.waitKey(0)的作用就是等待用户按一个键。当然,焦点要在窗口上时才可以。
我按了一个键盘上的q键,它就会捕捉到并输出一个113。113就是q的ASCII码值。(注意是小写q,不是大写Q)

补充:ord()函数来返回ASCII值

(五)销毁窗口
我们可以配合cv2.waitKey(0),先接收到用户按键的ASCII码值,然后就能根据用户按的是什么键,判断是否要销毁窗口了。(常用的比如q键、ESC键)。

按下q键后,窗口直接被销毁(关闭),而不会再有窗口未响应的问题。
但是由于程序只接收一次按键,如果你按的不是q键,它还是会有窗口未响应的问题。

注意,如果对于
key == 'q'为什么有问题有疑问,则需要补一补python基础。
(※)完整代码
# ------------------------- 创建和显示窗口 -------------------------# opencv名字叫opencv,但是导包的时候叫做cv2
import cv2# 创建窗口
# 注意,cv2.WINDOW_AUTOSIZE则后续修改窗口大小无效
# cv2.namedWindow('myWindow01', cv2.WINDOW_AUTOSIZE)
cv2.namedWindow('myWindow01', cv2.WINDOW_NORMAL)# 更改窗口大小
cv2.resizeWindow('myWindow01', 800, 600)# 显示指定名字的窗口
cv2.imshow('myWindow01', 0)# 等待按键
# 若用户按键为q键,则销毁窗口
key = cv2.waitKey(0) # 先用变量key接收
# 注意,这样写更易读,而不要写key == 113,即使你知道q是113
# 注意,不要写成key == 'q'
if key == ord('q'):print('准备销毁窗口')cv2.destroyAllWindows()# ------------------------- 创建和显示窗口 -------------------------
二、加载显示图片
imread(path, flag)
使用imread可以读取图片,默认读取的是彩色图片。
path是图片的路径(绝对路径、相对路径都可以)。
flag是以什么方式读取这个图片(比如读出来是黑白的)。
(一)cv2.imread()返回值
# 导入opencv包
import cv2# 读取图片
cat = cv2.imread('./1.png')# numpy的ndarray(多维数组)
cat
输出如下:
array([[[ 1, 12, 90],[ 2, 12, 91],[ 1, 13, 91],...,[ 3, 10, 61],[ 4, 9, 61],[ 4, 9, 65]],[[ 3, 13, 91],[ 3, 13, 92],[ 2, 14, 92],...,[ 2, 11, 60],[ 2, 10, 60],[ 2, 9, 63]],[[ 2, 12, 91],[ 2, 13, 91],[ 2, 14, 92],...,[ 3, 10, 60],[ 3, 10, 60],[ 3, 10, 62]],...,[[ 4, 31, 111],[ 4, 32, 112],[ 4, 31, 113],...,[119, 190, 208],[119, 190, 208],[119, 190, 208]],[[ 5, 31, 111],[ 5, 31, 111],[ 5, 31, 112],...,[119, 190, 208],[119, 190, 208],[119, 190, 208]],[[ 6, 32, 111],[ 6, 31, 111],[ 6, 31, 111],...,[118, 189, 207],[119, 190, 208],[119, 190, 208]]], dtype=uint8)
(二)用matplotlib显示图片
import matplotlib.pyplot as pltplt.imshow(cat)
我的原图是:

输出结果如下:

发现这个猫的样子没变,但是颜色不太对。这是因为OpenCV读取的图片颜色通道是按照BGR(蓝绿红)排列的,一般的图片通道都是按照RGB来排列的。
为了正常显示图片,我们要使用OpenCV的图像显示方法。换句话说,用OpenCV读进来的图片一般不要用别的方式进行展示,比如matplotlib。
(三)用OpenCV显示图片
cv2.imshow('cat', cat)# 按键以销毁窗口,避免每次都有窗口未响应的问题
key = cv2.waitKey(0)
if key == ord('q'):print('准备销毁窗口')cv2.destroyAllWindows()
这样就会弹出一个窗口,并正常显示该图片,我们可以按下q键以正常关闭窗口。
(1)封装函数
此外,我们可以把显示图片的方法封装成一个函数,方便我们显示图片:
# 把展示图片的代码封装成函数
def cv_show(name, img):cv2.imshow(name, img)key = cv2.waitKey(0)if key == ord('q'):cv2.destroyAllWindows()
之后想显示图片的时候,直接调用函数即可:
# 导入opencv包
import cv2# 读取图片
cat = cv2.imread('./1.png')cv_show('cat', cat)
(2)封装外部.py文件
我们可以在当前目录下创建一个.py文件,把封装的函数代码放进去。


注意,如果这样放代码,那么在调用的时候会报错。因为,在utils.py这个文件中,我们调用了cv2,但是并没有导入cv2,就会报错。

需要在函数中调用cv2之前,先import cv2。

这样就可以正常运行了。

注意:如果还是有问题,可以使用%run utils.py执行一下外部文件(这是在jupyter中执行外部文件的方法),看看外部文件本身是否运行不了。如果在执行外部文件时报错IndentationError: unindent does not match any outer indentation level,则是代码缩进问题,一般是tab和空格混用导致的缩进问题,这个问题仅凭肉眼是不容易看出来的(新手容易踩的坑)。(如果使用的是notepad++,可以通过View--Show Symbol--Show All Characters来检查这一问题)

(四)保存图片
imwrite(path, img):使用imwrite保存图片。
import cv2cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 320, 240)img = cv2.imread('./1.png')# 利用while循环优化退出逻辑
while True:cv2.imshow('img', img)key = cv2.waitKey(0)if(key & 0xFF == ord('q')):breakelif(key & 0xFF == ord('s')):cv2.imwrite('./123.png', img)else:print(key)cv2.destroyAllWindows()
三、视频采集和录制
(一)视频采集
- 视频是由图片组成的,视频的每一帧就是一幅图片,一般是30帧,表示一秒显示30张图片。
cv2.VideoCapture可以捕获摄像头,用数字来表示不同的设备,比如0、1。- 如果是视频文件,可以直接指定路径即可。
# 打开视频文件
vc = cv2.VideoCapture('./1.mp4')# 打开摄像头
vc = cv2.VideoCapture(0)
打开摄像头
示例:
# 打开摄像头
import cv2cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('video', 640, 480)# 如果打开失败(比如没有摄像头),不会报错
# cap = cv2.VideoCapture(1) # 我只有摄像头0,没有摄像头1
cap = cv2.VideoCapture(0)# 循环读取摄像头的每一帧
# while True:
while cap.isOpened():# 读一帧数据,返回标记和这一帧数据,标记为True表示读到了数据,False表示没读到数据ret, frame = cap.read()# 可以根据ret做个判断if not ret:# 没读到数据,直接退出break# 显示数据cv2.imshow('video', frame)key = cv2.waitKey(1)# 注意,此处就不要再写0了,因为写0表示无限等待,也就是显示一帧数据然后一直等待用户按键# 写个1,表示等1毫秒,若等不到按键就继续处理了if key == ord('q'):break# 别忘了释放资源
cap.release()
cv2.destroyAllWindows()
打开视频文件
示例:
# 打开摄像头
import cv2cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('video', 640, 480)# 打开视频,传入视频路径即可
cap = cv2.VideoCapture('./1.mp4')# 循环读取摄像头的每一帧
# while True:
while cap.isOpened():# 读一帧数据,返回标记和这一帧数据,标记为True表示读到了数据,False表示没读到数据ret, frame = cap.read()# 可以根据ret做个判断if not ret:# 没读到数据,直接退出break# 显示数据cv2.imshow('video', frame)key = cv2.waitKey(1)# 注意,此处就不要再写0了,因为写0表示无限等待,也就是显示一帧数据然后一直等待用户按键# 写个1,表示等1毫秒,若等不到按键就继续处理了# key = cv2.waitKey(1000 // 30) # 让视频以30帧播放if key == ord('q'):break# 别忘了释放资源
cap.release()
cv2.destroyAllWindows()
注意,上述代码,和刚才“打开摄像头”的代码只有一行不同,即第8行的cap = cv2.VideoCapture('./1.mp4'),其他地方都相同。
运行此代码时,发现其播放的视频好像加速了一样,这是因为,第24行代码的key = cv2.waitKey(1)造成的效果是每等待1毫秒显示一帧数据,所以播放的比较快。
假如我们想让视频是30帧,那么每张图片要间隔多少毫秒?
答:理论上来说,是1000 / 30ms,但此处传递的参数必须是整数,所以我们代码写成1000 // 30。(Python语法,//表示向下取整)
另外,我们此处处理的是视频中每一帧的图片,所以没有声音。
(二)视频录制
VideoWriter:参数1为输出文件,参数2为多媒体文件格式(VideoWriter_fourcc),参数3为帧率,参数4为分辨率;write编码并写入缓存;release缓存内容写入磁盘,并释放资源。
import cv2cap = cv2.VideoCapture(0)# *mp4v 就是解包操作,等同于 'm','p','4','v'
# fourcc = cv2.VideoWriter_fourcc(*'mp4v')# avi格式的视频
fourcc = cv2.VideoWriter_fourcc(*'XVID')# (640, 480)表示摄像头拍视频的分辨率,这个大小搞错了也不行
# vw = cv2.VideoWriter('output.mp4', fourcc, 20, (640, 480))# 如果前面写的是avi,这里要改成avi格式
vw = cv2.VideoWriter('output.avi', fourcc, 20, (640, 480))while cap.isOpened():ret, frame = cap.read()if not ret:print('can not receive frame, Exiting...')breakvw.write(frame)cv2.imshow('frame', frame)if cv2.waitKey(1) == ord('q'):breakcap.release()vw.release()cv2.destroyAllWindows()
四、控制鼠标
OpenCV允许我们对窗口上的鼠标动作做出响应。
setMouseCallback(winname, callback, userdata):winname是窗口名字,callback是回调函数,userdata是给回调函数的参数。callback(event, x, y, flags, userdata):回调函数必须包含这5个参数。event是事件(鼠标移动、左键、右键),xy是点鼠标的坐标点,flags主要用于组合键,userdata就是上面的setMouseCallback的userdata。
鼠标事件:
EVENT_MOUSEMOVE 0 鼠标移动
EVENT_LBUTTONDOWN 1 按下鼠标左键
EVENT_RBUTTONDOWN 2 按下鼠标右键
EVENT_MBUTTONDOWN 3 按下鼠标中键
EVENT_LBUTTONUP 4 左键释放
EVENT_RBUTTONUP 5 右键释放
EVENT_MBUTTONUP 6 中键释放
EVENT_LBUTTONDBLCLK 7 左键双击
EVENT_RBUTTONDBLCLK 8 右键双击
EVENT_MBUTTONDBLCLK 9 中键双击
EVENT_MOUSEWHEEL 10 鼠标滚轮上下滚动
EVENT_MOUSEHWHEEL 11 鼠标左右滚动flags:
EVENT_FLAG_LBUTTON 1 按下左键
EVENT_FLAG_RBUTTON 2 按下右键
EVENT_FLAG_MBUTTON 4 按下中键
EVENT_FLAG_CTRLKEY 8 按下ctrl键
EVENT_FLAG_SHIFTKEY 16 按下shift键
EVENT_FLAG_ALTKEY 32 按下alt键
示例:
import cv2
import numpy as np# 函数名可以随便取,但是参数必须是5个(参数名也可以随便取)
# event表示鼠标事件
# x, y是发生鼠标事件的坐标
# flags是鼠标的组合操作
def mouse_callback(event, x, y, flags, userdata):print(event, x, y, flags, userdata)# 按下鼠标右键退出if event == 2:cv2.destroyAllWindows()# 创建窗口
cv2.namedWindow('mouse', cv2.WINDOW_NORMAL)
cv2.resizeWindow('mouse', 640, 360)# 设置鼠标的回调函数
cv2.setMouseCallback('mouse', mouse_callback, '123')# 生成全黑的图片
img = np.zeros((360, 640, 3), np.uint8)while True:cv2.imshow('mouse', img)key = cv2.waitKey(1)if key == ord('q'):breakcv2.destroyAllWindows()
五、TrackBar控件

createTrackbar(trackbarname, winname, value, count, onChange):创建TrackBar控件,value为trackbar的默认值,count为bar的最大值,最小为0。getTrackbarPos(trackbarname, winname):获取TrackBar当前值。
示例:
import cv2
import numpy as np# 创建窗口
cv2.namedWindow('trackbar', cv2.WINDOW_NORMAL)
cv2.resizeWindow('trackbar', 640, 480)# 定义回调函数
def callback(value):print(value)# 创建trackbar
cv2.createTrackbar('R', 'trackbar', 0, 255, callback)
cv2.createTrackbar('G', 'trackbar', 0, 255, callback)
cv2.createTrackbar('B', 'trackbar', 0, 255, callback)# 创建一个背景图片
img = np.zeros((480, 640, 3), np.uint8)while True:# 获取当前trackbar的值r = cv2.getTrackbarPos('R', 'trackbar')g = cv2.getTrackbarPos('G', 'trackbar')b = cv2.getTrackbarPos('B', 'trackbar')# 改变背景图颜色img[:] = [b, g, r]cv2.imshow('trackbar', img)key = cv2.waitKey(1)if key & 0xFF == ord('q'):breakcv2.destroyAllWindows()
相关文章:
【2】图像视频的加载和显示
文章目录 【2】图像视频的加载和显示一、代码在哪写二、创建和显示窗口(一)导入OpenCV的包cv2(二)创建窗口(三)更改窗口大小 & 显示窗口(四)等待用户输入补充:ord()函…...
1. BOOT.BIN 2. 固化 3. 启动 4. SDK 5. 文件
在进行FPGA的开发与固化过程中,生成BOOT.BIN文件是一个重要的步骤。BOOT.BIN文件通常包含了系统启动所需的不同文件,以下是如何创建和使用该文件的详细说明。 ### 生成BOOT.BIN文件的步骤 1. **方法一:通过项目构建** - 右键单击项目…...
vue按钮接收键盘回车事件
了解了!如果您想让 Submit 按钮在按下回车键时被触发,可以在 Vue 组件中监听全局的键盘事件。以下是实现这一功能的示例: 示例代码 <template><div><inputtype"text"v-model"inputValue"placeholder&qu…...
腾讯云点播及声音上传
文章目录 1、开通腾讯云点播2、获取腾讯云API密钥3、完成声音上传3.1、引入依赖3.2、参考:接入点地域3.3、参考:任务流设置3.4、首先修改配置:3.4.1、 3.5、TrackInfoApiController --》 uploadTrack()3.6、VodServiceImpl --》 uploadTrack(…...
如何查看服务器是否有raid阵列卡以及raid类型
要查看服务器是否配置了RAID阵列卡以及RAID的类型,可以使用多种方法。以下是一些常用的命令和步骤: 1. 使用 lspci 命令 这个命令可以列出所有的PCI设备,包括RAID控制器。 lspci | grep -i raid 如果输出中有RAID相关的设备信息,那…...
工博会动态 | 来8.1馆 看桥田如何玩转全场
北京时间2024年9月24日,中国国际工业博览会开幕,桥田智能(8.1馆A001)推出心意三重奏,有没有小伙伴们发现呢?现在,让我们一起city walk下! 桥田显眼包横空出道 有小伙伴已经发现&…...
新版torch_geometric不存在uniform、maybe_num_nodes函数问题(Prune4ED论文报错解决)
这是在复现论文“Towards accurate subgraph similarity computation via neural graph pruning”时遇到的报错。 ImportError: cannot import name uniform from torch_geometric.nn.pool.topk_pool 一、报错原因 论文作者使用的是2.1.0版本的torch_geometric。而我安装了2.…...
实现简易 vuedraggable 的拖拽排序功能
一、案例效果 拖拽计数4实现手动排序 二、案例代码 <draggable:list"searchResult.indicator":group"{ name: indicators }"item-key"field"handle".drag-handle-icon"><divclass"field-item"v-for"(item…...
第L2周:机器学习|线性回归模型 LinearRegression:2. 多元线性回归模型
本文为365天深度学习训练营 中的学习记录博客原作者:K同学啊 任务: ●1. 学习本文的多元线形回归模型。 ●2. 参考文本预测花瓣宽度的方法,选用其他三个变量来预测花瓣长度。 一、多元线性回归 简单线性回归:影响 Y 的因素唯一&…...
JavaScript的条件语句
if条件语句 if结构先判断一个表达式的布尔值,然后根据布尔值的真伪,执行不同的语句。所谓布尔值,指的是JavaScript 的两个特殊值,true表示真,false表示伪。 if语句语法规范 if(布尔值){语句;}var m3if(m3){console.l…...
vue3 vite模式配置测试,开发、生产环境以及代理配置
1、首先在根目录下创建三个文本文件:.env.development,.env.production,.env.test .env.development中的内容为: // 开发环境 .env.development NODE_ENV development VITE_APP_MODE development VITE_OUTPUTDIR dist_dev /…...
【rabbitmq-server】安装使用介绍
在 1050a 系统下安装 rabbitmq-server 服务以及基本配置;【注】:改方案用于A版统信服务器操作系统 文章目录 功能概述功能介绍一、安装软件包二、启动服务三、验证四、基本配置功能概述 RabbitMQ 是AMQP的实现,高性能的企业消息的新标准。RabbitMQ服务器是一个强大和可扩展…...
Kafka系列之:安装部署CMAK,CMAK管理大型Kafka集群参数调优
Kafka系列之:安装部署CMAK,CMAK管理大型Kafka集群参数调优 一、CMAK二、要求三、配置四、启动服务五、使用 Security 启动服务六、消费者/生产者滞后七、从 Kafka Manager 迁移到 CMAK八、CMAK管理大型Kafka集群参数调优九、后台运行CMAK十、输出日志一、CMAK CMAK(之前称为…...
c语言200例 64
大家好,欢迎来到无限大的频道。 今天带领大家来学习c语言。 题目要求: 设计一个进行候选人的选票程序。假设有三位候选人,在屏幕上输入要选择的候选人姓名, 有10次投票机会,最后输出每个人的得票结果。好的ÿ…...
[leetcode]216_组合总和III_给定数字范围且输出无重复
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件: 只使用数字1到9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。示例 1: 输入: k 3, n 7 输出: [[1,2,4]] 解释: 1…...
Doris 2.x 安装及使用
Doris 2.x 安装及使用 简介 Apache Doris 是一款基于 MPP 架构的高性能、实时的分析型数据库,以高效、简单、统一的特点被人们所熟知,仅需亚秒级响应时间即可返回海量数据下的查询结果,不仅可以支持高并发的点查询场景,也能支持…...
MySQL字符集设置
MySQL字符集设置 一、查看当前配置的字符集 \s;示例 MariaDB [(none)]> \s -------------- mysql Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1Connection id: 11 Current database: Current user: rootlocalhost SSL: …...
深度学习模型量化
模型量化是深度学习领域中的一项重要技术,它通过降低模型参数的精度,将浮点数转换为整数或定点数,从而实现模型的压缩和优化。以下是进行模型量化的详细步骤和注意事项: 一、模型量化的基本步骤 选择量化方法 后训练量化…...
红黑树和B+树
红黑树和B树是两种常用的自平衡数据结构,适用于不同的应用场景和需求。下面是对这两种树的详细比较和描述: 红黑树 基本结构: 红黑树是一种自平衡的二叉搜索树(Binary Search Tree),其中每个节点都有一个颜…...
debian 12配置固定ip
配置文件 cat /etc/network/interfaces |grep -v # source /etc/network/interfaces.d/*auto lo iface lo inet loopbackallow-hotplug ens18 iface ens18 inet staticaddress 192.168.0.105/24network 192.168.0.0broadcast 192.168.0.255gateway 192.168.0.1dns-nameserver…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
