图像的读写与显示
读取图像
使用函数 cv.imread()
来读取图像,该函数共两个参数
- 图像的路径
- 图像的读取方式
cv.IMREAD_COLOR
加载彩色图像,图像的任何透明度都将被忽略。这是默认标志cv.IMREAD_GRAYSCALE
以灰度模式加载图像cv.IMREAD_UNCHANGED
加载图像,包括alpha
通道
例:
1 |
import cv2 as cv |
警告:如果图像路径错误,它将不会引发任何错误,但是会返回一个空值
显示图像
使用函数 cv.imshow()
在窗口显示图像,窗口自动适合图像尺寸。该函数共两个参数。
- 窗口名称
- 要显示的图像
可以根据需求创建任意多个窗口,但需要使用不同的窗口名称
例:
1 |
cv.imshow('image', img) |
cv.waitkey()
等待按键按下功能,其参数是时间(以毫秒为单位),默认为0,即永远等待。
cv.destoryAllWindows()
用来回收我们创建的所有窗口。
保存图像
使用函数cv.imwrite()
来保存图像,该函数共两个参数。
- 文件名
- 需要保存的图像
1 |
cv.imwrite('2.jpg', img) |
图像的基本操作
来源:https://docs.opencv.org/4.1.2/d3/df2/tutorial_py_basic_ops.html
本节中的大部分操作都与numpy
相关,因为要操作图像数据,而图像数据就是一个np.ndarray
的数组。
注意:在OpenCV中图像都处于GBR模式,使用这种方式的是因为历史遗留问题,在早年大部分的照相机制造商和软件供应商中流行的就是BGR模式, OpenCV为了迎合当时开发者的习惯就是用了BGR模式,然而在当今这个时代RGB又流行了起来,OpenCV已经无法在兼容RGB模式了,所以只能这样将就着使用GBR模式了
访问和修改像素值
1 |
import numpy as np |
警告:Numpy是用于快速数组计算的优化库。因此,简单的访问每个元素并对其进行修改是非常缓慢的,不建议这样使用。
更好的访问像素值和修改像素值的方法
1 |
# 访问 RED 的值 |
访问图像属性
图像的属性包括:行、列、通道数、图像的数据类型、像素数等等
图像的形状可以通过img.shape
访问。它返回行,列和通道数的元组(如果是彩色的图像)
1 |
print(img.shape) |
注意:如果图像是灰度的,则返回的元组只会包含行和列,因此这是检测加载的图像是灰度还是彩色的好方法。
像素总数可以通过img.size
进行获取:
1 |
print(img.size) |
图像数据类型可以通过img.dtype
进行获取
1 |
print(img.dtype) |
注意: img.dtype
在调试的时候非常重要,因为OpenCV-Python代码中大部分的错误可能都是因为无效数据类型引起的。
图像ROI(Region Of Internest)
有时候我们需要使用图像的某个区域,这是可以通过NumPy索引的方式获取ROI
1 |
# 获取图像第220行到500行,250行到620行的图像 |
注意:如果对裁剪区域内容进行修改,这个值也会反馈裁剪之前的图像数组,因为在NumPy中默认使用的是引用拷贝的方式,所以在需要对特定的区域修改的时候,我们可以将其裁剪出来,然后在更小的区域做处理,这样可以提高我们修改的速度和准确性。
分割和合并图像通道
有的时候需要分别处理图像的G、B、R通道。可以使用以下方法做到这一点:
1 |
# 拆分 |
警告:cv.split()
是一项非常耗时的操作,相比于numpy的索引而言,实测速度大约相差百倍,数据量大的情况下可以到几百倍。
为图像设置边框(填充)
如果要在图像周围创建边框,则可以使用 cv.copyMakeBorder()
。但是它在卷积运算,零填充等方便有更多的运用。该函数共7个参数:
src
输入的图像top
上边界宽度bottom
下边界宽度left
左边界宽度right
右边界宽度borderType
边界类型cv.BORDER_CONSTANT
添加恒定的色彩边框cv.BORDER_REFLECT
边框是边框元素的镜像,例如:fedcba | abcdefgh |hgfedcbcv.BORDER_REFLECT_101
或cv.BORDER_DEFAULT
,与上述基本相同,但是略有变化。例如:gfedcb | abcdefgh | gfedcbacv.BORDER_REPLICATE
最后一个元素被复制,例如:aaaaaa | abcdefg | ggggggcv.BORDER_WRAP
例如:cdefgh | abcdefgh | abcdefg
value
颜色值,类型为cv.BORDER_CONSTANT
有效
图像上的算术运算
来源:https://docs.opencv.org/4.1.2/d0/d86/tutorial_py_image_arithmetics.html
图像加法
图像的加法可以通过OpenCV函数cv.add()
或仅通过NumPy操作(res = img1 + img2)。两个图像应该具有相同的深度和类型,或者第二个图像可以只有一个标量。
注意:OpenCV的加法是饱和运算,而NumPy的加法是模运算,简单的讲就是,当相加的结果超过255的时候,OpenCV的相加的值为255,而NumPy相加的值为其取模的值
图像融合
这也类似于图像的加法,但是对图像赋予的权重不同,以使其具有融合或者透明的感觉。根据以下等式添加图像:
$$
g(x)=(1-\alpha)f_{0}(x)+(\alpha)f_{1}(x)
$$
在
OpenCV 中,我们可以使用cv.addWeighted()
函数来达到图像融合的效果,该函数有7个参数:
src1
:第一个输入的数组alpha
:第一个数组元素的权重src2
:第二个输入的数组beta
:第二个数组元素的权重gamma
:标量,加到每个元素中。dst
:输出数组dtype
:输出的数据类型
大致可以表示为如下方程式:
$$
dst = \alpha \cdot img_{1} + \beta \cdot img_{2} + \gamma
$$