【OpenCV】入门教学

news2025/2/21 5:14:37

🏠大家好,我是Yui_💬
🍑如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
🚀如有不懂,可以随时向我提问,我会全力讲解~
🔥如果感觉博主的文章还不错的话,希望大家关注、点赞、收藏三连支持一下博主哦~!
🔥你们的支持是我创作的动力!
🧸我相信现在的努力的艰辛,都是为以后的美好最好的见证!
🧸人的心态决定姿态!
💬欢迎讨论:如有疑问或见解,欢迎在评论区留言互动。
👍点赞、收藏与分享:如觉得这篇文章对您有帮助,请点赞、收藏并分享!
🚀分享给更多人:欢迎分享给更多对编程感兴趣的朋友,一起学习!

本文是基于哔哩哔哩OpenCV入门课程的内容加上我个人的理解而来。
本篇文章的主要内容:
阅读本篇文章,你需要具备python的基本语法的学习。如果你并没有学习过python,可以去看我的python专栏:python

本文的内容:图片的读取,RGB彩色通道,区域裁剪,绘制图像1和文字,均值滤波,特征提取,模板匹配,梯度算法,阈值算法,形态学操作,摄像头的读取。

文章目录

  • 1. 背景
  • 2. 安装OpenCV库
  • 3. Hello World示例
  • 4.图像的彩色通道
  • 5. 图像的裁剪
  • 6.绘制功能
    • `np.zeros`函数
    • `cv2.rectangle`函数
    • `cv2.rectangle`函数
    • `cv2.circle`函数
    • `cv2.putText`函数
  • 7. 均值滤波
    • `cv2.GaussianBlur`函数
    • `cv2.medianBlur`函数
  • 8.图像特征提取
    • `cv2.goodFeaturesToTrack`函数
  • 9. 模板匹配
    • `cv2.matchTemplate`函数
    • `np.where`函数
  • 10. 图像梯度算法
    • 10.1 `cv2.Laplacian`函数
    • 10.2 `cv2.Canny`函数
  • 11.阈值算法
    • 11.1 `cv2.threshold`函数
      • 11.1.1 `cv2.THRESH_BINARY`
      • 11.1.2 `cv2.THRESH_BINARY + cv2.THRESH_OTSU`
    • 11.2 `cv2.adaptiveThreshold`函数
  • 12. 腐蚀与膨胀
    • 12.1 `np.ones`函数
    • 12.2 `cv2.erode`函数
    • 12.3 `cv2.dilate`函数
  • 13.调用摄像头
  • 14. 总结

1. 背景

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,最初由英特尔于1999年发布,现已成为计算机视觉领域的一个重要工具。它以C++为核心语言开发,并提供了多种语言的绑定,包括Python、Java、C等,适用于多种操作系统,如Windows、Linux和macOS。

2. 安装OpenCV库

在Windows终端输入:

pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple

这是用清华的镜像源,下载起来会快很多。
验证是否下载成功:
打开编辑器,查看安装OpenCV的版本

import cv2
print(cv2.__version__)

在这里插入图片描述

我的版本是4.10.0


本片文章,将用到四张图片,图中的4张图片。
在这里插入图片描述

3. Hello World示例

import cv2

image = cv2.imread("opencv_logo.jpg")
print(image.shape)#打印维度

读取的图片数据会存储在image变量里,且为一个numpy数组类型。

打印结果
(250, 250, 3)

其中,(250,250)分别位图片像素的横行和纵列,最后一个3为,图片的3原色彩色通道。
打开画图板验证:
在这里插入图片描述

得到结果确实如此。
下面我们把读取到的图片打印到显示屏当中。

import cv2

image = cv2.imread("opencv_logo.jpg")
print(image.shape)

cv2.imshow("Image", image)
cv2.waitKey()

在这里插入图片描述

cv2.imshow('Image',image),用于在一个新窗口显示图像,第一个参数是窗口的名称,第二个参数是要显示的图像。
cv2.waitKey()等待用户输入任意键,确保图像窗口不会立即关闭。

4.图像的彩色通道

在数字图像处理中,彩色图像通常由三个颜色通道组成:红色(Red)、绿色(Green)和蓝色(Blue),这三个通道也被称为RGB通道。每个通道代表图像在该颜色上的强度分布。
在OpenCV中,图像是以BGR格式存储的,而不是常见的RGB格式。这意味着第一个通道是蓝色,第二个通道是绿色,第三个通道是红色。
对于OpenCV来说,存储一张彩色图片等同于存储3张灰度图片,它们被存储在OpenCV图像数据的第3个维度上,灰度范围是0-255。当显示器需要渲染一张图片时,计算机会依次取出图像数据中的3张灰度图在把它们分别投影到显示器的蓝色、绿色和红色的led芯片上。
下面开始让显示屏上显示这3张灰度图以及原图:

import cv2

# 读取图像
image = cv2.imread("opencv_logo.jpg")


# 显示原始图像和各个通道
cv2.imshow("Original Image", image)
cv2.imshow("Blue Channel", image[:, :, 0])
cv2.imshow("Green Channel", image[:, :, 1])
cv2.imshow("Red Channel", image[:, :, 2])

# 等待按键,然后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

OpenCV同时还提供一种彩色图像的灰度变换算法,可以把3个彩色通道的图像做平方和加权平均。

import cv2

# 读取图像
image = cv2.imread("opencv_logo.jpg")


# 显示原始图像和各个通道
cv2.imshow("Blue Channel", image[:, :, 0])
cv2.imshow("Green Channel", image[:, :, 1])
cv2.imshow("Red Channel", image[:, :, 2])
#显示灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray", gray)

# 等待按键,然后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

可以看到gray是BGR3原色的平均,而且它也描述了图案的明暗分布,在计算机视觉邻域我们通常把这个变换后的图像gray称为称为灰度图。
大量的图像算法都是基于灰度图来操作的

5. 图像的裁剪

import cv2

image = cv2.imread("opencv_logo.jpg")

crop = image[10:170,40:200]

cv2.imshow("Crop", crop)
cv2.waitKey(0)

运行代码
在这里插入图片描述

可以看到,部分代码被提取出来了。
下面我将打开,Windows中的画图来进行讲解:
对于OpenCV索引的顺序是先横行后纵列
在这里插入图片描述

也就是说:索引10:170对应的是第10横行到第170横行,对应的40:200就是第40纵列到第200纵列。这个索引顺序可能与某些图像处理工具是不同的,比如加州理工大学基于MATLAB的图像处理包为相反顺序。

6.绘制功能

本次代码需要引入numpy工具包,实际上opencv的图像数据是numpy数组数据结构。

import cv2
import numpy as np

image = np.zeros([300,300,3],dtype=np.uint8)#利用numpy创建一个黑色画布

cv2.line(image,(100,200),(250,250),(255,0,0),2)
cv2.rectangle(image,(30,100),(60,150),(0,255,0),2)
cv2.circle(image,(150,100),20,(0,0,255),3)
cv2.putText(image,"Hello World",(100,50),0,1,(255,255,255),2,1)

cv2.imshow("Image",image)
cv2.waitKey(0)

在这里插入图片描述

下面我会开始介绍代码中出现的函数。

np.zeros函数

np.zeros([300,300,3],dtype=np.uint8)
创建一个300*300像素的黑色画布,并初始化所有像素值为0(也就是黑色)。

  • np.zeros:NumPy库中的一个函数,用于创建一个指定形状和数据类型的全零数组。
  • [300,300,3]:这是数组的形状。这里表示一个300x300像素的图像,每个像素有3个通道(BGR颜色通道)。
  • dtype=np.uint8:指定数组的数据类型为无符号8位整数(unsigned 8-bit integer),这是图像处理中常用的数据类型,因为每个像素的BGR值通常在0到255之间。

cv2.rectangle函数

cv2.rectangle(image,(30,100),(60,150),(0,255,0),2)
cv2.line 是 OpenCV 库中的一个函数,用于在图像上绘制一条直线。

  • image:要在其上绘制直线的图像。
  • (100, 200):直线的起点坐标。
  • (250, 250):直线的终点坐标。
  • (255, 0, 0):直线的颜色,这里是蓝色。
  • 2:直线的粗细。

cv2.rectangle函数

cv2.rectangle(image,(30,100),(60,150),(0,255,0),2)
cv2.rectangle 是 OpenCV 库中的一个函数,用于在图像上绘制一个矩形

  • image:要在其上绘制矩形的图像。
  • (30, 100):矩形左上角的坐标。
  • (60, 150):矩形右下角的坐标。
  • (0, 255, 0):矩形的颜色,这里是绿色。
  • 2:矩形边框的粗细。

cv2.circle函数

cv2.circle 是 OpenCV 库中的一个函数,用于在图像上绘制一个圆形。
cv2.circle(image,(150,100),20,(0,0,255),3)

  • image:要在其上绘制圆形的图像。
  • (150, 100):圆心的坐标。
  • 20:圆的半径。
  • (0, 0, 255):圆的颜色,这里是红色。
  • 3:圆边框的粗细。

cv2.putText函数

cv2.putText 是 OpenCV 库中的一个函数,用于在图像上绘制文本。
cv2.putText(image,"Hello World",(100,50),0,1,(255,255,255),2,1)

  • image:要在其上绘制文本的图像。
  • "Hello World":要绘制的文本内容。
  • (100, 50):文本左下角的坐标。
  • cv2.FONT_HERSHEY_SIMPLEX:字体类型。
  • 1:字体比例因子。
  • (255, 255, 255):文本的颜色,这里是白色。
  • 2:文本线条的粗细。
  • cv2.LINE_AA:文本线条的类型,抗锯齿线。

7. 均值滤波

本次代码会使用的到飞机素材。
在这里插入图片描述

该图片是一张噪点十分多的图片,下面我会用滤波器对其进行处理。

import cv2

image = cv2.imread('plane.jpg')

gauss = cv2.GaussianBlur(image, (5, 5), 0)#高斯滤波
median = cv2.medianBlur(image, 5)#均值滤波
cv2.imshow('Original', image)
cv2.imshow('Gaussian Blur', gauss)
cv2.imshow('Median Blur', median)

cv2.waitKey(0)  

在这里插入图片描述

可以看到无论是高斯滤波器还是均值滤波器都使得图片的噪点噪点减少,不过也破坏了些图像细节。
实际的处理中,我们很难遇到噪点这么严重的图片,更多情况下,我们会遇到干净背景中的少数几个噪点,使用均值滤波把它消除。

cv2.GaussianBlur函数

cv2.GaussianBlur 是 OpenCV 库中的一个函数,用于对图像应用高斯模糊。
cv2.GaussianBlur(image, (5, 5), 0)

  • image:输入图像。
  • (5, 5):高斯核的大小,表示核的宽度和高度均为 5。
  • 0:高斯核在 X 方向上的标准差,设为 0 表示自动计算。

cv2.medianBlur函数

cv2.medianBlur 是 OpenCV 库中的一个函数,用于对图像应用中值滤波(Median Blur)。中值滤波是一种非线性滤波方法,它通过将每个像素的值替换为其邻域内像素值的中值来工作。这种方法对于去除椒盐噪声(salt-and-pepper noise)特别有效。
cv2.medianBlur(image, 5)

  • image:输入图像。
  • 5:滤波器的大小,表示邻域的大小为 5×55×5。

8.图像特征提取

import cv2

image = cv2.imread('opencv_logo.jpg')

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

corners = cv2.goodFeaturesToTrack(gray, 500, 0.1, 10)
for corner in corners:
    x,y = corner.ravel()#是 NumPy 数组的一个方法,用于将多维数组展平成一维数组。
    cv2.circle(image,(int(x),int(y)),3,(255,0,255),-1)

cv2.imshow('Corners', image)
cv2.waitKey(0)

在这里插入图片描述

我们看到识别出来的特征都是图案的转角,转交是最简单的图像特征,提取转角的算法都是非常高效的。

cv2.goodFeaturesToTrack函数

cv2.goodFeaturesToTrack(gray, 500, 0.1, 10)

  • gray:需要检测角点的灰度图像。
  • 500:最大角点数,即函数最多会返回500个角点。
  • 0.1:质量等级,表示角点的最小可接受质量。该值越小,检测到的角点越多,但质量可能较低。
  • 10:最小距离,表示检测到的任意两个角点之间的最小像素距离。该值越大,检测到的角点越分散。
    函数返回一个包含检测到的角点的数组,每个角点由其坐标(x, y)表示。

9. 模板匹配

模板匹配我们会用到扑克那张图片,来匹配扑克中的菱形。

import cv2
import numpy as np

image = cv2.imread("poker.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

template = gray[75:105, 235:265] #该区域刚好包含一个菱形

match = cv2.matchTemplate(gray, template, cv2.TM_CCOEFF_NORMED)
locations = np.where(match >= 0.9)#找出匹配系数大于0.9的匹配点

w, h = template.shape[0:2] #求出模板的长和宽,方便后续标记图片。
for p in zip(*locations[::-1]):
    x1, y1 = p[0], p[1]
    x2, y2 = x1 + w, y1 + h
    cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)

cv2.imshow("image", image)
cv2.waitKey()

在这里插入图片描述

我们这里使用的匹配算法是大小敏感的,如果想要把图片中的菱形都匹配出来,可以放到缩小图像多次来匹配。

cv2.matchTemplate函数

cv2.matchTemplate函数在提供的代码中用于在灰度图像gray中查找与模板template最匹配的区域.

  • cv2.matchTemplate函数会在输入图像(gray)中滑动模板(template)
  • 并计算每个位置与模板的匹配程度,返回一个匹配程度的矩阵
  • cv2.TM_CCOEFF_NORMED是一种匹配方法,它通过归一化相关系数来衡量匹配程度

np.where函数

np.where(match >= 0.9) 是 NumPy 库中的一个函数调用,用于根据条件 match >= 0.9 查找数组 match 中满足条件的元素的索引

  • match:这是一个二维数组,由 cv2.matchTemplate 函数返回,表示输入图像中每个位置与模板的匹配程度。
  • match >= 0.9:这是一个布尔数组,表示 match 中每个元素是否大于等于 0.9。
  • np.where(match >= 0.9):这个函数调用返回一个元组,包含两个数组,分别表示满足条件的元素的行索引和列索引。

10. 图像梯度算法

我们前面学的特征点提取与图像匹配这些算法的背后都使用的图像梯度。
图像梯度就是图像的明暗变化,比如我们可以分别计算沿水平和垂直方向的明暗变化,再其这俩个变化的平方和就得到了梯度,它和地理上的梯度是一样的,只不过地面的高低起伏变成了图像的明暗变化。

import cv2

gray = cv2.imread("opencv_logo.jpg", cv2.IMREAD_GRAYSCALE)

laplacian = cv2.Laplacian(gray, cv2.CV_64F)#拉普拉斯算子
canny = cv2.Canny(gray, 100, 200)

cv2.imshow("gray", gray)
cv2.imshow("laplacian", laplacian)
cv2.imshow("canny", canny)

cv2.waitKey()

在这里插入图片描述

拉普拉斯算子给出了图像明暗变化的趋势,比如均一的背景区域变成了黑色,有明暗变化的部分,比如边缘就变成了白色,我们知道一个几何图形的变化往往有剧烈的明暗变化,所以梯度算法也常常用于检测边缘。
conny边缘检测,在conny算法中我们使用一个梯度区间来定义边缘,比如梯度区间100到200,如果某个像素的梯度大于200,那么可以确定它是一个边缘,因为它周围的明暗变化足够强烈。反过来,如果梯度小于100,那么可以确定它不是一个边缘,因为他周围没有明暗变化,如果梯度在100到200之间,那么就要看这个像素是否和已知的边缘像素相连,如果和某个已知的边缘像素连载一起,那么我们判定它是边缘,否则不是。
这个过程有点像扫雷,先确定一些显而易见的像素,剩下的像素由确定好的像素来辅助判断。
![[Pasted image 20250127213341.png]]在这里插入图片描述

10.1 cv2.Laplacian函数

Laplacian 算子是图像处理中的一种二阶微分算子,用于检测图像中的边缘。 它通过计算图像灰度值的二阶导数来确定边缘的位置。 在 OpenCV 中,cv2.Laplacian 函数用于计算图像的 Laplacian 变换。
Laplacian 算子的工作原理是:

  1. 计算图像中每个像素点的二阶导数。
  2. 二阶导数的正值表示图像在该点的亮度从暗到亮的变化,负值表示从亮到暗的变化。
  3. 边缘通常发生在二阶导数的绝对值较大的地方。
    cv2.Laplacian(gray, cv2.CV_64F)
  • gray: 输入的灰度图像。
  • cv2.CV_64F: 指定输出图像的深度,这里是 64 位浮点型。

10.2 cv2.Canny函数

cv2.Canny 是 OpenCV 中用于边缘检测的函数,它实现了 Canny 边缘检测算法。Canny 边缘检测是一种多阶段的算法,旨在检测图像中的边缘,并尽量减少噪声和虚假边缘的数量。
Canny 边缘检测算法通常包括以下步骤:

  1. 高斯滤波:首先,图像通过高斯滤波器进行平滑处理,以减少噪声。
  2. 梯度计算:然后,计算图像的梯度强度和方向,通常使用 Sobel 算子。
  3. 非极大值抑制:在梯度方向上进行非极大值抑制,以细化边缘。
  4. 双阈值检测:使用两个阈值(低阈值和高阈值)来确定哪些边缘是强边缘,哪些是弱边缘。
  5. 边缘跟踪:通过连接强边缘和与其相连的弱边缘来形成最终的边缘图。
    cv2.Canny(gray, 100, 200)
  • gray:输入的灰度图像。Canny 算法通常在灰度图像上执行,因为彩色图像中的颜色信息对于边缘检测不是必需的,并且可能会引入额外的复杂性。
  • 100:这是 Canny 算子的低阈值。低于此阈值的边缘将被忽略。
  • 200:这是 Canny 算子的高阈值。高于此阈值的边缘将被视为强边缘,并且可能会触发与其相连的弱边缘的检测。

11.阈值算法

阈值算法也叫二值化算法,它把灰度图像分为黑与白。
阈值的阈是门槛的意思,通俗的讲,门槛下面是黑色,门槛上面是白色,我们常说世界是复杂的,充满灰色地带,但是在阈值算法的观点中,世界是简单的,非黑即白。

import cv2

gray = cv2.imread("bookpage.jpg", cv2.IMREAD_GRAYSCALE)
ret, binary = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
binary_adaptive = cv2.adaptiveThreshold(
    gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)
ret1, binary_otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

cv2.imshow("gray", gray)
cv2.imshow("binary", binary)
cv2.imshow("adaptive", binary_adaptive)
cv2.imshow("otsu", binary_otsu)

cv2.waitKey()

在这里插入图片描述

11.1 cv2.threshold函数

cv2.threshold 是 OpenCV 中用于图像二值化的函数。它将输入图像转换为二值图像,根据指定的阈值将像素分为两类:前景和背景。
工作原理

  1. 固定阈值cv2.threshold 使用一个固定的阈值来分割图像。在这个例子中,阈值被设置为10。
  2. 二值化:所有灰度值大于10的像素将被设置为255(白色),而所有灰度值小于或等于10的像素将被设置为0(黑色)。

11.1.1 cv2.THRESH_BINARY

cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)

  • gray:输入的灰度图像。
  • 10:这是阈值。所有大于这个值的像素将被设置为最大值(通常是255),而所有小于或等于这个值的像素将被设置为0。
  • 255:这是最大值,用于设置前景像素的值。
  • cv2.THRESH_BINARY:这是阈值类型。在这种情况下,它表示如果像素值大于阈值,则将其设置为最大值,否则设置为0。

11.1.2 cv2.THRESH_BINARY + cv2.THRESH_OTSU

Otsu 方法(也称为大津法)是一种自动确定图像二值化阈值的算法。它适用于双峰图像(即图像的直方图有两个峰值),并且能够有效地处理光照不均匀的情况。Otsu 方法通过最大化类间方差来选择最佳阈值,从而将图像分为前景和背景两部分。

  • gray:输入的灰度图像。
  • 0:这里的阈值参数设置为0,意味着不使用固定阈值,而是让算法自动计算阈值。
  • 255:这是最大值,用于设置前景像素的值。
  • cv2.THRESH_BINARY + cv2.THRESH_OTSU:这是阈值类型。cv2.THRESH_BINARY 表示二值化类型,而 cv2.THRESH_OTSU 是一个标志位,表示使用 Otsu 方法来自动计算阈值。

11.2 cv2.adaptiveThreshold函数

cv2.adaptiveThreshold 是 OpenCV 中的一个函数,用于根据图像的小区域计算阈值,以实现自适应的二值化。这种方法特别适合于光照不均匀的图像,因为它会在不同的局部区域内分别计算阈值。
工作原理

  1. 局部阈值计算:对于图像中的每个像素,函数会考虑其周围的一个小区域(由邻域大小决定),并计算该区域的加权平均值(或加权中值)。
  2. 二值化:然后,将这个局部阈值与像素的实际值进行比较。如果像素值大于局部阈值减去常数 C,则将该像素设置为最大值,否则设置为0。
    cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)
  • gray:输入的灰度图像。
  • 255:这是用于设置前景像素的最大值。
  • cv2.ADAPTIVE_THRESH_GAUSSIAN_C:这是自适应方法。ADAPTIVE_THRESH_GAUSSIAN_C 表示阈值是邻域像素的加权和,权重为一个高斯窗口。
  • cv2.THRESH_BINARY:这是阈值类型。THRESH_BINARY 表示如果计算的局部阈值大于像素值,则将该像素设置为0(黑色),否则设置为最大值(白色)。
  • 115:这是邻域大小,用于计算局部阈值的窗口大小。它必须是奇数,例如 11x11 或 15x15 的区域。
  • 1:这是常数 C,从计算的局部均值或加权均值中减去。这个常数可以用来微调阈值。

12. 腐蚀与膨胀


import cv2
import numpy as np

gray = cv2.imread("opencv_logo.jpg", cv2.IMREAD_GRAYSCALE)

_, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)
kernel = np.ones((5, 5), np.uint8)

erosion = cv2.erode(binary, kernel)
dilation = cv2.dilate(binary, kernel)

cv2.imshow("binary", binary)
cv2.imshow("erosion", erosion)
cv2.imshow("dilation", dilation)


cv2.waitKey()

在这里插入图片描述
cv2.THRESH_BINARY_INV:这是阈值类型。THRESH_BINARY_INV 表示反向二值化,即如果像素值大于阈值,则将其设置为0(黑色),否则设置为最大值(白色)。

12.1 np.ones函数

np.ones() 是 NumPy 库中的一个函数调用,用于创建一个指定形状和数据类型的数组,其中所有元素都初始化为1。
参数说明

  1. 形状参数 (5, 5):
  • 这个参数定义了数组的维度。在这个例子中,(5, 5) 表示创建一个二维数组,具有5行5列。
  1. 数据类型参数 np.uint8:
  • 这个参数指定了数组中元素的数据类型。np.uint8 是无符号8位整型,其取值范围是0到255。
  • 使用 np.uint8 数据类型可以节省内存,并且在处理图像时非常常见,因为大多数图像格式使用8位像素值。
    返回值
    函数返回一个二维数组,所有元素都被初始化为1,且数据类型为 np.uint8

12.2 cv2.erode函数

cv2.erode 是 OpenCV 库中的一个函数,用于对图像进行腐蚀操作。腐蚀操作是一种形态学操作,它可以消除图像中的小物体、在纤细点分离物体、平滑较大物体的边界同时并不明显改变其面积。

12.3 cv2.dilate函数

cv2.dilate 是 OpenCV 库中的一个函数,用于对图像进行膨胀操作。膨胀操作是一种形态学操作,它可以扩大图像中的物体、填补物体内部的空洞、平滑物体的边界同时可能会增加其面积。

13.调用摄像头

import cv2  # 导入OpenCV库

# 创建VideoCapture对象,参数0表示默认摄像头
capture = cv2.VideoCapture(0)

# 开始一个无限循环,用于持续捕获视频帧
while True:
    ret, frame = capture.read()  # 读取摄像头的一帧
    if not ret:  # 如果读取失败,跳出循环
        break
    cv2.imshow("camera", frame)  # 显示捕获到的帧
    key = cv2.waitKey(1)  # 等待用户按键,参数1表示等待1毫秒
    if key != -1:  # 如果用户按下了键,跳出循环
        break

capture.release()  # 释放摄像头资源
cv2.destroyAllWindows()  # 关闭所有OpenCV窗口

14. 总结

OpenCV是一个集轻量、高效、开源与一身的被使用最广泛的计算机视觉工具,非常值得程序员的学习。

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

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

相关文章

嵌入式 lwip http server makefsdata

背景: 基于君正X2000 MCU Freertoslwip架构 实现HTTP server服务,MCU作为HTTP服务器通过网口进行数据包的传输,提供网页服务。其中设计到LWIP提供的工具makefsdata,常用于将文件或目录结构转换为适合嵌入到固件中的二进制格式。 …

qemu-kvm源码解析-cpu虚拟化

背景 Qemu 虚拟化中,CPU,内存,中断是虚拟化的核心板块。本章主要对CPU虚拟化源码进行分析 而随着技术的发展包括CPU、内存、网卡等常见外设。硬件层面的虚拟化现在已经是云计算的标配。形成了,qemu作为cpu外层控制面&#xff0c…

数据治理中 大数据处理一般都遵循哪些原则

在数据治理中,大数据处理通常遵循以下原则: 最小化原则:企业应只收集实现特定目的所需的数据,避免数据冗余和安全风险。 合法性原则:企业必须遵守相关法律法规,确保数据处理符合法律要求,降低法…

【Python pro】基本数据类型

一、数字类型 1.1 数字类型的组成 1.1.1 整数 (1)十进制,二进制0b,八进制0o,十六进制0x print(16 0b10000 0o20 0x10) # 输出:True(2)十进制转其他进制 a bin(16) b oct(1…

sql server查询IO消耗大的排查sql诊断语句

原文链接: sql server查询IO消耗大的排查sql诊断语句-S3软件[code]select top 50 (total_logical_reads/execution_count) as avg_logical_reads , (total_logical_writes/execution_count) as avg_logical_writes , (tota ... https://blog.s3.sh.cn/thread-120-1…

kubernetes源码分析 kubelet

简介 从官方的架构图中很容易就能找到 kubelet 执行 kubelet -h 看到 kubelet 的功能介绍: kubelet 是每个 Node 节点上都运行的主要“节点代理”。使用如下的一个向 apiserver 注册 Node 节点:主机的 hostname;覆盖 host 的参数&#xff1…

Golang学习笔记_33——桥接模式

Golang学习笔记_30——建造者模式 Golang学习笔记_31——原型模式 Golang学习笔记_32——适配器模式 文章目录 桥接模式详解一、桥接模式核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、桥接模式的特点三、适用场景1. 多维度变化2. 跨平台开发3. 动态切换实现 四、与其他…

【js逆向_入门】图灵爬虫练习平台 第四题

(base64解码)地址:aHR0cHM6Ly9zdHUudHVsaW5ncHl0b24uY24vcHJvYmxlbS1kZXRhaWwvNC8 请求接口带有加密参数: 全局搜索Sign,找到参数生成位置 一目了然,知道参数是怎么构造生成的 调试代码 测试验证思路是否正确 时间: …

Mybatis后端数据库查询多对多查询解决方案

问题场景: 我开发的是一个论文选择系统。 后端用一个论文表paper来存储论文信息。 论文信息中,包含前置课程,也就是你需要修过这些课程才能选择这个论文。 而一个论文对应的课程有很多个。 这样就造成了一个数据库存储的问题。一个paper…

【MySQL排错 】mysql: command not found 数据库安装后无法加载的解决办法

【MySQL排错 】mysql: command not found 数据库安装后无法加载的解决办法 A Solution to Solve Error - mysql: command not found After The Installation of MySQL Community Server By JacksonML 本文简要介绍如何在macOS安装完毕MySQL数据库服务器后,针对无…

分享一款AI绘画图片展示和分享的小程序

🎨奇绘图册 【开源】一款帮AI绘画爱好者维护绘图作品的小程序 查看Demo 反馈 github 文章目录 前言一、奇绘图册是什么?二、项目全景三、预览体验3.1 截图示例3.2 在线体验 四、功能介绍4.1 小程序4.2 服务端 五、安装部署5.1 快速开始~~5.2 手动部…

大模型知识蒸馏技术(4)——离线蒸馏

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl离线蒸馏概述 离线蒸馏是知识蒸馏中最早被提出且最为常见的实现方式,其核心在于教师模型和学生模型的训练是分阶段进行的。具体而言,教师模型首先在训练集上进行充分训练,直至收敛,然后利用教…

解决DeepSeek服务器繁忙的有效方法

全球42%的企业遭遇过AI工具服务器过载导致内容生产中断(数据来源:Gartner 2025)。当竞品在凌晨3点自动发布「智能家居安装指南」时,你的团队可能正因DeepSeek服务器繁忙错失「净水器保养教程」的流量黄金期⏳。147SEO智能调度系统…

BT401双模音频蓝牙模块如何开启ble的透传,有什么注意事项

BT401音频蓝牙模块如何开启ble的透传? 首先BT401的蓝牙音频模块,分为两个版本,dac版本和iis数字音频版本 DAC版本:就是BT401蓝牙模块【9和10脚】直接输出模拟音频信号,也就是说,直接推动耳机可以听到声音 …

基于SSM框架的宠物之家系统(有源码+论文!!!)

这个系统可以帮助大家去做设计或者学习,大家可以管我要word版论文🥰这里具体论文内照片、e-r图等等加载不进来, 大家如果想要源码+论文+制定+调试,可以私信我!!(可改别的系统,例如调查问卷系统等等) 目录 第1章 绪论 1.1开发背景 1.2开发工具及语言 第2章 宠物之家系…

网工项目理论1.7 设备选型

本专栏持续更新,整一个专栏为一个大型复杂网络工程项目。阅读本文章之前务必先看《本专栏必读》。 一.交换机选型要点 制式:盒式交换机/框式交换机。功能:二层交换机/三层交换机。端口密度:每交换机可以提供的端口数量。端口速率:百兆/千兆/万兆。交换容量:交换矩阵…

Gateway中的Filter机制

Gateway中的Filter机制 文章目录 Gateway中的Filter机制Gateway中的Filter机制Gateway Filter 机制的概述核心思想与设计Filter 的两种类型过滤器的生命周期Gateway Filter 的特点Gateway Filter 的意义Gateway Filter 的工作原理核心架构与执行流程执行流程解析过滤器类型的角…

顺序表常用操作和笔试题

1、顺序表的常用操作 1.1 顺序表的创建 如下代码所示&#xff1a;创建了一个默认空间为10的整型顺序表&#xff0c;如果空间不足则会以1.5倍扩容。 List<Integer> list new ArrayList<>(); 创建一个空间为15的整型顺序表 List<Integer> list2 new ArrayL…

二.数据治理流程架构

1、数据治理流程架构核心思想&#xff1a; 该图描绘了一个以数据标准规范体系为核心&#xff0c;大数据生命周期管理为主线&#xff0c;数据资源中心为依托&#xff0c;并辅以数据质量管理和大数据安全与隐私管理的数据治理流程架构。它旨在通过规范化的流程和技术手段&#x…

解锁机器学习核心算法 | 线性回归:机器学习的基石

在机器学习的众多算法中&#xff0c;线性回归宛如一块基石&#xff0c;看似质朴无华&#xff0c;却稳稳支撑起诸多复杂模型的架构。它是我们初涉机器学习领域时便会邂逅的算法之一&#xff0c;其原理与应用广泛渗透于各个领域。无论是预测房价走势、剖析股票市场波动&#xff0…