最近做了一个基于cv2展开的一个人脸识别的小项目,现要理解cv2的底层原理、相关的函数、实现的相关功能,现对此做出总结。
一、cv2的底层原理
底层原理从数据结构、图像处理算法、计算优化、内存管理方面进行介绍。
数据结构: 在底层图像通常多以二维数组的形式表示,在python的cv2里,图像一般用NumPy数组存储,例如BGR格式,数组中的每个元素都代表一个像素点,其值代表像素的颜色强度。 opencv广泛使用矩阵和向量来处理各种数据,利用矩阵运算来描述变换关系。
图像处理算法: 1.滤波操作 用于平滑图像、去除噪声等 常见的算法如均值滤波、高斯滤波等,均值滤波详细展开就是,遍历图像的每个像素,将该像素及其邻域的像素值取平均值,作为该像素的新值 高斯滤波详细展开就是,基于二维高斯函数构建权重矩阵,生成高斯核,对图像中的每个像素,用高斯核与其邻域的像素进行加权平均,中心像素权重最大,周围像素权重随着距离增大而减小,从而实现平滑、去除噪声。2.边缘检测 用于检测图像中的边缘信息 算法主要包括高斯平滑(减少噪声对边缘检测的影响)、梯度计算(对图像中每个像素点确定梯度幅值和方向为后续定位提供依据)、非极大值抑制(消除边缘响应的非最大值,使得边缘更加清晰)、双阈值处理(去除虚假边缘并且连接边缘断点使得边缘更加流畅)等步骤。3.特征提取 利用特征提取算法(SIFI SURF ORB等)用于提取图像中的特征点和特征描述符。
计算优化: 为了提升效率,opencv使用多线程和并行计算技术 例如 进行大规模图像处理时,可以将图像分成多个小块,并行对每个小块处理
内存管理: opencv使用智能指针等技术管理内存,opencv与NumPy紧密集成使得数据传递更加高效
二、相关的函数拓展
1.图像的读取和显示
cv2.imread( )用于读取图像文件并将转换为NumPy数组 函数原型是cv2.imread(filename, flags=1)
,其中filename
是要读取的图像文件的名称(包括路径),flags
参数用于指定读图的方式:
-
cv2.IMREAD_COLOR
:默认值,用于读取一张彩色图像。 -
cv2.IMREAD_GRAYSCALE
:以灰度模式读取图像。 -
cv2.IMREAD_UNCHANGED
:读取图像包括alpha通道。注:alpha通道表示透明度通道
图像显示用cv2.imshow( )函数 原型是cv2.imshow(window_name, image)
,其中window_name
是窗口名称,image
是要显示的图像。其相关代码:
cv2.imshow('Image Window', img)
cv2.waitKey(0) # 等待键盘输入,参数为0表示无限等待
cv2.destroyAllWindows() # 关闭所有创建的窗口
2.图像的复制和保存
图像的保存是cv2.imwrite( )函数,原型是cv2.imwrite(filename, img, params)
,其中filename
是要保存的文件名,img
是要保存的图像,params
是针对特定格式的参数 注:若为填写params参数则会安装对应图片的默认值来设置,如JPEG图像的质量(0 - 100的整数,默认95)
图像的复制用img.copy( )方法,返回一个副本. 如 img_copy = img.copy()
3.图像颜色空间的转换
这个转换是图像处理的一个重要环节,opencv提供了cv2.cvtColor( )函数来实现不同颜色空间之间的转换。原型是cv2.cvtColor(src, code, dstCn=None)
,其中src
是输入图像,code
是颜色空间转换的代码,dstCn
是目标图像的通道数,若dstCn=None则可能表示由函数根据源图像或其他条件自动确定目标图像的通道数。例如将BGR图像转换为灰度图像的代码如下:
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
4.图像的基本运算
4.1 图像的算数运算
图像的算术运算是图像处理的基础操作,包括加减乘除等。
图像的加法: 可以使用cv2.add( ) 常用于图像的合成,也可以调整图像的亮度
例如 result = cv2.add(img1, img2)
图像的减法: 可以使用cv2.substract( ) 常用于图像的背景消除,也可以用于检测图像之间的差异 在视频监控中检测运动的物体 例如 result = cv2.subtract(img1, img2)
图像的乘法: 可以使用cv2.multiply( ) 常用于图像的对比度增强,也可以用于图像的融合
例如 乘以参数2 result = cv2.multiply(img, 2)
图像的除法: 可以使用cv2.divide( ) 常用于图像的归一化,将图像的像素值归一化到0-1之间,也可用于图像的去雾 例如 result = cv2.divide(img, 2)
4.2 图像的位运算
图像位运算是对图像像素二进制位进行操作的运算,包括按位与、按位或、按位异或、按位非等
按位与: 可以用cv2.bitwise_and( )用于图像的掩膜操作
掩膜操作的核心原理在于利用掩膜图像的像素值来控制原图像像素的保留或舍弃,具体来说:
- 像素值为 0 的区域:在掩膜图像中像素值为 0 的位置,原图像对应位置的像素会被忽略或者置为 0。
- 像素值为非零的区域:在掩膜图像中像素值为非零的位置,原图像对应位置的像素会被保留或者进行特定处理。
例如图像img与掩膜mask进行按位与运算
result = cv2.bitwise_and(img, img, mask=mask)
cv2.bitwise_and
函数接收三个参数,前两个参数img
代表参与按位与运算的图像,一般是同一幅图像。- 第三个参数
mask
是一个二值图像,它的作用是指定哪些像素需要参与运算。只有在mask
中值为非零的像素才会进行按位与运算,而值为零的像素会被置为零。 - 函数的返回值
result
是经过按位与运算之后得到的图像。
按位或: 可以用result = cv2.bitwise_or( ) 按位或运算用于图像的合成,还可以用于图像的逻辑运算 判断两个图像的像素是否满足至少一个条件。 result = cv2.bitwise_or(img1, img2)
按位异或: 可以用cv2.bitwise_xor( ) 常用于图像的异常检测 result = cv2.bitwise_xor(img1, img2)
按位非: 可以用cv2.bitwise_not( ) 常用于图像的反相处理,如将图像的亮部变为暗部,还用于图像的逻辑运算,如对图像的像素进行取反操作 result = cv2.bitwise_not(img)
三、实现的功能及其应用领域
opencv是一个开源的计算机视觉和机器学习的软件库,拥有的优化算法涵盖图像处理、视频分析、特征提取与匹配、机器学习、三维重建与增强现实等多个领域
应用领域: 包括人机互动、物体识别、图像分割、人脸识别、动作识别、运动跟踪、机器人视觉、运动分析、机器视觉、结构分析、汽车安全驾驶等计算机视觉领域,以及图像数据操作、矩阵和向量操作、动态数据结构、基本的GUI功能、图像标注等计算机操作底层技术。