看看计算机眼中的世界———OpenCV
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.保存参数的设置:
cv2.imwrite(‘output_high.jpg’, img, [cv2.IMWRITE_JPEG_QUALITY, 95])
# 低质量保存(质量=50),文件更小但画质有损
cv2.imwrite(‘output_low.jpg’, img, [cv2.IMWRITE_JPEG_QUALITY, 50])
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(“图像保存失败,请检查文件路径和权限”)
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)