数字图像的表达
一副数字图像可以用一个二维的数组来表示,其中的每一个元素对应一个像素,比如将一个2D图像写作一个
i
×
j
i \times j
i×j 矩阵(其中
i
,
j
i,j
i,j 分别代表图像的总行数和总列数)
F
=
[
f
11
f
12
⋯
f
1
j
f
21
f
22
⋯
f
2
j
⋮
⋮
⋮
f
i
1
f
i
2
⋯
f
i
j
]
F = \left[ \begin{matrix} f_{11} & f_{12} &\cdots & f_{1j} \\ f_{21} & f_{22} &\cdots & f_{2j} \\ \vdots & \vdots & &\vdots \\ f_{i1} & f_{i2} & \cdots & f_{ij} \end{matrix} \right]
F=
f11f21⋮fi1f12f22⋮fi2⋯⋯⋯f1jf2j⋮fij
矩阵中的每一个元素都对应一个像素,在 OpenCV 里面,像素是由R,G,B三个数组成
f
i
j
=
[
r
i
j
g
i
j
b
i
j
]
f_{ij} = \left[ \begin{matrix} r_{ij} & g_{ij} & b_{ij} \end{matrix} \right]
fij=[rijgijbij]
用 python 和 OpenCV 来将图片转化为数组,这里的图片使用的是相对路径
import cv2 as cv
image = cv.imread("Paimon_01.jpg")
print(image)
运行结果
可以看到返回的是一个三维数组,打印原图像
cv.imshow("原图", image)
cv.waitKey(0)
运行结果
图片来源于网络,若有侵权请联系删除
灰度图像
任何颜色都由红、绿、蓝三原色组成,而灰度图只有一个通道,他有256个灰度等级,在 Windows 操作系统中将红绿蓝三个通道的数值设定为相同值就可以看到其对应的灰度效果
为了更好的得到灰度图像,我们要采用 Gamma 校正,因为人眼对于亮度的感知和物理功率不成正比,而是幂函数的关系,这个函数的指数通常为2.2,称为 Gamma 值
Gamma 矫正算法
G
r
a
y
=
R
2.2
+
(
1.5
G
)
2.2
+
(
0.6
B
)
2.2
1
2.2
+
1.
5
2.2
+
0.
6
2.2
Gray = \sqrt{\dfrac{R^{2.2} + (1.5G)^{2.2} + (0.6B)^{2.2}}{1^{2.2} + 1.5^{2.2} + 0.6^{2.2}}}
Gray=12.2+1.52.2+0.62.2R2.2+(1.5G)2.2+(0.6B)2.2
为了方便,我们采用浮点法进行近似计算
G
r
a
y
=
R
∗
0.299
+
G
∗
0.587
+
B
∗
0.114
Gray = R * 0.299 + G * 0.587 + B * 0.114
Gray=R∗0.299+G∗0.587+B∗0.114
同时将 R, G, B 设为 Gray,使得表现为灰度图像
import cv2 as cv
image = cv.imread("Paimon_01.jpg")
R = image[:, :, 0]
G = image[:, :, 1]
B = image[:, :, 2]
Y = R * 0.299 + G * 0.587 + B * 0.114
gray = image.copy()
gray[:, :, 0] = Y
gray[:, :, 1] = Y
gray[:, :, 2] = Y
# cv.imshow("原图", image)
cv.imshow("灰度图", gray)
cv.waitKey(0)
运行结果
二值图像
二值图像是指将图像上的每一个像素只有两种可能的取值或灰度等级状态,本文所用的二值图像为黑白图像,即图像中的任何像素点的灰度值均为0或者255,分别代表黑色和白色
我们将上面的灰度图转化为二值图像,当像素值小于阈值设置其为0,也就是黑色,否则为255,也就是白色
binary_image = gray.copy()
height, width = gray.shape[0:2]
threshold = 200 # 设置阈值
for row in range(height):
for col in range(width):
if binary_image[row, col, 0] < threshold:
binary_image[row, col, 0] = 0
binary_image[row, col, 1] = 0
binary_image[row, col, 2] = 0
else:
binary_image[row, col, 0] = 255
binary_image[row, col, 1] = 255
binary_image[row, col, 2] = 255
cv.imshow("二值图像", binary_image)
cv.waitKey(0)
运行结果
不同的阈值对于图片的影响效果不一样,取值范围为
(
0
,
255
)
(0, 255)
(0,255),阈值越大,图片中黑色部分也就越多
总结
从彩色图像到灰度图像再到二值图像,图片中所能蕴含的信息越来越少,同时也会使得某些图像处理的计算量变得更少,当然,OpenCV有自带得可以处理这些图像的函数,已经有许多优秀的博客有这方面的内容,本文主要是对其原理进行大概的总结,故并不多述
参考文献
[1] 章毓晋.计算机视觉教程[M].北京:人民邮电出版社,2021.1:7-8
[2] 链接:灰度图像百度百科
[3] 链接:二值图像百度百科