OpenCV(open source computer vision library)

一,了解OpenCV:

OpenCV是开源的计算机视觉与机器学习软件库,为计算机视觉应用程序提供了一个通用基础设备,加速机器感知在商业产品中的应用,拥有超过2500种优化算法,涵盖了一套全面的经典与最先进的计算机视觉与机器学习算法,可以运行在Window是,linux,andriod和MAC OS操作系统上

特点:
1.轻量且高效:

  • 由一些列c函数与少量c++构成,可以实现图像处理与计算机视觉方面的很多通用算法

2.良好的跨平台性:

  • 同时提供了Python,Ruby,MATLAB等语言的接口
  • 支持 Windows、Linux、macOS 等桌面系统,Android、iOS 等移动系统,以及树莓派、Jetson Nano等嵌入式平台

3.具有强大的算法库:
OpenCV包含多个功能强大的模块,每个模块专注于不同的计算机视觉任务:

  • Core(核心模块 提供基础数据结构和函数,包括多为数组(Mat),基本绘图,线性代数等
  • ImgProc(图像处理 图像滤波、几何变换、颜色空间转换、边缘检测等
  • Video(视频分析) 视频读写、背景分离、光流估计、目标跟踪
  • Calib3d(3D模块 相机标定、立体视觉、3D重建、姿态估计
  • Features2d(2D特征) SIFT、SURF、ORB等特征点检测与匹配
  • ObjDetect(目标检测) Haar级联分类器、HOG特征、QR码检测
  • DNN(深度学习) 支持Caffe、TensorFlow、ONNX等框架模型导入
  • ML(机器学习) KNN、SVM、决策树、随机森林等传统算法

4.高性能优化:
OpenCV内置的很多算法都经过高性能优化:

  • 多指令集优化:支持SSE,AVX,AVX-512等指令集,大幅度提升CPU性能:
  • 支撑GPU加速:通过CUDA和OpenCL接口提供GPU加速
  • 并行计算:内置并行计算架构,自动利用多核CPU
  • 内存优化:支持内存映射和零拷贝操作,减少数据传输开销

通过这些高性能的算法使得图像处理和图像分析变得更加易于上手,让开发人员更多篇的精力花在算法的设计上

二 图像处理:

OpenCV本质上就是对图像进行一系列的处理,先来了解一下OpenCV处理的图像类型:

BRG三通道显示图像原理:

在裸机部分我们基础过的屏幕的显示是通过RGB格式显示的,但是OpenCV处理的图像与RGB略有不同:

1.BRG与BGR的关系

1.本质区别:

  • RBG与RGB本质上上完全相同的,区别就在于颜色通道的排列顺序不同

  • RGB格式:通道顺序为 Red(红)、Green(绿)、Blue(蓝)

  • BGR格式:通道顺序为 Blue(蓝)、Green(绿)、Red(红)

在计算机的内存中,这仅仅只是通道索引的差距。例如,一个纯红色像素点在RGB中的表示为(255,0,0),在RGB中则表示为(0,0,255)。

2.历史渊源:为什么OpenCV使用BGR??

这是一个有趣的历史遗留问题:

1990年代末,相机制造商(如Windows的VFW、DShow)普遍使用BGR格式
2000年OpenCV诞生时,为了兼容当时的硬件设备,选择了BGR作为默认格式
这个历史包袱一直延续至今,形成了“OpenCV是BGR,其他都是RGB”的局面

2.BRG的数据结构:

1.存储方式:

一张BRG的彩色图像在计算机中存储为M * N * 3的三维矩阵中,其中:

  • M = 图像高度(行数)
  • N= 图像宽度(列数)
  • 3 = 三个颜色通道(B,G,R)

BGR888:
每个像素的每个通道范围都是0 - 255 ,刚好是一个字节可以表示的最大二进制数,通过这种组合可以表示 1677万种颜色(255255255),RGB也是遵循这种存储方式,常见的还有RGB565(表示的颜色数略少,但是存储的空间更小)

2.内存布局:

以32位的ARGB格式为例,每个像素占用四个字节存储,采用小段存储:

内存布局(十六进制):0xAARRGGBB
AA = Alpha通道(透明度)
RR = 红色通道(RED)
GG= 绿色通道(GREEN)
BB = 蓝色通道(BLUE)

在BGR格式中,通道0表示蓝色,通道1是绿色,通道2是红色

三,BGR三通道的物理意义:

1.通道特性:

B (0 ~ 255) 天空海洋阴影信息的提取
G (0 ~ 255) 植被2分析,亮度信息(人眼最为敏感)
R (0 ~ 255) 交通信号灯检测,人体皮肤检测

2.色彩合成原理:

RGB/BGR都基于加色法模型:

  • 三通道等值混合 -> 产生灰度色,(100,100,100)呈现深灰色
  • 全通道最大值(255,255,255) → 纯白色
  • 全通道最小值 (0,0,0) → 纯黑色

四,BGR在实际应用中的陷阱

1.OpenCV与其他库的混用:

OpenCV使用BRG读取图像,但是Matplotlib,PIL等库期望RGB

import cv2
import matplotlib.pyplot as plt

#OpenCV读取 → BGR格式
img_bgr = cv2.imread(‘photo.jpg’)

#直接传给Matplotlib → 颜色错误(红蓝互换)
plt.imshow(img_bgr) # ❌ 错误:显示为蓝调

#正确的做法:转换颜色空间
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
plt.imshow(img_rgb) # ✅ 正确

2.通道操作

BGR通道分离是图像处理的基本操作:

#使用OpenCV分离通道
b, g, r = cv2.split(img_bgr)

#或者使用索引访问
blue_channel = img_bgr[:, :, 0] # 第0通道 = 蓝色
green_channel = img_bgr[:, :, 1] # 第1通道 = 绿色
red_channel = img_bgr[:, :, 2] # 第2通道 = 红色

然后进行通道合成:

#仅保留红色通道
zeros = np.zeros_like(b)
red_only = cv2.merge([zeros, zeros, r]) # B=0, G=0, R保持不变

所以,在OpenCV中要清楚,图片的读取和存储都要使用BGR格式,在进行Matplotlib调用或者进行模型显示的时候要将BGR的格式转换为RGB的格式

五,BGR与其他色彩空间的转换

1.转灰度图

BRG转灰度图使用人眼亮度感知公式:

Gray = 0.299 * R + 0.587 * G+ 0.144 * B

2.转HSV

HSV(色相,饱和度,明度)更接近人类描述的颜色格式,常用于:

  • 颜色分割 (踢球特点颜色的物体)
  • 图像增强

转换公式 :cv2.cvColor(img_bgr, cv2.COLOR_BGR2HSV)

六,核心要义:

BGR是OpenCV的原生格式,理解他相当与理解OpenCV的数据存储与处理的底层逻辑

  • 使用摄像头捕获视频流
  • 进行图像预处理
  • 与深度学习框架交互时

都需要正确处理BGR和RGB之间的转换

七 OpenCV实战:

1.图片的导出与显示:

img = cv2.imread(image_path)
if img is None:
    print(f"错误:无法读取图像 '{image_path}',请检查文件路径")
    return None

# 显示图像
cv2.imshow("Image", img)
print("按任意键关闭窗口...")
cv2.waitKey(0)
cv2.destroyAllWindows()
print(img.shape)0

这段代码会将指定路径下的图片利用OpenCV导出为BGR格式。

  • img :BGR格式图片数组

  • cv2.imshow() : OpenCV提供的库函数,根据对应的数组就可以显示出对应的图片

  • img.shape :(4096, 3072, 3)
    图片其实就是一个矩阵,每个像素点都是矩阵中的一个数值,对于彩色图片,就是采用BGR三通道进行显示的,也即是一个彩色图片是由三个矩阵构成的,上述的输出中(4096, 3072, 3),表示的正是4096 * 500的彩色图片

函数接口:

retval = cv.imread(filename[, flags])

  • filename:字符串类型,指定要读取的图像文件的路径(可以是绝对路径或相对路径)
  • flags:可选参数,指定图像的读取方式,默认为 cv2.IMREAD_COLOR

常量名称 数值 说明
cv2.IMREAD_COLOR 1 默认方式,将图像转换为3通道BGR彩色图像,忽略透明度
cv2.IMREAD_GRAYSCALE 0 将图像转换为单通道灰度图像
cv2.IMREAD_UNCHANGED -1 按原样加载图像(包含Alpha通道)
cv2.IMREAD_ANYDEPTH 2 输入具有相应深度时返回16位/32位图像,否则转换为8位
cv2.IMREAD_ANYCOLOR 4 以任何可能的颜色格式读取图像

此外,OpenCV还提供缩略读取模式,可以在读取时直接缩小图像尺寸

常量 说明
cv2.IMREAD_REDUCED_COLOR_2 以1/2尺寸读取彩色图像
cv2.IMREAD_REDUCED_COLOR_4 以1/4尺寸读取彩色图像
cv2.IMREAD_REDUCED_COLOR_8 以1/8尺寸读取彩色图像
cv2.IMREAD_REDUCED_GRAYSCALE_2 以1/2尺寸读取灰度图像
cv2.IMREAD_REDUCED_GRAYSCALE_4 以1/4尺寸读取灰度图像
cv2.IMREAD_REDUCED_GRAYSCALE_8 以1/8尺寸读取灰度图像

返回值
cv2.imread() 返回一个NumPy多维数组(numpy.ndarray):

成功时:返回图像数据。彩色图像返回形状为 (height, width, 3) 的数组(BGR顺序),灰度图像返回形状为 (height, width) 的数组
失败时:返回 None(不会抛出异常)

返回值数组还具有以下特点:

img = cv2.imread(‘image.jpg’)

print(img.shape) # 图像的维度(高度,宽度,通道数)
print(img.size) # 像素总数 = 高度 × 宽度 × 通道数
print(img.dtype) # 数据类型,通常为 uint8

2.灰度处理:

1.基本概念:
灰度图是单通道图像,每个像素点只有一个像素值,取址范围是(0 ~ 255),其中0代表纯黑色,255代表纯白色,中间值会呈现不同深浅的灰色

区别于彩色图:

  • 彩色图:三通道,每个像素由三个值表示
  • 灰度图:单通道,每个像素只有一个值

所以灰度图在存储空间上约为彩色图的1/3

2.灰度化的方法:

1- 加权平均法:
灰度值 = R×0.299 + G×0.587 + B×0.114
公式中绿色通道的权重最高(0.587),因为人眼对绿色最敏感;红色次之(0.299),蓝色最低(0.114)

OpenCV提供函数接口实现图片灰度化:
img = cv2.imread(‘input.jpg’)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

也可以手动进行灰度化处理:
img = cv2.imread(‘input.jpg’)
b,g,r = cv2.split(img)
gray = (int(b) * 0.114 + int(g) * 0.587 + int® * 0.299).astype(np.uint8)

2 - 平均值法

将三个通道的值简单平均,但效果不如加权平均法自然:

灰度值 = (R + G + B) / 3

img = cv2.imread(‘input.jpg’)
gray = np.mean(img, axis = 2).astype(np.uint8)

3.常用操作方法:

1.在读取时直接灰度化:

在imread读取时指定读取模式为0

  • img = cv2.imread(image_path,0)

2.使用cvtColor函数转化
这是较为常用的处理方法,可以随时对现有图像进行处理

img = cv2.imread(image_path)
dst = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

这里来介绍两个宏定义:

cv2.IMREAD_COLOR:彩色图像
cv2.IMREAD_GRAYSCALE:灰度图像
可以在调cv2.imread()时当作参数传入

dst是灰度图像,所以对应的dst.shape也就是一个二维矩阵(4096, 3072)

3.图像显示函数:

cv2.imshow(‘image’, dst)
print(“按任意键关闭窗口…”)
cv2.waitKey(0)
cv2.destroyAllWindows()
print(img.shape)

这里定义了一个图像显示的函数,

  • imshow()为显示函数
  • waitkey(0)为无限时间的显示函数,如果参数改为1,就会是ms级别的显示时间
  • destoryAllWindows()为按下任意键就可以关闭窗口

4.图像的保存:

cv2.imwrite():

这是OpenCV库中用于将数据保存为文件的核心函数,

cv2.imwrite(filename, img[, params])

1.参数说明:

  • filename:要保存的文件名,包括文件路径和扩展名(如.jpg,.png)的,文件扩展名决定了保存的图像格式

  • img:要保存的图像数据,通常是一个NumPy数组,可以是OpenCV读取的图像,也可以是经过处理后的图像数据

  • params:可选参数,是一个列表,用于指定保存图像的格式和质量等信息

2.支持的图像格式:

OpenCV支持多种图像格式,包括BMP,PNG,JPEG,TIFF等,保存的图像格式由文件扩展名决定

cv2.imwrite(‘output.jpg’, img) # JPEG格式
cv2.imwrite(‘output.png’, img) # PNG格式
cv2.imwrite(‘output.tiff’, img) # TIFF格式
cv2.imwrite(‘output.bmp’, img) # BMP格式

3.保存参数的设置:

  • 1.JPEG质量控制
    对于JPEG格式,可以使用cv2.IMWRITE_JPEG_QUALITY参数来控制压缩质量,取值范围0-100,默认值为95

    高质量保存(质量=95)

cv2.imwrite(‘output_high.jpg’, img, [cv2.IMWRITE_JPEG_QUALITY, 95])

# 低质量保存(质量=50),文件更小但画质有损

cv2.imwrite(‘output_low.jpg’, img, [cv2.IMWRITE_JPEG_QUALITY, 50])

    1. PNG压缩级别
      对于PNG格式,可以使用cv2.IMWRITE_PNG_COMPRESSION参数控制压缩级别,取值范围0-9,默认值为3

    最低压缩(速度最快,文件最大)

cv2.imwrite(‘output.png’, img, [cv2.IMWRITE_PNG_COMPRESSION, 0])

# 最高压缩(速度最慢,文件最小)

cv2.imwrite(‘output.png’, img, [cv2.IMWRITE_PNG_COMPRESSION, 9])

4.返回值与错误处理:

cv2.imwrite() 返回一个布尔值:True表示保存成功,False表示保存失败。重要提示:该函数失败时不会抛出异常,而是静默返回False,因此检查返回值至关重要

success = cv2.imwrite(‘output.jpg’, img)
if success:
print(“图像保存成功”)
else:
print(“图像保存失败,请检查文件路径和权限”)

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐