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

ubuntu22.04@laptop OpenCV Get Started: 013_contour_detection

ubuntu22.04@laptop OpenCV Get Started: 013_contour_detection

  • 1. 源由
  • 2. 应用Demo
    • 2.1 C++应用Demo
    • 2.2 Python应用Demo
  • 3. contour_approx应用
    • 3.1 读取图像并将其转换为灰度格式
    • 3.2 应用二进制阈值过滤算法
    • 3.3 查找对象轮廓
    • 3.4 绘制对象轮廓
    • 3.5 效果
    • 3.6 `CHAIN_APPROX_SIMPLE` v.s.`CHAIN_APPROX_NONE`
  • 4. channel_experiments应用
    • 4.1 读取图像并将其转换为单通道
    • 4.2 查找对象轮廓
    • 4.3 绘制对象轮廓
    • 4.4 效果
  • 5. contour_extraction应用
    • 5.1 RETR_LIST
    • 5.2 RETR_EXTERNAL
    • 5.3 RETR_CCOMP
    • 5.4 RETR_TREE
    • 5.5 运行时间比较
  • 6. 总结
  • 7. 参考资料
  • 8. 补充

1. 源由

使用轮廓检测检测物体的边界,通常是许多有趣应用的第一步,如图像前景提取、简单的图像分割、检测和识别。

罗列一些使用轮廓进行运动检测或分割应用:

  • 运动检测:在监控视频中,运动检测技术有许多应用,包括室内和室外安全环境、交通控制、体育活动中的行为检测、无人看管物体的检测,甚至视频压缩。在下图中,可以看到检测视频流中的人员移动在监控应用程序中是如何有用的。请注意,未检测到静止在图像左侧的那组人。只有运动中的人才会被捕捉到。请参考《Moving Object Detection and Segmentation using Frame differencing and Summing Technique》详细研究这种方法。

在这里插入图片描述

  • 无人值守物体检测:公共场所的无人值守物体通常被视为可疑物体。一个有效且安全的解决方案详见:《Unattended Object Detection through Contour Formation using Background Subtraction》。

在这里插入图片描述

  • 背景/前景分割:要用另一个图像替换图像的背景,需要执行图像前景提取(类似于图像分割)。使用轮廓是可以用于执行分割的一种方法。有关更多详细信息,请参阅《Background Removal with Python Using OpenCV to Detect the Foreground》。

在这里插入图片描述

2. 应用Demo

013_contour_detection是OpenCV通过鼠标指针和轨迹条与用户交互的示例。

2.1 C++应用Demo

C++应用Demo工程结构:

013_contour_detection/CPP$ tree .                                              .
├── channel_experiments
│   ├── channel_experiments.cpp
│   └── CMakeLists.txt
├── contour_approximations
│   ├── CMakeLists.txt
│   └── contour_approx.cpp
└── contour_extraction├── CMakeLists.txt└── contour_extraction.cpp3 directories, 6 files

确认OpenCV安装路径:

$ find /home/daniel/ -name "OpenCVConfig.cmake"
/home/daniel/OpenCV/installation/opencv-4.9.0/lib/cmake/opencv4/
/home/daniel/OpenCV/opencv/build/OpenCVConfig.cmake
/home/daniel/OpenCV/opencv/build/unix-install/OpenCVConfig.cmake$ export OpenCV_DIR=/home/daniel/OpenCV/installation/opencv-4.9.0/lib/cmake/opencv4/

C++应用Demo工程编译执行:

$ mkdir build
$ cd build
$ cmake ..
$ cmake --build . --config Release
$ cd ..
$ ./build/channel_experiments
$ mkdir build
$ cd build
$ cmake ..
$ cmake --build . --config Release
$ cd ..
$ ./build/contour_approximations
$ mkdir build
$ cd build
$ cmake ..
$ cmake --build . --config Release
$ cd ..
$ ./build/contour_extraction

2.2 Python应用Demo

Python应用Demo工程结构:

013_contour_detection/Python$ tree .
.
├── channel_experiments
│   └── channel_experiments.py
├── contour_approximations
│   └── contour_approx.py
├── contour_extraction
│   └── contour_extraction.py
└── requirements.txt3 directories, 4 files

Python应用Demo工程执行:

$ workoncv-4.9.0
$ python channel_experiments.py
$ python contour_approx.py
$ python contour_extraction.py

3. contour_approx应用

在OpenCV中检测和绘制轮廓的步骤如下所示:

  1. 读取图像并将其转换为灰度格式
  2. 应用二进制阈值过滤算法
  3. 查找对象轮廓
  4. 绘制对象轮廓

查找轮廓可以采用两种方式:

  • CHAIN_APPROX_SIMPLE
  • CHAIN_APPROX_NONE

3.1 读取图像并将其转换为灰度格式

读取图像并将图像转换为灰度格式。将图像转换为灰度非常重要,因为它为下一步的图像做准备。

将图像转换为单通道灰度图像对于阈值处理很重要,这反过来又是轮廓检测算法正常工作所必需的。

C++:

    // read the imageMat image = imread("../../input/image_1.jpg");// convert the image to grayscale formatMat img_gray;cvtColor(image, img_gray, COLOR_BGR2GRAY);

Python:

# read the image
image = cv2.imread('../../input/image_1.jpg')
# convert the image to grayscale format
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

3.2 应用二进制阈值过滤算法

在寻找轮廓时,首先总是对灰度图像应用二进制阈值或Canny边缘检测。在这里,我们将应用二进制阈值。

这将图像转换为黑白图像,突出显示感兴趣的对象,从而简化轮廓检测算法。阈值化使图像中对象的边界完全变白,所有像素都具有相同的强度。该算法现在可以从这些白色像素中检测物体的边界。

C++:

    // apply binary thresholdingMat thresh;threshold(img_gray, thresh, 150, 255, THRESH_BINARY);

Python:

# apply binary thresholding
ret, thresh = cv2.threshold(img_gray, 150, 255, cv2.THRESH_BINARY)

3.3 查找对象轮廓

C++:

    // detect the contours on the binary image using cv2.CHAIN_APPROX_NONEvector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(thresh, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);########## 两种轮廓检测方法,所以有两段对应的代码// Now let's try with CHAIN_APPROX_SIMPLE`// detect the contours on the binary image using cv2.CHAIN_APPROX_NONEvector<vector<Point>> contours1;vector<Vec4i> hierarchy1;findContours(thresh, contours1, hierarchy1, RETR_TREE, CHAIN_APPROX_SIMPLE);

Python:

# detect the contours on the binary image using cv2.CHAIN_APPROX_NONE
contours, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)########## 两种轮廓检测方法,所以有两段对应的代码
# detect the contours on the binary image using cv2.ChAIN_APPROX_SIMPLE
contours1, hierarchy1 = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

3.4 绘制对象轮廓

C++:

    // draw contours on the original imageMat image_copy = image.clone();drawContours(image_copy, contours, -1, Scalar(0, 255, 0), 2);imshow("None approximation", image_copy);########## 两种轮廓检测方法,所以有两段对应的代码// draw contours on the original imageMat image_copy1 = image.clone();drawContours(image_copy1, contours1, -1, Scalar(0, 255, 0), 2);imshow("Simple approximation", image_copy1);

Python:

# draw contours on the original image
image_copy = image.copy()
cv2.drawContours(image=image_copy, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
# see the results
cv2.imshow('None approximation', image_copy)########## 两种轮廓检测方法,所以有两段对应的代码
# draw contours on the original image for `CHAIN_APPROX_SIMPLE`
image_copy1 = image.copy()
cv2.drawContours(image_copy1, contours1, -1, (0, 255, 0), 2, cv2.LINE_AA)
# see the results
cv2.imshow('Simple approximation', image_copy1)

3.5 效果

该算法生成的轮廓很好地识别了每个对象的边界。然而,如果你仔细观察手机,你会发现它包含不止一个轮廓。已经为与相机镜头和光线相关的圆形区域确定了单独的轮廓。沿着手机边缘的部分,也有“次要”轮廓。
在这里插入图片描述

3.6 CHAIN_APPROX_SIMPLE v.s.CHAIN_APPROX_NONE

轮廓算法的准确性和质量在很大程度上取决于所提供的二进制图像的质量。某些场景需要高质量的轮廓,因此在创建二进制图像时使用不同的阈值进行实验,看看这是否会改善生成的轮廓。

另外,两种方法执行完后,将轮廓进行描点,可以发现:CHAIN_APPROX_NONE点数多于CHAIN_APPROX_SIMPLE

CHAIN_APPROX_SIMPLE算法沿轮廓压缩水平、垂直和对角线段,只保留它们的端点。这意味着沿着直线路径的任何点都将被忽略,将只剩下终点。

例如,考虑一个沿着矩形的轮廓。除四个角点外,所有轮廓点都将被忽略。此方法比CHAIN_APPROX_NONE更快,因为该算法不存储所有点,使用更少的内存,因此执行所需时间更少。

换一张复杂的图

4. channel_experiments应用

在OpenCV中检测和绘制轮廓的步骤如下所示:

  1. 读取图像并将其转换为单通道:红色、绿色或蓝色
  2. 查找对象轮廓
  3. 绘制对象轮廓

4.1 读取图像并将其转换为单通道

C++:

    // read the imageMat image = imread("../../input/image_1.jpg");// B, G, R channel splittingMat channels[3];split(image, channels);

Python:

# read the image
image = cv2.imread('../../input/image_1.jpg')# B, G, R channel splitting
blue, green, red = cv2.split(image)

4.2 查找对象轮廓

C++:

    // detect contours using blue channel and without thresholdingvector<vector<Point>> contours1;vector<Vec4i> hierarchy1;findContours(channels[0], contours1, hierarchy1, RETR_TREE, CHAIN_APPROX_NONE);// detect contours using green channel and without thresholdingvector<vector<Point>> contours2;vector<Vec4i> hierarchy2;findContours(channels[1], contours2, hierarchy2, RETR_TREE, CHAIN_APPROX_NONE);// detect contours using red channel and without thresholdingvector<vector<Point>> contours3;vector<Vec4i> hierarchy3;findContours(channels[2], contours3, hierarchy3, RETR_TREE, CHAIN_APPROX_NONE);

Python:

# detect contours using blue channel and without thresholding
contours1, hierarchy1 = cv2.findContours(image=blue, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)# detect contours using green channel and without thresholding
contours2, hierarchy2 = cv2.findContours(image=green, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)# detect contours using red channel and without thresholding
contours3, hierarchy3 = cv2.findContours(image=red, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)

4.3 绘制对象轮廓

C++:

    // draw contours on the original imageMat image_contour_blue = image.clone();drawContours(image_contour_blue, contours1, -1, Scalar(0, 255, 0), 2);imshow("Contour detection using blue channels only", image_contour_blue);// draw contours on the original imageMat image_contour_green = image.clone();drawContours(image_contour_green, contours2, -1, Scalar(0, 255, 0), 2);imshow("Contour detection using green channels only", image_contour_green);// draw contours on the original imageMat image_contour_red = image.clone();drawContours(image_contour_red, contours3, -1, Scalar(0, 255, 0), 2);imshow("Contour detection using red channels only", image_contour_red);

Python:

# draw contours on the original image
image_contour_blue = image.copy()
cv2.drawContours(image=image_contour_blue, contours=contours1, contourIdx=-1, color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
# see the results
cv2.imshow('Contour detection using blue channels only', image_contour_blue)# draw contours on the original image
image_contour_green = image.copy()
cv2.drawContours(image=image_contour_green, contours=contours2, contourIdx=-1, color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
# see the results
cv2.imshow('Contour detection using green channels only', image_contour_green)# draw contours on the original image
image_contour_red = image.copy()
cv2.drawContours(image=image_contour_red, contours=contours3, contourIdx=-1, color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
# see the results
cv2.imshow('Contour detection using red channels only', image_contour_red)

4.4 效果

在下面的图像中,我们可以看到轮廓检测算法不能正确地找到轮廓。这是因为它不能正确地检测对象的边界,而且像素之间的强度差也没有很好地定义。这就是我们更喜欢使用灰度和二进制阈值图像来检测轮廓的原因。

另外,CHAIN_APPROX_SIMPLECHAIN_APPROX_NONE并没有差异,同样无法找到轮廓。

在这里插入图片描述

5. contour_extraction应用

1. 轮廓之间的层次结构表示为父子关系:

  • 1、2、3和4是独立的对象
  • 3a是3个孩子
  • 1、2和4都是父形状,没有任何关联的子形状,因此它们的编号可以是任意的

2. 轮廓层次表示为一个数组,该数组又包含四个值的数组。它表示为:

[Next, Previous, First_Child, Parent]

  • Next:轮廓表示图像中处于相同层级的下一个轮廓。因此,

对于轮廓1,与其处于相同层级的下一个轮廓是2。在这里,Next 将是2。
. 相应地,轮廓3没有与其自身处于相同层级的轮廓。因此,它的 Next 值将是 -1。

  • Previous:轮廓表示相同层级上的上一个轮廓。这意味着轮廓1的上一个值始终为 -1。

  • First_Child:表示我们当前考虑的轮廓的第一个子轮廓。

轮廓1和2根本没有子轮廓。因此,它们的 First_Child 的索引值将为 -1。
但是轮廓3有一个子轮廓。因此,对于轮廓3,First_Child 的位置值将是3a的索引位置。

  • Parent: 表示当前轮廓的父轮廓的索引位置。

轮廓1和2,显而易见地,没有任何父轮廓。
对于轮廓3a,其父轮廓将是轮廓3。
对于轮廓4,父轮廓是轮廓3a。
在这里插入图片描述

目前,有四种不同的轮廓检索技术:

  • RETR_LIST
  • RETR_EXTERNAL
  • RETR_CCOMP
  • RETR_TREE

5.1 RETR_LIST

RETR_LIST 轮廓检索方法不会在提取的轮廓之间创建任何父子关系。因此,对于检测到的所有轮廓区域,First_Child 和 Parent 索引位置值始终为 -1。

LIST: [[[ 1 -1 -1 -1]
[ 2  0 -1 -1]
[ 3  1 -1 -1]
[ 4  2 -1 -1]
[-1  3 -1 -1]]]

C++:

 findContours(thresh2, contours3, hierarchy3, RETR_LIST, CHAIN_APPROX_NONE);

Python:

contours3, hierarchy3 = cv2.findContours(thresh2, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

5.2 RETR_EXTERNAL

RETR_EXTERNAL 轮廓检索方法非常有趣。它只检测父轮廓,并忽略任何子轮廓。因此,所有内部轮廓,如3a和4,将不会在其上绘制任何点。

EXTERNAL: [[[ 1 -1 -1 -1]
[ 2  0 -1 -1]
[-1  1 -1 -1]]]

在这里插入图片描述上述输出图像仅显示在轮廓1、2和3上绘制的点。轮廓3a和4被省略,因为它们是子轮廓。

C++:

 findContours(thresh2, contours4, hierarchy4, RETR_EXTERNAL, CHAIN_APPROX_NONE);

Python:

contours4, hierarchy4 = cv2.findContours(thresh2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

5.3 RETR_CCOMP

与 RETR_EXTERNAL 不同,RETR_CCOMP 检索图像中的所有轮廓。除此之外,它还对图像中所有形状或对象应用了两级层次结构。

CCOMP: [[[ 1 -1 -1 -1]
[ 3  0  2 -1]
[-1 -1 -1  1]
[ 4  1 -1 -1]
[-1  3 -1 -1]]]

在这里插入图片描述上面的图像显示了层次级别为HL-1或HL-2,分别表示级别1和级别2。现在,让我们来看一下代码和输出的层次结构数组。

C++:

  findContours(thresh2, contours5, hierarchy5, RETR_CCOMP, CHAIN_APPROX_NONE);

Python:

contours5, hierarchy5 = cv2.findContours(thresh2, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)

5.4 RETR_TREE

就像 RETR_CCOMP 一样,RETR_TREE 也检索图像中的所有轮廓。它还创建了一个完整的层次结构,其级别不限于1或2。每个轮廓都可以有自己的层次结构,与其所在级别和相应的父子关系一致。

TREE: [[[ 3 -1  1 -1]
[-1 -1  2  0]
[-1 -1 -1  1]
[ 4  0 -1 -1]
[-1  3 -1 -1]]]

在这里插入图片描述从上图可以明确看出:

  • 轮廓1、2和3位于同一级别,即级别0。
  • 轮廓3a位于层次级别1,因为它是轮廓3的子轮廓。
  • 轮廓4是一个新的轮廓区域,所以其层次级别是2。

C++:

  findContours(thresh2, contours6, hierarchy6, RETR_TREE, CHAIN_APPROX_NONE);

Python:

contours6, hierarchy6 = cv2.findContours(thresh2, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

5.5 运行时间比较

注:不同的计算机时间可能有所差异,这里仅仅做一个相对比较。
在这里插入图片描述

  • RETR_LIST 和 RETR_EXTERNAL 执行时间最短,因为 RETR_LIST 不定义任何层次结构,而 RETR_EXTERNAL 仅检索父轮廓。
  • RETR_CCOMP 执行时间次之。它检索所有轮廓并定义了一个两级层次结构。
  • RETR_TREE 执行时间最长,因为它检索所有轮廓,并为每个父子关系定义独立的层次级别。

6. 总结

本文通过findContoursdrawContours来实现在OpenCV下寻找轮廓,在图像上绘制轮廓边界凸显物体的方法。同时,也讨论了关于轮廓之间的父子关系,为后续物体识别奠定一定的基础。

  • findContours(image, contours, hierarchy, mode, method)
  • image: The binary input image obtained in the previous step.
  • mode: This is the contour-retrieval mode.
  • method: This defines the contour-approximation method.
  • drawContours(image, contours, contourIdx, color, thickness, lineType)
  • image: This is the input RGB image on which you want to draw the contour.
  • contours: Indicates the contours obtained from the findContours() function.
  • contourIdx: The pixel coordinates of the contour points are listed in the obtained contours. Using this argument, you can specify the index position from this list, indicating exactly which contour point you want to draw. Providing a negative value will draw all the contour points.
  • color: This indicates the color of the contour points you want to draw. We are drawing the points in green.
  • thickness: This is the thickness of contour points.

7. 参考资料

【1】ubuntu22.04@laptop OpenCV Get Started
【2】ubuntu22.04@laptop OpenCV安装
【3】ubuntu22.04@laptop OpenCV定制化安装

8. 补充

学习是一种过程,对于前面章节学习讨论过的,就不在文中重复了。

有兴趣了解更多的朋友,请从《ubuntu22.04@laptop OpenCV Get Started》开始,一个章节一个章节的了解,循序渐进。

相关文章:

ubuntu22.04@laptop OpenCV Get Started: 013_contour_detection

ubuntu22.04laptop OpenCV Get Started: 013_contour_detection 1. 源由2. 应用Demo2.1 C应用Demo2.2 Python应用Demo 3. contour_approx应用3.1 读取图像并将其转换为灰度格式3.2 应用二进制阈值过滤算法3.3 查找对象轮廓3.4 绘制对象轮廓3.5 效果3.6 CHAIN_APPROX_SIMPLE v.s…...

[ai笔记5] 个人AI资讯助手实战

欢迎来到文思源想的ai空间&#xff0c;这是技术老兵重学ai以及成长思考的第5篇分享&#xff0c;也是把ai场景化应用的第一篇实操内容&#xff01; 既然要充分学习和了解ai&#xff0c;自然少不了要时常看看ai相关资讯&#xff0c;所以今天特地用字节的“扣子”做了一个ai的资讯…...

QT+OSG/osgEarth编译之八十九:osgdb_ply+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5插件库osgdb_ply)

文章目录 一、osgdb_ply介绍二、文件分析三、pro文件四、编译实践一、osgdb_ply介绍 斯坦福三角形格式(Stanford Triangle Format)是一种用于存储三维模型数据的文件格式,也称为 PLY 格式。它最初由斯坦福大学图形实验室开发,用于存储和共享三维扫描和计算机图形数据。 P…...

机器人专题:我国机器人产业园区发展现状、问题、经验及建议

今天分享的是机器人系列深度研究报告&#xff1a;《机器人专题&#xff1a;我国机器人产业园区发展现状、问题、经验及建议》。 &#xff08;报告出品方&#xff1a;赛迪研究院&#xff09; 报告共计&#xff1a;26页 机器人作为推动工业化发展和数字中国建设的重要工具&…...

算法沉淀——哈希算法(leetcode真题剖析)

算法沉淀——哈希算法 01.两数之和02.判定是否互为字符重排03.存在重复元素04.存在重复元素 II05.字母异位词分组 哈希算法&#xff08;Hash Algorithm&#xff09;是一种将任意长度的输入&#xff08;也称为消息&#xff09;映射为固定长度的输出的算法。这个输出通常称为哈希…...

深入理解Redis哨兵原理

哨兵模式介绍 在深入理解Redis主从架构中Redis 的主从架构中&#xff0c;由于主从模式是读写分离的&#xff0c;如果主节点&#xff08;master&#xff09;挂了&#xff0c;那么将没有主节点来服务客户端的写操作请求&#xff0c;也没有主节点给从节点&#xff08;slave&#…...

MySQL-存储过程(PROCEDURE)

文章目录 1. 什么是存储过程&#xff1f;2. 存储过程的优点3. MySQL中的变量3.1 系统变量3.2 用户自定义变量3.3 局部变量 4. 存储过程的相关语法4.1 创建存储过程&#xff08;CREATE&#xff09;4.2 查看存储过程&#xff08;SHOW&#xff09;4.3 修改存储过程&#xff08;ALT…...

linux系统监控工具prometheus的安装以及监控mysql

prometheus 安装服务端客户端监控mysql prometheus浏览器查看 安装 https://prometheus.io/download/下载客户端和服务端以及需要监控的所有的包服务端 官网下载下载prometheustar -xf prometheus-2.47.2.linux-amd64.tar.gz -C /usr/local/ cd /usr/local/ mv prometheus-2.…...

初识tensorflow程序设计模式

文章目录 建立计算图tensorflow placeholdertensorflow数值运算常用的方法 tensorboard启动tensorboard的方法 建立一维与二维张量建立一维张量建立二维张量建立新的二维张量 矩阵的基本运算矩阵的加法矩阵乘法与加法 github地址https://github.com/fz861062923/TensorFlow 建…...

【QT+QGIS跨平台编译】之三十八:【GDAL+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、gdal介绍二、文件下载三、文件分析四、pro文件五、编译实践一、gdal介绍 GDAL(Geospatial Data Abstraction Library)是一个用于读取、写入和处理地理空间数据的开源库。它支持多种栅格和矢量地理空间数据格式,包括常见的GeoTIFF、Shapefile、NetCDF、HDF5等,…...

黑马鸿蒙教程学习1:Helloworld

今年打算粗略学习下鸿蒙开发&#xff0c;当作兴趣爱好&#xff0c;通过下华为那个鸿蒙开发认证&#xff0c; 发现黑马的课程不错&#xff0c;有视频和完整的代码和课件下载&#xff0c;装个devstudio就行了&#xff0c;建议32G内存。 今年的确是鸿蒙大爆发的一年呀&#xff0c;…...

蓝桥杯每日一题------背包问题(四)

前言 前面讲的都是背包的基础问题&#xff0c;这一节我们进行背包问题的实战&#xff0c;题目来源于一位朋友的询问&#xff0c;其实在这之前很少有题目是我自己独立做的&#xff0c;我一般习惯于先看题解&#xff0c;验证了题解提供的代码是正确的后&#xff0c;再去研究题解…...

OpenAI发布Sora技术报告深度解读!真的太强了!

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;洲与AI。 &#x1f388; 本文专栏&#xff1a;本文收录…...

AJAX——接口文档

1 接口文档 接口文档&#xff1a;描述接口的文章 接口&#xff1a;使用AJAX和服务器通讯时&#xff0c;使用的URL&#xff0c;请求方法&#xff0c;以及参数 传送门&#xff1a;AJAX阶段接口文档 <!DOCTYPE html> <html lang"en"><head><meta c…...

leetcode hot100不同路径

本题可以采用动态规划来解决。还是按照五部曲来做 确定dp数组&#xff1a;dp[i][j]表示走到&#xff08;i&#xff0c;j&#xff09;有多少种路径 确定递推公式&#xff1a;我们这里&#xff0c;只有两个移动方向&#xff0c;比如说我移动到&#xff08;i&#xff0c;j&#x…...

【前端工程化面试题目】webpack 的热更新原理

可以在顺便学习一下 vite 的热更新原理&#xff0c;请参考这篇文章。 首先有几个知识点需要明确 热更新是针对开发过程中的开发服务器的&#xff0c;也就是 webpack-dev-serverwebpack 的热更新不需要额外的插件&#xff0c;但是需要在配置文件中 devServer属性中配置&#x…...

不花一分钱,在 Mac 上跑 Windows(M1/M2 版)

这是在 MacOS M1 上体验最新 Windows11 的效果&#xff1a; VMware Fusion&#xff0c;可以运行 Windows、Linux 系统&#xff0c;个人使用 licence 免费 安装流程见 &#x1f449; https://zhuanlan.zhihu.com/p/452412091 从申请 Fusion licence 到下载镜像&#xff0c;再到…...

Attempt to call an undefined function glutInit

Attempt to call an undefined function glutInit 解决方法&#xff1a; 从这里下载PyOpenGL 的whl安装文件&#xff0c; https://drive.google.com/drive/folders/1mz7faVsrp0e6IKCQh8MyZh-BcCqEGPwx 安装命令举栗 pip install PyOpenGL-3.1.7-cp39-cp39-win_amd64.whl pi…...

AB测试最小样本量

1.AB实验过程 常见的AB实验过程&#xff0c;分流-->实验-->数据分析-->决策&#xff1a;分流&#xff1a;用户被随机均匀的分为不同的组实验&#xff1a;同一组内的用户在实验期间使用相同的策略&#xff0c;不同组的用户使用相同或不同的策略。数据收集&#xff1a;…...

在Spring中事务失效的场景

在Spring框架中&#xff0c;事务管理是通过AOP&#xff08;面向切面编程&#xff09;实现的&#xff0c;主要依赖于Transactional注解。然而&#xff0c;在某些情况下&#xff0c;事务可能会失效。以下是一些可能导致Spring事务失效的常见场景&#xff1a; 非public方法&#…...

Rust 学习笔记 - 变量声明与使用

前言 任何一门编程语言几乎都脱离不了&#xff1a;变量、基本类型、函数、注释、循环、条件判断&#xff0c;这是一门编程语言的语法基础&#xff0c;只有当掌握这些基础语法及概念才能更好的学习 Rust。 变量介绍 Rust 是一种强类型语言&#xff0c;但在声明变量时&#xf…...

windows 下跑起大模型(llama)操作笔记

原贴地址&#xff1a;https://testerhome.com/topics/39091 前言 国内访问 chatgpt 太麻烦了&#xff0c;还是本地自己搭一个比较快&#xff0c;也方便后续修改微调啥的。 之前 llama 刚出来的时候在 mac 上试了下&#xff0c;也在 windows 上用 conda 折腾过&#xff0c;环…...

人工智能专题:基础设施行业智能化的基础设施,自智网络双价值分析

今天分享的是人工智能系列深度研究报告&#xff1a;《人工智能专题&#xff1a;基础设施行业智能化的基础设施&#xff0c;自智网络双价值分析》。 &#xff08;报告出品方&#xff1a;埃森哲&#xff09; 报告共计&#xff1a;32页 自智网络驱动的电信产业变革 经过多年的…...

docker 编译安装redis脚本

在Docker中编译安装Redis通常不是一个常见的做法&#xff0c;因为Redis官方提供了预编译的Docker镜像&#xff0c;这些镜像包含了已经编译好的Redis二进制文件。不过&#xff0c;如果你有特殊需求&#xff0c;想要自己从源代码编译Redis并打包成Docker镜像&#xff0c;你可以使…...

鸿蒙开发系列教程(二十三)--List 列表操作(2)

列表样式 1、设置内容间距 在列表项之间添加间距&#xff0c;可以使用space参数&#xff0c;主轴方向 List({ space: 10 }) { … } 2、添加分隔线 分隔线用来将界面元素隔开&#xff0c;使单个元素更加容易识别。 startMargin和endMargin属性分别用于设置分隔线距离列表侧…...

C#根据权重抽取随机数

&#xff08;游戏中一个很常见的简单功能&#xff0c;比如抽卡抽奖抽道具&#xff0c;或者一个怪物有多种攻击动作&#xff0c;按不同的权重随机出个攻击动作等等……&#xff09; 假如有三种物品 A、B、C&#xff0c;对应的权重分别是A&#xff08;50&#xff09;&#xff0c…...

SORA:OpenAI最新文本驱动视频生成大模型技术报告解读

Video generation models as world simulators&#xff1a;作为世界模拟器的视频生成模型 1、概览2、Turning visual data into patches&#xff1a;将视觉数据转换为补丁3、Video compression network&#xff1a;视频压缩网络4、Spacetime Latent Patches&#xff1a;时空潜在…...

阿里云第七代云服务器ECS计算c7、通用g7和内存r7配置如何选择?

阿里云服务器配置怎么选择合适&#xff1f;CPU内存、公网带宽和ECS实例规格怎么选择合适&#xff1f;阿里云服务器网aliyunfuwuqi.com建议根据实际使用场景选择&#xff0c;例如企业网站后台、自建数据库、企业OA、ERP等办公系统、线下IDC直接映射、高性能计算和大游戏并发&…...

视觉slam十四讲学习笔记(六)视觉里程计 1

本文关注基于特征点方式的视觉里程计算法。将介绍什么是特征点&#xff0c;如何提取和匹配特征点&#xff0c;以及如何根据配对的特征点估计相机运动。 目录 前言 一、特征点法 1 特征点 2 ORB 特征 FAST 关键点 BRIEF 描述子 3 特征匹配 二、实践&#xff1a;特征提取…...

PyTorch-线性回归

已经进入大模微调的时代&#xff0c;但是学习pytorch&#xff0c;对后续学习rasa框架有一定帮助吧。 <!-- 给出一系列的点作为线性回归的数据&#xff0c;使用numpy来存储这些点。 --> x_train np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168],[9.779], [6.1…...

C++数据结构与算法——栈与队列

C第二阶段——数据结构和算法&#xff0c;之前学过一点点数据结构&#xff0c;当时是基于Python来学习的&#xff0c;现在基于C查漏补缺&#xff0c;尤其是树的部分。这一部分计划一个月&#xff0c;主要利用代码随想录来学习&#xff0c;刷题使用力扣网站&#xff0c;不定时更…...

掌上新闻随心播控,HarmonyOS SDK助力新浪新闻打造精致易用的资讯服务新体验

原生智能是HarmonyOS NEXT的核心亮点之一&#xff0c;依托HarmonyOS SDK丰富全面的开放能力&#xff0c;开发者只需通过几行代码&#xff0c;即可快速实现AI功能。新浪新闻作为鸿蒙原生应用开发的先行者之一&#xff0c;从有声资讯入手&#xff0c;将基于Speech Kit朗读控件上线…...

2024年危险化学品经营单位主要负责人证模拟考试题库及危险化学品经营单位主要负责人理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年危险化学品经营单位主要负责人证模拟考试题库及危险化学品经营单位主要负责人理论考试试题是由安全生产模拟考试一点通提供&#xff0c;危险化学品经营单位主要负责人证模拟考试题库是根据危险化学品经营单位主…...

C/C++如何把指针所指向的指针设为空指针?

实践出真知&#xff0c;指针对于初学的友友来说&#xff0c;头都要大了。喵喵一直遵循在实践中学&#xff0c;在学习中实践&#xff0c;相信你也会有所得&#xff01; 以下是该问题的解决方案&#xff1a; int** ptrPtr new int*; // 创建指向指针的指针 int* ptr new int;…...

第三节:基于 InternLM 和 LangChain 搭建你的知识库(课程笔记)

视频链接&#xff1a;https://www.bilibili.com/video/BV1sT4y1p71V/?vd_source3bbd0d74033e31cbca9ee35e111ed3d1 文档地址&#xff1a; https://github.com/InternLM/tutorial/tree/main/langchain 课程笔记&#xff1a; 1.仅仅包含训练时间点之前的数据&#xff0c;无法…...

qt-C++笔记之打印所有发生的事件

qt-C笔记之打印所有发生的事件 code review! 文章目录 qt-C笔记之打印所有发生的事件1.ChatGPT问答使用 QApplication 的 notify 方法使用 QObject 的 event 方法 2.使用 QObject 的 event 方法3.使用 QApplication 的 notify 方法 1.ChatGPT问答 在Qt C中&#xff0c;若要打…...

pytorch 实现线性回归(深度学习)

一 查看原始函数 初始化 %matplotlib inline import random import torch from d2l import torch as d2l 1.1 生成原始数据 def synthetic_data(w, b, num_examples):x torch.normal(0, 1, (num_examples, len(w)))y torch.matmul(x, w) bprint(x:, x)print(y:, y)y tor…...

[Doris] Doris的安装和部署 (二)

文章目录 1.安装要求1.1 Linux操作系统要求1.2 软件需求1.3 注意事项1.4 内部端口 2.集群部署2.1 操作系统安装要求2.2 下载安装包2.3 解压2.4 配置FE2.5 配置BE2.6 添加BE2.7 FE 扩容和缩容2.8 Doris 集群群起脚本 3.图形化 1.安装要求 1.1 Linux操作系统要求 1.2 软件需求 1…...

【QT+QGIS跨平台编译】之三十五:【cairo+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、cairo介绍二、文件下载三、文件分析四、pro文件五、编译实践一、cairo介绍 Cairo是一个功能强大的开源2D图形库,它提供了一套跨平台的API,用于绘制矢量图形和文本。Cairo支持多种输出目标,包括屏幕、图像文件、PDF、SVG等。 Cairo的设计目标是简单易用、高效…...

MySQL(基础)

第01章_数据库概述 1. 为什么要使用数据库 持久化(persistence)&#xff1a;把数据保存到可掉电式存储设备中以供之后使用。大多数情况下&#xff0c;特别是企业级应用&#xff0c;数据持久化意味着将内存中的数据保存到硬盘上加以”固化”&#xff0c;而持久化的实现过程大多…...

STM32F1 - 中断系统

Interrupt 1> 硬件框图2> NVIC 中断管理3> EXTI 中断管理3.1> EXTI与NVIC3.2> EXTI内部框图 4> 外部中断实验4.1> 实验概述4.2> 程序设计 5> 中断向量表6> 总结 1> 硬件框图 NVIC&#xff1a;Nested Vectored Interrupt Controller【嵌套向量…...

【Linux系统化学习】缓冲区

目录 缓冲区 一个样例 现象解释 缓冲区存在的位置 缓冲区 在刚开始学习C语言的时候我们就听过缓冲区这个名词&#xff0c;很是晦涩难懂&#xff1b;在Linux下进程退出时也包含缓冲区&#xff0c;因此缓冲区到底是什么&#xff1f;有什么作用&#xff1f; 让我们先从一个小…...

基于BP算法的SAR成像matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 BP算法的基本原理 4.2 BP算法的优点与局限性 5.完整工程文件 1.课题概述 基于BP算法的SAR成像。合成孔径雷达&#xff08;SAR&#xff09;是一种高分辨率的雷达系统&#xff0c;能够在各种天气和光…...

【C++ STL】你真的了解string吗?浅谈string的底层实现

文章目录 底层结构概述扩容机制浅拷贝与深拷贝插入和删除的效率浅谈VS和g的优化总结 底层结构概述 string可以帮助我们很好地管理字符串&#xff0c;但是你真的了解她吗&#xff1f;事实上&#xff0c;string的设计是非常复杂的&#xff0c;拥有上百个接口&#xff0c;但最常用…...

17.3.1.3 灰度

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 灰度的算法主要有以下三种&#xff1a; 1、最大值法: 原图像&#xff1a;颜色值color&#xff08;R&#xff0c;G&#xff0c;B&a…...

基于CAS操作的atomic原子类型

在上一节的卖票程序中&#xff0c;我们讲解了如何在多线程中保证临界资源的正确访问——使用互斥锁&#xff0c;即 lock_guard<mutex> lock(mtx); count;lock_guard<mutex> lock(mtx); count--; 从汇编角度解释线程间互斥-mutex互斥锁与lock_guard的使用-CSDN博客…...

Rust HashMap详解及单词统计示例

在Rust中&#xff0c;HashMap是一种非常有用的数据结构&#xff0c;用于存储键值对。本文将深入介绍HashMap的特性&#xff0c;以及通过一个单词统计的例子展示其用法。 HashMap简介 HashMap是Rust标准库提供的用于存储键值对的数据结构。它允许通过键快速查找对应的值&#…...

命令执行讲解和函数

命令执行漏洞简介 命令执行漏洞产生原因 应用未对用户输入做严格得检查过滤&#xff0c;导致用户输入得参数被当成命令来执行 命令执行漏洞的危害 1.继承Web服务程序的权限去执行系统命会或读写文件 2.反弹shell&#xff0c;获得目标服务器的权限 3.进一步内网渗透 远程代…...

外包实在是太坑了,划水三年,感觉人都废了

先说一下自己的情况&#xff0c;专科生&#xff0c;19年通过校招进入杭州某个外包软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了3年的功…...

代码随想录算法训练营第19天

77. 组合 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 class Solution:def combine(self, n: int, k: int) -> List[List[int]]:path []res []def dfs(n,k,index):if len(path) k:res.append(path[:])returnfor i in range(index,n1):…...