【2】图像视频的加载和显示

文章目录

  • 【2】图像视频的加载和显示
  • 一、代码在哪写
  • 二、创建和显示窗口
    • (一)导入OpenCV的包`cv2`
    • (二)创建窗口
    • (三)更改窗口大小 & 显示窗口
    • (四)等待用户输入
        • 补充:ord()函数来返回ASCII值
    • (五)销毁窗口
    • (※)完整代码
  • 二、加载显示图片
    • (一)cv2.imread()返回值
    • (二)用matplotlib显示图片
    • (三)用OpenCV显示图片
      • (1)封装函数
      • (2)封装外部.py文件
    • (四)保存图片
  • 三、视频采集和录制
    • (一)视频采集
    • (二)视频录制
  • 四、控制鼠标
  • 五、TrackBar控件

【2】图像视频的加载和显示

一、代码在哪写

注:上一节中已经创建好了虚拟环境。

打开Anaconda Prompt,切换到我们已经创建好的opencv虚拟环境下。

image-20240910205759402

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

image-20240910205949797

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

image-20240910210017744

弹出的这些东西就不太对了。

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

image-20240910210132157

可见,此时这一堆东西都是我的C:\Users\11202目录下的文件,这些文件肯定都是不能动的,我们也不应该以这里作为我们写代码的目录

也就是说,上述是一个错误的演示。

正确的应该怎么做呢?如下。

如果是继续刚才的命令往下写,那么需要按两下ctrl+C把刚才打开的jupyter notebook先退出。

如果是关掉,又新打开的Anaconda Prompt,则不要忘了使用activate opencv先跳转到需要的虚拟环境下

然后我们使用cd命令,打开到我们想要作为根目录的路径(我的是D:\ANACONDA\dirs\test2409),然后再使用命令jupyter notebook

image-20240910212613163

注意:从C盘跳转到D盘时,不要写成cd D:,而是直接输入D:。之后,跳转到D盘后,再使用cd去打开对应文件夹。

这时,再跳转到的控制页面就是我们想要的了。之后我们可以在里面新建一个notebook,就可以写代码了。

image-20240910222157917

image-20240910222233409

二、创建和显示窗口

  • namedWindow() 创建命名窗口
  • imshow() 显示窗口
  • destroyAllwindows() 摧毁窗口
  • resizeWindow() 改变窗口大小
  • waitKey() 等待用户输入

我们依次试一下其效果。

(一)导入OpenCV的包cv2

注意:OpenCV名字虽然叫OpenCV,但是在导包的时候,导入的包叫作cv2。(这是个历史遗留问题,很早的时候它就叫cv,之后进行了重构,于是又叫cv2了,并沿用至今)

image-20240910222645716

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

(二)创建窗口

image-20240910223021704

注意:光标放在函数上,按shift+tab可以显示对该函数用法的说明(按一下是简洁版说明,按两下是详细版说明)。这个功能也是使用jupyter notebook所带来的一个好处。

注意:如果发现按shift+tab无效,则首先检查一下是否执行过import cv2代码,因为有时候你刚打开这个文件直接就去shift+tab,发现显示不出说明。实际上是因为没有导入cv2的包,导致它不认识这个函数,自然也就不会给出说明。

这个函数的用法是,括号的内的第一个参数,是窗口名字(注意,应当是一个字符串)。后面的参数是窗口标记(可以从函数用法说明中阅读到具体介绍)。

image-20240910224639146

可见,不同的窗口标记,可以使窗口以不同的风格进行显示;以及如果不注明窗口标记,则会有一个默认值。

注意:如果想要设置flag这一参数,仅仅输入对应标记名是不够的,还要在前面加上cv2.,如cv2.WINDOW_AUTOSIZE。(注意标记名不要写错)

image-20240910225901433

运行后,的确会出现一个窗口,说明代码没问题,但是是未响应状态,这是因为我们写的不是一个规范的写法。

注意:我们把import cv2创建窗口代码写在两个不同的代码框中,此时,务必要保证先运行了import cv2之后,再去运行创建窗口代码,否则会报错(报错原因是找不到cv2这个包)。或者你就把所有代码都写在同一个框里。

(三)更改窗口大小 & 显示窗口

cv2.resizeWindow()的第一个参数为要修改大小的窗口名,后两个参数为窗口大小尺寸

cv2.imshow()的第一个参数为要显示的窗口名,第二个参数为要显示的图片。此处我们没有什么要显示的图片,因此第二个参数设置为0。

此外,需要注意的是,对于我们创建窗口时设置的窗口标记,若设置的是cv2.WINDOW_AUTOSIZE(根据内容自动调节窗口尺寸),那么你修改窗口大小是没有效果的。

注意,注释单行代码的快捷键:ctrl+/

image-20240910231632608

(四)等待用户输入

cv2.waitKey()的作用是,等待接收用户按键,并返回该按键对应的ASCII码值。

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

image-20240910232204977

注意,此时观察左侧,是In [*],是星号说明这段代码正在运行中,还没有运行结束。

实际上,cv2.waitKey(0)的作用就是等待用户按一个键。当然,焦点要在窗口上时才可以。

我按了一个键盘上的q键,它就会捕捉到并输出一个113113就是q的ASCII码值。(注意是小写q,不是大写Q)

image-20240910232058134

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

image-20240910232736048

(五)销毁窗口

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

image-20240910233703301

按下q键后,窗口直接被销毁(关闭),而不会再有窗口未响应的问题。

但是由于程序只接收一次按键,如果你按的不是q键,它还是会有窗口未响应的问题。

image-20240910233819979

注意,如果对于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)

我的原图是:

image-20240911104705365

输出结果如下:

image-20240911104637344

发现这个猫的样子没变,但是颜色不太对。这是因为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文件,把封装的函数代码放进去。

image-20240911110226843

image-20240911110256307

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

image-20240911111714180

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

image-20240911110636568

这样就可以正常运行了。

image-20240911111813648

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

image-20240911112039540

(四)保存图片

  • 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控件

image-20240926102921673

  • 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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/55128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Unity踩坑】Unity更新Google Play结算库

一、问题描述: 在Google Play上提交了app bundle后,提示如下错误。 我使用的是Unity 2022.01.20f1,看来用的Play结算库版本是4.0 查了一下文档,Google Play结算库的维护周期是两年。现在需要更新到至少6.0。 二、更新过程 1. 下…

【视频目标分割-2024CVPR】Putting the Object Back into Video Object Segmentation

Cutie 系列文章目录1 摘要2 引言2.1背景和难点2.2 解决方案2.3 成果 3 相关方法3.1 基于记忆的VOS3.2对象级推理3.3 自动视频分割 4 工作方法4.1 overview4.2 对象变换器4.2.1 overview4.2.2 Foreground-Background Masked Attention4.2.3 Positional Embeddings 4.3 Object Me…

cpp,git,unity学习

c#中的? 1. 空值类型(Nullable Types) ? 可以用于值类型(例如 int、bool 等),使它们可以接受 null。通常,值类型不能为 null,但是通过 ? 可以表示它们是可空的。 int? number null; // …

使用 SSH 连接 Docker 服务器:IntelliJ IDEA 高效配置与操作指南

使用 SSH 连接 Docker 服务器:IntelliJ IDEA 高效配置与操作指南 本文详细介绍了如何在 2375 端口未开放的情况下,通过 SSH 连接 Docker 服务器并在 Idea 中进行开发。通过修改用户权限、生成密钥对以及配置 SSH 访问,用户可以安全地远程操作…

NASA数据集:ATLAS/ICESat-2 L3B 每日和每月网格化海冰自由面高度,第 4 版

目录 简介 摘要 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3B Daily and Monthly Gridded Sea Ice Freeboard, Version 4 简介 ATLAS/ICESat-2 L3B Daily and Monthly Gridded Sea Ice Freeboard, Version 4数据是由NASA的ATLAS&#xff08…

Ubuntu 系统崩了,如何把数据拷下来

问题描述: Linux系统中安装输入法后,重启后,导致系统无法进入,进入 recovery mode下的resume 也启动不了,所以决定将需要的东西复制到U盘 解决方案: 1.重启ubuntu,随即点按Esc进入grub菜单&am…

OpenStack Yoga版安装笔记(十五)Horizon安装

1、官方文档 OpenStack Installation Guidehttps://docs.openstack.org/install-guide/ 本次安装是在Ubuntu 22.04上进行,基本按照OpenStack Installation Guide顺序执行,主要内容包括: 环境安装 (已完成)OpenStack…

HarmonyOS/OpenHarmony Audio 实现音频录制及播放功能

关键词:audio、音频录制、音频播放、权限申请、文件管理 在app的开发过程中时常会遇见一些需要播放一段音频或进行语音录制的场景,那么本期将介绍如何利用鸿蒙 audio 模块实现音频写入和播放的功能。本次依赖的是 ohos.multimedia.audio 音频管理模块&am…

AI日常绘画【国庆海报】:盛世迎华诞,Flux国庆节海报制作教程

大家好我是极可菌!!! 马上就要到祖国母亲的节日了,想想心里都美滋滋的,终于可以放松一下了。相信AI绘画关于国庆主题肯定也会精彩纷呈吧,今天和大家分享几组关于国庆海报的制作教程。 本文使用基于Flux的相…

windows 驱动实例分析系列-定时日志的COM驱动

本文章的前置文章为: windows 驱动编写原则 windows COM驱动 案例 windows COM驱动的I/O处理 在前面的设计中,主要是对windows提供的VirtualSerial源代码的讲解,但是那个驱动其实是一个空壳驱动,用于学习的,在I/O处理中,也讲述了serial I/O处理的本质,接下来会将这些…

【EXCEL数据处理】000009 案列 EXCEL单元格数字格式。文本型数字格式和常规型数字格式的区别

前言:哈喽,大家好,今天给大家分享一篇文章!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【EXCEL数据处理】000009 案列 EXCEL单元格数字格式。文本型数字格式和…

如何使用SCCMSecrets识别SCCM策略中潜在的安全问题

关于SCCMSecrets SCCMSecrets是一款针对SCCM策略的安全扫描与检测工具,该工具旨在提供一种有关 SCCM 策略的全面安全检测方法。 该工具可以从各种权限级别执行,并将尝试发现与策略分发相关的潜在错误配置。除了分发点上托管的包脚本外,它还将…

【C++篇】启航——初识C++(下篇)

接上篇【C篇】启航——初识C(上篇) 目录 一、引用 1.引用的概念 2.引用的基本语法 3.引用的特点 3.1 别名 3.2 不占用额外内存 3.3 必须初始化 3.4 不能为 NULL 4.引用的使用 4.1 函数参数传递 4.2 返回值 4.3 常量引用 5.引用和指针的关…

网站建设公司如何选?2024专业网站建设公司哪家好TOP3

要找一家靠谱的网站建设公司,可以根据以下五点判断: 1.企业的工商信息 企业有多少人、什么时候成立的、成立资金是多少、是否有违约记录这些都可以在查企业的那种app里可以看到,去查的时候一定要仔细甄别,别最后找了一家皮包公司…

PCL 索引空间采样

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 索引空间采样 2.1.2 可视化原始点云和下采样后的点云 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇总&#xf…

软件设计师——计算机网络

📔个人主页📚:秋邱-CSDN博客☀️专属专栏✨:软考——软件设计师🏅往期回顾🏆:🌟其他专栏🌟:C语言_秋邱 一、OSI/ RM七层模型(⭐⭐⭐) ​ 层次 名称 主要功…

【Iceberg分析】调研Iceberg中表的原地演变

调研Iceberg中表的原地演变 文章目录 调研Iceberg中表的原地演变原生非分区表文件关系图表的原地演变之表schema演变新增字段new_column文件关系变化图为新增字段写入数据文件关系变化图删除新增字段文件关系变化图新增字段new_column2文件关系变化图删除数据文件关系变化图 原…

C++ | Leetcode C++题解之第433题最小基因变化

题目&#xff1a; 题解&#xff1a; class Solution { public:int minMutation(string start, string end, vector<string>& bank) {int m start.size();int n bank.size();vector<vector<int>> adj(n);int endIndex -1;for (int i 0; i < n; i)…

爬虫及数据可视化——运用Hadoop和MongoDB数据进行分析

作品详情  运用Hadoop和MongoDB对得分能力数据进行分析&#xff1b;  运用python进行机器学习的模型调理&#xff0c;利用Pytorch框架对爬取的评论进行情感分析预测&#xff1b;  利用python和MySQL对网站的数据进行爬取、数据清洗及可视化。

快速实现AI搜索!Fivetran 支持 Milvus 作为数据迁移目标

Fivetran 现已支持 Milvus 向量数据库作为数据迁移的目标&#xff0c;能够有效简化 RAG 应用和 AI 搜索中数据源接入的流程。 数据是 AI 应用的支柱&#xff0c;无缝连接数据是充分释放数据潜力的关键。非结构化数据对于企业搜索和检索增强生成&#xff08;RAG&#xff09;聊天…