当前位置: 首页 > 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;声明为虚函数也没有什么意思…...

使用OBS推流,大华摄像头 srs服务器播放

说明&#xff1a; ffmpeg可以推流&#xff0c;但是是命令行方式不太友好&#xff0c;还可以使用主流的OBS开源推流软件&#xff0c;可从官网Open Broadcaster Software | OBS 下载最新版本&#xff0c;目前很多网络主播都是用它做直播。该软件支持本地视频文件以及摄像头推流。…...

CSS 组合选择符详解与实战示例

在 Web 开发过程中&#xff0c;CSS 用于定义页面元素的样式&#xff0c;而选择器则帮助我们精确定位需要添加样式的元素。今天我们主要来讲解 CSS 中的组合选择符&#xff0c;它们能够根据 DOM 结构中元素之间的关系来选中目标元素&#xff0c;从而写出结构清晰、易于维护的 CS…...

Window系统通过Docker本地安装ollama和deepseek

在 Windows 系统上安装 Ollama 和 DeepSeek 的步骤如下&#xff1a; 安装 Ollama 安装 WSL&#xff08;Windows Subsystem for Linux&#xff09;&#xff1a; 如果还没有安装 过WSL的&#xff08;安装过的你直接跳过就行了&#xff09;&#xff0c;可以按照以下步骤进行安装&…...

镜头放大倍率和像素之间的关系

相互独立的特性 镜头放大倍率&#xff1a;主要取决于镜头的光学设计和结构&#xff0c;决定了镜头对物体成像时的缩放程度&#xff0c;与镜头的焦距等因素密切相关。比如&#xff0c;微距镜头具有较高的放大倍率&#xff0c;能将微小物体如昆虫、花朵细节等放大成像&#xff0…...

P3413 SAC#1 - 萌数

题目背景 本题由世界上最蒟蒻的 SOL 提供。 寂月城网站是完美信息教室的官网。地址:http://191.101.11.174/mgzd。 题目描述 蒟蒻 SOL 居然觉得数很萌! 好在在他眼里,并不是所有数都是萌的。只有满足“存在长度至少为 22 的回文子串”的数是萌的——也就是说,101 是萌…...

[RabbitMQ] RabbitMQ常见面试题

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

Java运行时数据区

JVM主要流程包括三部分&#xff1a; 首先是 ClassLoard 类加载器&#xff0c;加载数据源文件到jvm当中然后将加载好的数据存放在运行时数据区最后由引擎进行解释和编译的工作 1.Java 内存区域&#xff1a; 1.1 程序计数器 程序计数器&#xff08;Program Counter Register&a…...

【03】 区块链分布式网络

3-1 P2P网络 传统中心化网络由中央服务器保存全量数据。客户端之间无法直接连接&#xff0c;必须通过中央服务器作为桥梁。客户端必须和中央服务器建立连接后访问资源。客户端之间并无连通。 在P2P网络中通过将数据资源分散在网络各个节点中存储以及节点间交互连接&#xff0…...

【SQL server】关于SQL server彻底的卸载删除。

1.未彻底卸载删除SQL Server会出现的问题 如果没有彻底删除之前的SQL server&#xff0c;就可能会出现这个 当要安装新的实例的时候因为之前安装过sql server没有删除干净而导致下图问题&#xff0c;说实例名已经存在。 2.首先要先关闭服务 “开始R”可以快速进入运行&#…...

【含文档+PPT+源码】基于微信小程序的校园志愿者管理系统的设计与实现

项目介绍 本课程演示的是一款 基于微信小程序的校园志愿者管理系统的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…...