利用计算机处理图像信息,我们必须要先了解计算机如何阅读图片信息。
我们都知道,在计算机的世界中只存在0和1两个元素,因此,为了能让计算机读懂图片,我们需要把图片转换成数字。右击图片,选择属性-详细信息,我们得到了一张图片的基本信息。
图片与其像素信息(图片437KB)
分辨率:照片长宽(长×宽),单位为像素
dpi:每英寸像素点数(Dots Per Inch),表示该图片的解析度
位深度:位深度是指在记录数字图像的颜色时,每个像素的所储存的信息大小
对于最基础的黑白色的图片,每个像素只需要考虑自己是白色还是黑色,因此,位深度可以为1 bit,每个像素用0(白色)或1(黑色)表示,可以得到下面这张图片:
1bit位深度的图片与其信息(图片18.7KB)
该图片事实上仅有0和1两个元素,即每个像素非黑即白,然而观察图片,却能看出灰色甚至其他颜色。这主要得益于人类大脑强大的脑部功能,自动处理了过渡区域的颜色变化。不过还是可以看出这张图好像打了马赛克一样,变得更模糊了。(大家可以放大这张图片看一看,可以看到许多黑点白点)
1-bit位深度的黑白照片很显然还是比较粗糙的,如果想要刻画出一张黑白照片的细节,则可以增加数据量,用一个字节(8-bit)来表示一个像素的数据。此时(00000000)2表示白色,(11111111)2(即十进制255)表示黑色,中间所有的数表示不同的灰度。
8bit位深度的图片与其信息(图片78.5KB)
可以发现上面的图片细节更加丰富,相对应的照片也更大了。
8-bit位深度的图片已经可以很好的展示黑白图像,但是如果想要展示彩色的照片,一个字节是不够的。为了确定颜色的数字化方式,国际照明委员会(CIE)确定了一套加色混色模型。
研究发现,我们眼睛的视网膜视锥细胞是可以分辨入射光线颜色变化的。
常人一般拥有三种类型的视锥细胞,每种类型的细胞能够识别出一种颜色——红色、绿色或蓝色,因此我们这样的普通人也被称为“三色视者”。
每种类型视细胞经过不同波长的光发生不同的连锁反应,引起视觉。三种视细胞被激活并往神经中枢(大脑)输送信息。大脑收集联合各种信号,并产生色觉,然后言语描述出来我们目及的是哪种颜色。
因此,我们通过不同比例的红绿蓝(RGB)三种光的混合模拟出所有颜色,每个颜色需要用3个字节(24-bit)表示,就得到了下面这张彩图:
24bit位深度的图片与其信息(图片232KB)
RGB混合模式目前最主流的一种颜色模型,但是该模型并不是唯一的颜色混合模型。因此,如果运用其他颜色模型存储彩色照片,就会出现其他位深度的图片。
各种颜色模型以及它们的内在关系
本机环境:
python 3.9
opencv库 4.5.2.52
pycharm community edition
库下载方式:
在终端输入:
pip install opencv-python
导入相应的库:
import numpy as np
import cv2
当cv2下没有出现红色下划线,表示安装成功。
通过调用opencv中的imread方法,可以实现读取图片的二进制代码:
img = cv2.imread(filename, flags)
# filename是图片的路径
# flags可以不用填写,默认flags是cv2.IMREAD_COLOR
阳光猫猫.png (400*400 px)
通过print函数,我们可以看到图片已经转化成一个矩阵:
print(img)
# [[[ 75 116 163]
# [ 76 117 162]
# [ 80 121 166]
# ...
# [ 57 72 93]
# [ 63 74 92]
# [ 66 75 90]]
#
# [[ 72 111 158]
# [ 74 114 159]
# [ 80 119 165]
# ...
# [ 60 73 97]
# [ 67 77 95]
# [ 71 78 93]]
#
# ...
#
# [[113 94 106]
# [ 98 79 93]
# [ 97 79 94]
# ...
# [116 127 136]
# [132 140 153]
# [155 162 175]]]
可以发现,这个格式是一个numpy矩阵,因此我们可以调用numpy里的一些方法,帮助我们理解这个图片每个数据的含义
print(type(img))
#
# 这是一个numpy矩阵
首先,先要弄清楚这个矩阵有几行几列
print(img.shape)
# (400, 400, 3)
可以看到这个矩阵有400行,400列,并且每个行列内的元素由3个数字构成。
对应我们的图片可以发现,矩阵行数对应图片的宽度(两者都对应竖直方向),矩阵的列数对应图片的宽度(两者对应的列数),数字3,则表示图像每一个像素点由3个字节表示,在RGB体系中表示构成该颜色的红绿蓝值注2。
[注2] 在opencv中,每个像素点色彩的混合顺序是BGR,而不是主流的RGB。
imread方法中需要传入的第二个参数是flags,可以理解成对图片的读取模式,最常用的两个如下:
cv2.IMREAD_COLOR # 原大小,全色彩 shape=(400, 400, 3)
cv2.IMREAD_GRAYSCALE # 原大小,黑白 shape=(400, 400)
读取图片,本质上是把图片信息转换成矩阵,矩阵的行列长度为图片的宽与长,矩阵每一个元素表示对应像素点位置的颜色信息。图像处理,本质上就是对矩阵进行各种变换处理,再转换成图片。
如果暂时预览图片的话,可以利用imshow的方法,弹出GUI窗口,具体方法如下:
cv2.imshow(winname, mat)
# winname是弹窗的标题,这里可以写任意字符
# mat(matrix)是我们的图片矩阵,需要输入矩阵形式的图片
但是当我们直接运行程序的时候,会发现我们的窗口会一闪而过,根本无法预览,这是因为我们需要设置弹窗一个等待时间。
cv2.imshow(winname, mat)
cv2.waitKey()
# 括号内可以传入一个整数,表示窗口停留的毫秒数,也可以空着
# 如果是0或负数,则会一直保持。
通过使用cv2里的imwrite方法,可以实现矩阵写入图片的功能,具体方法如下:
cv2.imwrite(filename, img, params=None)
# filename是图片的保存路径
# img是图片的矩阵形式
# params一般不用,可不写
例如,我想要保存保存一张图片的黑白照片,可以这样处理:
in_path = 'in.png'
out_path = 'out.png'
img = cv2.imread(in_path, cv2.IMREAD_GRAYSCALE)
# 把图片转化成矩阵,只读取灰度
cv2.imwrite(out_path, img)
# 把img矩阵保存到out_path里面
图像处理,本质上就是对矩阵进行各种变换处理,再转换成图片。
python库的准备:cv2(图像处理),numpy(矩阵处理)
读取图片:cv2.imread(图片转变成矩阵)
预览图片:cv2.imshow, cv2.waitKey
保存图片:cv2.imwrite(矩阵转变为图片)
下一章将向大家深入介绍图片处理的各种细节。
OpenCV в Python. Часть 1 [https://habr.com/ru/post/519454]
什么是位深度?[https://etc.usf.edu/techease/win/images/what-is-bit-depth]
各种颜色模型以及它们的内在关系 [https://blog.csdn.net/qq_35247586/article/details/109919637]
三色视者与四色视者身后的理论基础:色彩原理 [https://www.cnblogs.com/zhoulujun/p/11334489.html]