opencv-初识opencv
学习 OpenCV 之前需要先安装使用的库pip install opencv-python3.4.18.65 -i https://pypi.tuna.tsinghua.edu.cn/simplepip install opencv-contrib-python3.4.18.65 -i https://pypi.tuna.tsinghua.edu.cn/simplepip install numpy1.26.4 -i https://pypi.tuna.tsinghua.edu.cn/simpleOpenCV 更偏向于一个计算机视觉算法库专注于图像的处理和分析。它不同于通用的深度学习框架如 TensorFlow、PyTorch后者主要用于模型的训练。在实际项目中两者常结合使用用 OpenCV 进行数据预处理再用深度学习模型进行推理。简单来说OpenCV 为计算机视觉提供了从基础到高级的乐高积木让开发者能高效地搭建各种看世界的应用。作为对图像处理和分析特化的算法库我们得先去读取电脑中的图片或者视频。假设我的文件夹里含有 1.jpg 这个图片可以用以下代码读取import cv2 # 读取的格式是 BGR numpy import numpy as np a cv2.imread(1.jpg)这时候 a 里面是 numpy 数组存储了读取的图像的像素值大概长这样子[[[184 64 22] [184 64 22] [184 64 22] ... [206 146 110] [206 146 110] [206 146 110]] [[185 66 21] [184 64 22] [184 64 22] ...可以使用以下代码显示图片cv2.imshow(1, a) # 显示图片。显示图片的名称显示的图片数据。如注释所说我们可以使用 imshow 来显示图片括号内前面是图片名后面是存储图片数据的数组变量。之后便引入图片显示的时间长短一般我们需要图片一直存在但输入上述的代码会出现两个结果一闪而过最常见程序执行完cv2.imshow()后紧接着脚本就运行结束了。Python 进程退出时会自动回收所有内存和窗口资源所以你几乎看不到图像窗口或者看到它出现一瞬间就消失了。卡死/无响应部分环境由于没有调用waitKey去刷新 GUI 事件循环窗口可能无法正常渲染直接显示为未响应的白色/灰色框。所以在这下面必须加上一句能控制图片出现时间的代码cv2.waitKey(0)默认值为 0写零表示没有倒计时图片一直存在而它的单位是毫秒ms也就是说在括号内写 1000 也只有一秒的显示时间。在这之后我们需要进行退出那需要释放内存cv2.destroyAllWindows() # 关闭所有打开的窗口并释放所有相关内存。对于简单的程序不需要调用这些函数应用程序的所有资源和窗口在退出时都会由操作系统自动关闭。在这之后我们可以对之前的图片进行一些操作输出一些信息# 调试时观察 shape、dtype、size 属性 print(图像形状 (shape): , a.shape) # 高、宽、通道数 print(图像数据类型 (dtype): , a.dtype) # 无符号 8 位整数用于表示像素值的范围在 0 到 255 之间 print(图像大小 (size): , a.size) # 表示图像的总像素数即图像的高度乘以宽度乘以通道数大概输出为图像形状 (shape): (834, 1024, 3) 图像数据类型 (dtype): uint8 图像大小 (size): 2562048灰度操作将彩色图像转为灰度图是为了在保留关键结构和纹理信息的同时大幅降低数据复杂度从而提高处理速度和算法鲁棒性。更具体地说有以下几个核心原因1. 计算效率更高速度与内存彩色图像通常是3 通道RGB 或 BGR而灰度图只有1 通道。数据量减少 2/3处理一张灰度图所需的计算量和内存仅为彩色的 1/3。推理更快在实时处理如视频流、嵌入式设备中减少通道数能显著提升帧率。2. 聚焦核心特征忽略颜色干扰很多计算机视觉任务关注的是物体的形状、轮廓、纹理和明暗变化而非颜色本身。例如在边缘检测如 Canny 算子或特征提取如 SIFT、ORB中算法主要依赖梯度亮度的变化。颜色信息往往是多余的甚至可能引入噪声比如相同颜色的物体与背景混淆。OCR文字识别识别黑白印刷体文字时颜色完全无用灰度化后算法能更专注于笔画形状。3. 降低过拟合风险机器学习/深度学习在训练深度学习模型时输入彩色图像意味着模型要学习 3 倍于灰度的参数。如果训练数据中颜色与标签存在偶发关联例如苹果大多是红色模型可能会过度依赖颜色而忽略形状。灰度化可以迫使模型关注更本质的纹理和结构从而提高泛化能力。4. 算法原生要求历史与数学原因许多经典的计算机视觉算法如直方图均衡化、二值化、形态学操作本身就是基于亮度强度设计的。如果输入彩色图通常需要先将彩色分量加权转换为灰度值否则算法无法直接处理多维数据。综上所述灰度图还是很有必要的我们通常用以下代码进行图片灰度化的操作b cv2.imread(r./1.jpg, cv2.IMREAD_GRAYSCALE)代码对 1.jpg 进行读取并将其灰度化。在进行灰度化之前也可能对图片的大小存疑是不是也可以改变其大小c cv2.imread(1.jpg) d c[230:580, 300:600] # 读取位置 cv2.imshow(yuantu, c) cv2.imshow(qiepian, d)开头也讲了 OpenCV 也可以对视频进行操作video_capture cv2.VideoCapture(2.mp4)可通过以上代码对视频文件进行读取同样也能对视频的颜色进行更改frame cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)GRAY 为颜色可更改为其他颜色。上面提到彩色是三通道的灰度是单通道的代码中可以将三个通道拆开来分开灰度化三个单通道灰度图cv2.imshow(b, b)→ 显示B蓝色通道的灰度图cv2.imshow(g, g)→ 显示G绿色通道的灰度图cv2.imshow(r, r)→ 显示R红色通道的灰度图每个窗口都是一张单通道图像像素值代表该通道的强度0~255显示为灰度。合并后的彩色图cv2.imshow(result3, img)→ 将a1B 通道、a2G 通道、a3R 通道重新合并为 BGR 彩色图像。由于a1, a2, a3正是原始图像a的三个通道所以合并后的图像与原始图像完全一致。 作用与意义教学演示帮助你直观理解彩色图像由三个独立通道组成每个通道可以看作一张灰度图。通道分离cv2.split()和数组切片都能提取单个通道便于后续对特定通道进行单独处理如调整亮度、增强对比度、替换通道等。通道合并cv2.merge()用于将修改后的单通道重新组合成彩色图是图像处理流水线中的常用操作。实际应用常用于颜色空间转换、通道增强、水印叠加、通道交换如将 R 通道与 B 通道互换等场景。代码如下a cv2.imread(1.jpg) a1 a[:,:,0] a2 a[:,:,1] a3 a[:,:,2] b, g, r cv2.split(a)这时候分别输出这 a1、a2、a3 就行了。我们也存在对图片某处打上马赛克也就是用一张图片的一部分对另一张图片的指定部分进行覆盖a[100:200, 200:300] np.random.randint(0, 256, (100, 100, 3))a[100:200, 200:300]为被覆盖图片指定位置。(100, 100, 3)前面两个数需要与 a 里面大小对应。若用其他图片来替换马赛克呢a cv2.imread(r./1.jpg) b cv2.imread(r./3.jpg) b[100:200, 200:300] a[200:300, 100:200]这下就用 a 中的部分图片替换 b 中图了。我们有时需要对图片进行缩放图片缩放 cv2.resize用于调整图像的大小。它有以下几个参数src要调整大小的输入图像可以是 numpy 数组、PIL 图像或其他类型。dsize输出图像的大小可以是一个元组例如宽高或者使用整数标量来缩放原始图像。如果 dsize 为 None则根据 fx 和 fy 缩放原始图像。我们有两种方法# 方法一直接指定尺寸 a_new cv2.resize(a, (200, 200)) # 宽、高 方法二使用缩放系数 a_new cv2.resize(a, dsize:None, fx0.5, fy0.5)fx沿 x 轴的缩放系数。fy沿 y 轴的缩放系数。可用第一句代码实现当然可以直接使用第二种。第二种可缩放比例也可以不写前置参数dsize:。