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

【OpenCV】入门教学

🏠大家好,我是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 cv2image = cv2.imread("opencv_logo.jpg")
print(image.shape)#打印维度

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

打印结果
(250, 250, 3)

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

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

import cv2image = 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 cv2image = 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 npimage = 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 cv2image = 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 cv2image = 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 npimage = 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 + hcv2.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 cv2gray = 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 cv2gray = 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 npgray = 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:  # 如果读取失败,跳出循环breakcv2.imshow("camera", frame)  # 显示捕获到的帧key = cv2.waitKey(1)  # 等待用户按键,参数1表示等待1毫秒if key != -1:  # 如果用户按下了键,跳出循环breakcapture.release()  # 释放摄像头资源
cv2.destroyAllWindows()  # 关闭所有OpenCV窗口

14. 总结

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

相关文章:

【OpenCV】入门教学

🏠大家好,我是Yui_💬 🍑如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 🚀如有不懂,可以随时向我提问,我会全力讲解~ &#x1f52…...

大数据项目4:基于spark的智慧交通项目设计与实现

项目概述 项目直达 www.baiyuntu.com 随着交通数据的快速增长,传统的交通管理方式已无法满足现代城市的需求。交通大数据分析系统通过整合各类交通数据,利用大数据技术解决交通瓶颈问题,提升交通管理效率。本项目旨在通过大数据技术&#…...

netcore openTelemetry+prometheus+grafana

一、netcore项目 二、openTelemetry 三、prometheus 四、grafana添加Dashborad aspire/src/Grafana/dashboards at main dotnet/aspire GitHub 导入:aspnetcore.json和aspnetcore-endpoint.json 效果:...

Spring Boot接入Deep Seek的API

1,首先进入deepseek的官网:DeepSeek | 深度求索,单击右上角的API开放平台。 2,单击API keys,创建一个API,创建完成务必复制!!不然关掉之后会看不看api key!!&…...

Git、Github和Gitee完整讲解:丛基础到进阶功能

第一部分:Git 是什么? 比喻:Git就像是一本“时光机日记本” 每一段代码的改动,Git都会帮你记录下来,像是在写日记。如果出现问题或者想查看之前的版本,Git可以带你“穿越回过去”,找到任意时间…...

MyBatis的工作流程是怎样的?

大家好,我是锋哥。今天分享关于【MyBatis的工作流程是怎样的?】面试题。希望对大家有帮助; MyBatis的工作流程是怎样的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MyBatis 的工作流程可以分为几个主要的步骤&…...

Maven 安装配置(完整教程)

文章目录 一、Maven 简介二、下载 Maven三、配置 Maven3.1 配置环境变量3.2 Maven 配置3.3 IDEA 配置 四、结语 一、Maven 简介 Maven 是一个基于项目对象模型(POM)的项目管理和自动化构建工具。它主要服务于 Java 平台,但也支持其他编程语言…...

分享如何通过Mq、Redis、XxlJob实现算法任务的异步解耦调度

一、背景 1.1 产品简介 基于大模型塔斯,整合传统的多项能力(NLP、OCR、CV等),构建以场景为中心的新型智能文档平台。通过文档审阅,实现结构化、半结构化和非结构化文档的信息获取、处理及审核,同时基于大…...

发布:大彩科技DN系列2.8寸高性价比串口屏发布!

一、产品介绍 该产品是一款2.8寸的工业组态串口屏,采用2.8寸液晶屏,分辨率为240*320,支持电阻触摸、电容触摸、无触摸。可播放动画,带蜂鸣器,默认为RS232通讯电平,用户短接屏幕PCB上J5短接点即可切换为TTL电…...

集合类不安全问题

ArrayList不是线程安全类,在多线程同时写的情况下,会抛出java.util.ConcurrentModificationException异常 解决办法: 1.使用Vector(ArrayList所有方法加synchronized,太重) 2.使用Collections.synchronized…...

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之上传头像和新增收货地址

🧸安清h:个人主页 🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 目录 🚀1.上传头像 -持久…...

AI知识库和全文检索的区别

1、AI知识库的作用 AI知识库是基于人工智能技术构建的智能系统,能够理解、推理和生成信息。它的核心作用包括: 1.1 语义理解 自然语言处理(NLP):AI知识库能够理解用户查询的语义,而不仅仅是关键词匹配。 …...

20240817 联想 笔试

文章目录 1、选择题1.11.21.31.41.51.61.71.81.91.101.111.121.131.141.151.161.171.181.191.202、编程题2.12.2岗位:Linux开发工程师 题型:20 道选择题,2 道编程题 1、选择题 1.1 有如下程序,程序运行的结果为 (D) #include <stdio.h>int main() {int k = 3...

IntelliJ IDEA 安装与使用完全教程:从入门到精通

一、引言 在当今竞争激烈的软件开发领域&#xff0c;拥有一款强大且高效的集成开发环境&#xff08;IDE&#xff09;是开发者的致胜法宝。IntelliJ IDEA 作为 JetBrains 公司精心打造的一款明星 IDE&#xff0c;凭借其丰富多样的功能、智能精准的代码提示以及高效便捷的开发工…...

【JVM详解一】类加载过程与内存区域划分

一、简介 1.1 概述 JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域等组成。JVM屏蔽了与操作系统平台相关…...

250207-MacOS修改Ollama模型下载及运行的路径

在 macOS 上&#xff0c;Ollama 默认将模型存储在 ~/.ollama/models 目录。如果您希望更改模型的存储路径&#xff0c;可以通过设置环境变量 OLLAMA_MODELS 来实现。具体步骤如下&#xff1a; 选择新的模型存储目录&#xff1a;首先&#xff0c;确定您希望存储模型的目标目录路…...

Win10 部署llama Factory 推荐教程和遇到的问题

教程 【大模型微调】使用Llama Factory实现中文llama3微调_哔哩哔哩_bilibili 大模型微调&#xff01;手把手带你用LLaMA-Factory工具微调Qwen大模型&#xff01;有手就行&#xff0c;零代码微调任意大语言模型_哔哩哔哩_bilibili 遇到问题解决办法 pytorch gpu国内镜像下载…...

如何在Android Studio中开发一个简单的Android应用?

Android Studio是开发Android应用的官方集成开发环境&#xff08;IDE&#xff09;&#xff0c;它提供了许多强大的功能&#xff0c;使得开发者能够高效地创建Android应用。如果你是Android开发的初学者&#xff0c;本文将引导你如何在Android Studio中开发一个简单的Android应用…...

ubuntu下迁移docker文件夹

在 Ubuntu 系统中迁移 Docker 文件夹&#xff08;如 Docker 数据存储文件夹 /var/lib/docker&#xff09;到另一个磁盘或目录&#xff0c;通常是为了释放系统盘空间。以下是迁移过程的详细步骤&#xff1a; 1. 停止 Docker 服务 在进行迁移之前&#xff0c;必须停止 Docker 服…...

嵌入式面试题 C/C++常见面试题整理_7

一.什么函数不能声明为虚函数? 常见的不能声明为虚函数的有:普通函数(非成员函数):静态成员函数;内联成员函数;构造函数;友元函数。 1.为什么C不支持普通函数为虚函数?普通函数(非成员函数)只能被overload&#xff0c;不能被override&#xff0c;声明为虚函数也没有什么意思…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...