Python学习笔记 | opencv图像处理(一)

1. 计算机数据——图片


1.1 图片信息解读

利用计算机处理图像信息,我们必须要先了解计算机如何阅读图片信息。

我们都知道,在计算机的世界中只存在0和1两个元素,因此,为了能让计算机读懂图片,我们需要把图片转换成数字。右击图片,选择属性-详细信息,我们得到了一张图片的基本信息。

Python学习笔记 | opencv图像处理(一)_第1张图片

图片与其像素信息(图片437KB)

分辨率:照片长宽(长×宽),单位为像素

dpi:每英寸像素点数(Dots Per Inch),表示该图片的解析度

位深度:位深度是指在记录数字图像的颜色时,每个像素的所储存的信息大小

1.2 深入理解位深度

1.2.1 1-bit位深度

对于最基础的黑白色的图片,每个像素只需要考虑自己是白色还是黑色,因此,位深度可以为1 bit,每个像素用0(白色)或1(黑色)表示,可以得到下面这张图片:
Python学习笔记 | opencv图像处理(一)_第2张图片

1bit位深度的图片与其信息(图片18.7KB)

该图片事实上仅有0和1两个元素,即每个像素非黑即白,然而观察图片,却能看出灰色甚至其他颜色。这主要得益于人类大脑强大的脑部功能,自动处理了过渡区域的颜色变化。不过还是可以看出这张图好像打了马赛克一样,变得更模糊了。(大家可以放大这张图片看一看,可以看到许多黑点白点)

1.2.2 8-bit位深度

1-bit位深度的黑白照片很显然还是比较粗糙的,如果想要刻画出一张黑白照片的细节,则可以增加数据量,用一个字节(8-bit)来表示一个像素的数据。此时(00000000)2表示白色,(11111111)2(即十进制255)表示黑色,中间所有的数表示不同的灰度。
Python学习笔记 | opencv图像处理(一)_第3张图片

8bit位深度的图片与其信息(图片78.5KB)

可以发现上面的图片细节更加丰富,相对应的照片也更大了。

1.2.3 24-bit位深度

8-bit位深度的图片已经可以很好的展示黑白图像,但是如果想要展示彩色的照片,一个字节是不够的。为了确定颜色的数字化方式,国际照明委员会(CIE)确定了一套加色混色模型。

研究发现,我们眼睛的视网膜视锥细胞是可以分辨入射光线颜色变化的。
常人一般拥有三种类型的视锥细胞,每种类型的细胞能够识别出一种颜色——红色、绿色或蓝色,因此我们这样的普通人也被称为“三色视者”。
每种类型视细胞经过不同波长的光发生不同的连锁反应,引起视觉。三种视细胞被激活并往神经中枢(大脑)输送信息。大脑收集联合各种信号,并产生色觉,然后言语描述出来我们目及的是哪种颜色。

因此,我们通过不同比例的红绿蓝(RGB)三种光的混合模拟出所有颜色,每个颜色需要用3个字节(24-bit)表示,就得到了下面这张彩图:

Python学习笔记 | opencv图像处理(一)_第4张图片

24bit位深度的图片与其信息(图片232KB)

1.2.4 其他位深度

RGB混合模式目前最主流的一种颜色模型,但是该模型并不是唯一的颜色混合模型。因此,如果运用其他颜色模型存储彩色照片,就会出现其他位深度的图片。

Python学习笔记 | opencv图像处理(一)_第5张图片

各种颜色模型以及它们的内在关系

2. opencv入门


2.1 环境介绍

本机环境:

  • python 3.9

  • opencv库 4.5.2.52

  • pycharm community edition

库下载方式:

在终端输入:

pip install opencv-python

导入相应的库:

import numpy as np
import cv2

当cv2下没有出现红色下划线,表示安装成功。

2.2 读取图片

通过调用opencv中的imread方法,可以实现读取图片的二进制代码:

img = cv2.imread(filename, flags)
# filename是图片的路径
# flags可以不用填写,默认flags是cv2.IMREAD_COLOR

以下图为例,该图片长400像素,宽400像素:
Python学习笔记 | opencv图像处理(一)_第6张图片

阳光猫猫.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)

Python学习笔记 | opencv图像处理(一)_第7张图片

cv2.IMREAD_GRAYSCALE    # 原大小,黑白 shape=(400, 400)

Python学习笔记 | opencv图像处理(一)_第8张图片

读取图片,本质上是把图片信息转换成矩阵,矩阵的行列长度为图片的宽与长,矩阵每一个元素表示对应像素点位置的颜色信息。图像处理,本质上就是对矩阵进行各种变换处理,再转换成图片。

2.3 预览图片

如果暂时预览图片的话,可以利用imshow的方法,弹出GUI窗口,具体方法如下:

cv2.imshow(winname, mat)
# winname是弹窗的标题,这里可以写任意字符
# mat(matrix)是我们的图片矩阵,需要输入矩阵形式的图片

但是当我们直接运行程序的时候,会发现我们的窗口会一闪而过,根本无法预览,这是因为我们需要设置弹窗一个等待时间。

cv2.imshow(winname, mat)
cv2.waitKey()
# 括号内可以传入一个整数,表示窗口停留的毫秒数,也可以空着
# 如果是0或负数,则会一直保持。

2.4 保存图片

通过使用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里面

回顾

  1. 图像处理,本质上就是对矩阵进行各种变换处理,再转换成图片。

  2. python库的准备:cv2(图像处理),numpy(矩阵处理)

  3. 读取图片:cv2.imread(图片转变成矩阵)

  4. 预览图片:cv2.imshow, cv2.waitKey

  5. 保存图片:cv2.imwrite(矩阵转变为图片)

下一章将向大家深入介绍图片处理的各种细节。

参考资料

  1. OpenCV в Python. Часть 1 [https://habr.com/ru/post/519454]

  2. 什么是位深度?[https://etc.usf.edu/techease/win/images/what-is-bit-depth]

  3. 各种颜色模型以及它们的内在关系 [https://blog.csdn.net/qq_35247586/article/details/109919637]

  4. 三色视者与四色视者身后的理论基础:色彩原理 [https://www.cnblogs.com/zhoulujun/p/11334489.html]

你可能感兴趣的:(python之opencv,opencv,python,深度学习)