很重要!
scikit-image的开发文档:https://scikit-image.org/docs/stable/api/api.html
长这样婶儿:
腾讯云的scikit-image教程:https://cloud.tencent.com/developer/doc/1221
南加大的图片数据源:http://sipi.usc.edu/database/database.php
比如论文中常见的山魈(Mandrill):
第一章 基础知识
from skimage import data, io
image = data.coffee()
# io.imshow(image[:, :, 1])
io.imshow(image)
io.show()
运行结果:
1.1 图像采样和量化
图像采样
图像采样是对图像空间位置的数字化,需要确定水平和垂直方向上分割出像素的数量(又称为分辨率)。
一般而言,采样间隔越大,所得图像像素数越少,空间分辨率低,图像质量差,严重时出现马赛克效应;采样间隔越小,所得图像像素数越多,空间分辨率高,图像质量好,但数据量较大。
使用求均值方法进行图像模拟采样的代码如下:
from skimage import data
from matplotlib import pyplot as plt
import numpy as np # 导入所需的类包
image = data.coffee() # 载入测试图像
print(image.shape) # 显示图像原始大小
print(type(image)) # 显示图像类型
ratio = 20 # 设置采样比率
image1 = np.zeros((int(image.shape[0]/ratio), int(image.shape[1]/ratio),
image.shape[2]), dtype='int32') # 设置采样后的图像大小
for i in range(image1.shape[0]):
for j in range(image1.shape[1]):
for k in range(image1.shape[2]):
# 获取需要采样的图像块
delta = image[i*ratio:(i+1)*ratio, j*ratio:(j+1)*ratio, k]
image1[i, j, k] = np.mean(delta) # 计算均值,并存入结果图像
plt.imshow(image1)
plt.show()
采样比率=10时的采样结果:
采样比率=20时的采样结果:
采样比率=40时的采样结果:
笔者阅读原书时,作者并没有对采样比率一词进行说明,根据笔者的实验结果,这里的采样比率应该就是采样间隔(或者是和采样间隔正相关的一个量):我们发现,随着采样比率的增加,图像空间分辨率越来越低,马赛克越来越严重。
图像量化
模拟图像经过采样后,在空间上实现了离散化,并形成像素。但采样所得的像素值(即灰度值)仍旧是连续量。采样后所得的各像素的灰度值从连续量到离散量的转换称为图像灰度的量化。
图像的像素值(响应值) I ( x , y ) I(x,y) I(x,y)的数字化被称为图像的量化,即把图像响应值 I ( x , y ) I(x,y) I(x,y)从 I m i n I_{min} Imin到 I m a x I_{max} Imax的实数域映射为有限级别的离散数值。
与图像量化相关的度量称为灰度级。灰度级(灰度层次)是表示像素明暗程度的整数量。例如,像素的取值范围是0~255,就称该图像是256个灰度级的图像。
图像数据的实际灰度层次越多,视觉效果越好。常用的有256级灰度量化、64级灰度量化、16级灰度量化等。
图像量化的python代码:
from skimage import data
from matplotlib import pyplot as plt
image = data.coffee()
ratio = 128 # 设置量化比率
for i in range(image.shape[0]):
for j in range(image.shape[1]):
for k in range(image.shape[2]):
# 对图像中的每个像素进行量化
image[i][j][k] = int(image[i][j][k]/ratio)*ratio
plt.imshow(image)
plt.show()
该代码将256级灰度的彩色图像量化到仅有2级灰度的彩色图像。
图像的量化比率决定了图像的颜色精细程度。
目前的一般做法是从图像响应最大值到响应最小值进行均匀量化,划分为若干量化层级。目前常见的量化级数一般为 2 n 2^n 2n,如256或者65536。最小的量化级数为2,即灰度图像转变为二值图像,量化后的图像仅有0和1两种灰度取值。
除均匀量化方法外,也存在非均匀量化。非均匀量化即在灰度级变化剧烈的区域用细粒度量化,而在灰度级比较平滑的区域用粗粒度量化。
量化等级越多,所得图像层次越丰富,灰度分辨率高,图像质量好,但数据量较大;量化等级越少,图像层次欠丰富,灰度分辨率低,可能会出现假轮廓现象,图像质量变差,但数据量较小
1.2 图像的表示和可视化
经过采样和量化之后,图像I已经成为空间位置和响应值均离散的数字图像。图像上的每个位置 ( x , y ) (x,y) (x,y)以及其对应量化响应值称为一个像素.
图像的表示
通过采样和量化,原本连续 I ( x , y ) I(x,y) I(x,y)的图像转换为一个二维阵列 f ( x , y ) f(x,y) f(x,y)该阵列具有M行N列,其中 ( x , y ) (x,y) (x,y)是离散坐标。
来源:岳亚伟,数字图像处理与python实现
一般而言,直接用二维矩阵A来表示量化后的图像
一幅M×N的图像可以表示为矩阵,矩阵中的每个元素称为图像的像素。每个像素都有它自己的空间位置和值,值是这一位置像素的颜色或者强度。
与图像表示相关的重要指标是图像分辨率。
图像分辨率是指组成一幅图像的像素密度。对同样大小的一幅图,组成该图的图像像素数目越多,说明图像的分辨率越高,看起来越逼真。相反,像素越少,图像越粗糙。
图像分辨率包括空间分辨率和灰度级(响应幅度)分辨率。
空间分辨率是图像中可辨别的最小空间细节,取样值多少是决定图像空间分辨率的主要参数。
灰度级分辨率是指在灰度级别中可分辨的最小变化。灰度级数通常是2的整数次幂。通常把大小为M×N、灰度为L级的数字图像称为空间分辨率为M×N像素、灰度级分辨率为L级的数字图像。
图像可视化模块
skimage全称为scikit-image。
Scikit-Image是基于Python的一款图像处理包,它将图片作为数组进行处理。它对scipy.ndimage进行了扩展,提供了更多的图片处理功能,由scipy社区开发和维护。与Opencv相比,skimage更容易安装和使用,对像素的操作和图像整体的操作更符合科学计算要求,所以这里选择使用skimage作为图像可视化工具包。
子模块 | 功能 |
---|---|
io | 读取、保存和显示图片或视频 |
data | 提供一些测试图片和样本数据 |
color | 颜色空间变换 |
filters | 图像增强、边缘检测、排序滤波器、自动阈值等滤波器操作 |
draw | 操作于numpy数组上的基本图形绘制,包括线条、矩形、圆和文本等 |
transform | 几何变换或其他变换,如旋转、拉伸等 |
morphology | 形态学操作,如开闭运算、骨架提取等 |
exposure | 图像强度调整,如亮度调整、直方图均衡等 |
measure | 图像属性的测量,如相似性或等高线 |
segmentation | 图像分割 |
restoration | 图像恢复 |
util | 通用工具函数 |
图像读取
图像读取将图像从磁盘读入内存。skimage通过io模块对图像文件进行读取,读入内存之后的图像放入一个numpy格式的数组内。例如,在当前目录下有一个名为coffee.jpg的图片,读入该图片的代码如下。
from skimage import io
file_name = 'coffee.jpg'
# 将图片读入数组image内
image = io.imread(fname = file_name)
以上代码将文件名为coffee.jpg的图片读入内存,并存放在数组image内,其中imread()函数用于文件的读取,其输入为图像路径,输出为一个名为image的numpy类型对象。可以通过对image进行操作,从而实现对图像的各种处理。
输出图片大小
from skimage import io
file_name = 'coffee.jpg'
# 将图片读入数组image内
image = io.imread(fname = file_name)
print(image.shape)
输出结果
(1333, 2000, 3)
含义为读入的图片大小位1333* 2000, 包含红绿蓝三个通道。
显示图像:
from skimage import io
from matplotlib import pyplot as plt
file_name = 'coffee.jpg'
# 将图片读入数组image内
image = io.imread(fname = file_name)
print(image.shape)
# 进行图片绘制
plt.imshow(image)
# 显示绘制图像
plt.show()
索引操作
通过索引操作可以选择数组内指定位置的元素。Python语言中,一维数组索引下标的取值范围为[0~(数组元素个数-1)]。
索引包括单个元素索引和多个元素索引两种类型。
单个元素索引指定要选择元素的确定行、列、通道位置,取出单个元素。
一维数组单个元素索引操作可以通过数组名[索引位置]形式,取出对应位置元素。
二维矩阵单个元素索引操作通过数组名 [行索引x,列索引y] 形式,取出矩阵第x行第y列元素。
同理,三维数组元素索引方式为数组名 [行索引x,列索引y,通道索引z]形式。对一维、二维数组进行元素索引的示例代码如下。
import numpy as np
array = np.array([2, 3, 4, 5, 6])
print(array[0])
print(array[1])
# 定义二维array
array2 = np.array(
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9],]
)
# 输出二维数组的第二行
print(array2[1, 0])
print(array2[1, 1])
print(array2[1, 2])
多个元素索引可以一次取多个元素。
一维数组多个元素索引通过数组名 [索引起始位置:索引结束位置] 形式取出从索引起始位置到索引结束位置的元素。
二维数组多个元素索引通过数组名 [起始行:结束行,起始列:结束列]形式取出开始行到结束行,起始列到结束列范围之间的元素。
三维数组多个元素索引可通过数组名 [起始行:结束行,起始列:结束列,起始通道:结束通道]形式取出起始行到结束行,起始列到结束列,起始通道到结束通道范围之间的元素。
需要注意的是:多个元素索引时,索引区间是一个前闭后开区间,并不包含结束索引位置的元素。
对一维、二维数组进行多个元素索引的示例代码如下。
import numpy as np
array = np.array([2, 3, 4, 5, 6])
# 输出一维数组下标为0到2的元素
print(array[0: 3])
# 定义二维array
array2 = np.array(
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9],]
)
# 输出二维数组第0到1行,第0到1列
print(array2[0 : 2, 0 : 2 ])
输出结果
[2 3 4]
[[1 2]
[4 5]]
使用多个元素索引可以对图像进行裁剪操作,取出图像的第20到200行,第30到200列的子图像,并进行显示。使用多元素索引对图像进行裁剪的示例代码如下。
注:这里用了三维,因为图片是3维的,而data子模块中有些是二维的。
from skimage import data
from matplotlib import pyplot as plt
image = data.rocket()
image1 = image[20: 200, 30: 200, :]
plt.imshow(image1)
plt.show()
全图:
截取后的图:
1.3 简单图像处理
图像基本属性的操作
数字图像的基本属性包括亮度、对比度、颜色通道等。在数字图像处理中,这些属性操作都可以通过矩阵操作体现。可以通过对图像矩阵的运算,达到对图像基本属性进行操作的目的。
1 亮度操作
亮度也称为灰度,它是颜色的明暗变化范围,常用0%~100%(由黑到白)表示。一般数字图像的像素亮度为0~255,可以通过对像素构成矩阵的灰度值进行操作,达到调整图像亮度的目的。图像亮度调节可以采用最简单的图像处理算法,通过常见的线性运算即可完成亮度调节,如所有像素点亮度值乘以或者加一个增强系数,使得图像整体变亮或者变暗。
2 对比度操作
对比度指的是图像暗和亮的落差值,即图像最大灰度级和最小灰度级之间的差值。对于数字图像变换,设原像素灰度为 f ( i , j ) f(i,j) f(i,j), 转换后的像素灰度为 g ( i , j ) g(i,j) g(i,j),则常用的线性变换为 g ( i , j ) = α × f ( i , j ) + β g(i,j) = \alpha \times f(i,j) + \beta g(i,j)=α×f(i,j)+β,其中系数α影响图像的对比度,系数β影响图像的亮度
- a = 1为原图
- a > 1对比度增强, 图像看起来更加清晰
- a < 1对比度减弱,图像看起来变暗
- β \beta β影响图像的亮度,随着增加β(β>0)和减小β(β>0),图像整体的灰度值上移或者下移,也就是图像整体变亮或者变暗,不会改变图像的对比度。
图像对比度代码测试:
test_contrast.py
from skimage import data
from matplotlib import pyplot as plt
from adjust_contrast import change_alpha
image = data.rocket()
fig, ax = plt.subplots(2, 2)
image1 = change_alpha(image, 1)
ax[0, 0].imshow(image1)
ax[0, 0].set_title("alpha = 1")
image2 = change_alpha(image, 0.2)
ax[0, 1].imshow(image2)
ax[0, 1].set_title("alpha = 0.2")
image3 = change_alpha(image, 0.5)
ax[1, 0].imshow(image3)
ax[1, 0].set_title("alpha = 0.5")
image4 = change_alpha(image, 2)
ax[1, 1].imshow(image4)
ax[1, 1].set_title("alpha = 2")
plt.show()
adjust_contrast.py
改变对比度的函数,时间复杂度 O ( n 3 ) O(n^3) O(n3)
import numpy as np
def change_alpha(im, a):
im_changed = np.zeros(shape = im.shape, dtype = 'uint8')
for i in range(im.shape[0]):
for j in range(im.shape[1]):
for k in range(im.shape[2]):
if im[i, j, k] * a > 255:
im_changed[i, j, k] = 255
elif im[i, j, k] * a < 0:
im_changed[i, j, k] = 0
else:
im_changed[i, j, k] = im[i, j, k] * a
return im_changed
运行结果:
运行test_contrast.py文件得到
3 颜色通道操作
数字图像的本质是一个多维矩阵,如彩色图像是一个三维矩阵,灰度图像和黑白图像由二维矩阵表示。彩色图像一般可分为红、绿、蓝3个颜色通道,每个颜色通道对应一个完整的二维矩阵。可以对这3个二维矩阵进行操作,达到操作图像通道的目的。对图像3个颜色通道进行分离的代码如下。
实验代码
from skimage import data, io
from matplotlib import pyplot as plt
image = data.coffee()
image_r = image[:, :, 0]
image_g = image[:, :, 1]
image_b = image[:, :, 2]
plt.subplot(2, 2, 1)
plt.title("origin")
io.imshow(image)
plt.subplot(2, 2, 2)
plt.title("channel r")
io.imshow(image_r)
plt.subplot(2, 2, 3)
plt.title("channel g")
io.imshow(image_g)
plt.subplot(2, 2, 4)
plt.title("channel b")
io.imshow(image_b)
plt.show()
运行结果
图像的简单运算
图像运算是以图像为单位对图像进行的数学操作,是数字图像信号处理的基础,运算对象以像素点为基本单位,运算结果为一幅灰度分布与原图像不同的新图像。
图像的简单运算包括算术运算和逻辑运算。常见的算术运算包括点运算、幂运算、直方图运算等。
1 算术运算和逻辑运算
算术运算和逻辑运算中每次只涉及一个空间像素的位置,所以可以“原地”操作,即在(x,y)位置做一个算术运算或逻辑运算的结果可以存在其中一个图像的相应位置。
图像加减运算实验
from skimage import data
from matplotlib import pyplot as plt
moon = data.moon()
camera = data.camera()
image_minus = moon - camera
image_plus = moon + camera
plt.subplot(2, 2, 1)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.title('月亮图像')
plt.imshow(moon)
plt.subplot(2, 2, 2)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.title('摄影师图像')
plt.imshow(camera)
plt.subplot(2, 2, 3)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.title('月亮加摄影师图像')
plt.imshow(image_plus)
plt.subplot(2, 2, 4)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.title('月亮减摄影师图像')
plt.imshow(image_minus)
plt.show()
2 点运算
点运算只涉及一幅原图像(称为输入图像),运算对象是输入图像像素的灰度值,即输出图像每个像素的灰度值仅取决于输入图像中对应像素的灰度值。
点运算具有两个特点:
其一,根据某种预先设置的规则,将输入图像各个像素本身的灰度(和该像素邻域内其他像素的灰度无关)逐一转换成输出图像对应像素的灰度值;
其二,点运算不会改变像素的空间位置。
因此,点运算也被称为灰度变换。前一小节讲述的亮度及对比度变换属于点运算的范畴。
点运算又可以分为线性点运算和非线性点运算。
线性点运算的原值和目标值通过线性方程完成转换,典型的如对比度灰度调整、图像反色都属于线性点运算。
非线性点运算对应非线性映射函数,典型的映射包括平方函数、对数函数、截取(窗口函数)、阈值函数、多值量化函数等。灰度幂次变换、灰度对数变换、阈值化处理、直方图均衡化是较常见的非线性点运算方法。
幂次变换又称伽马变换,数学形式为 t = c × s γ t=c×s^γ t=c×sγ,其中 c c c和 γ γ γ是正常数,s代表源图像像素值,t表示变换后的像素值。
γ < 1 γ<1 γ<1提高灰度级,在正比函数上方,使图像变亮。 γ > 1 γ>1 γ>1降低灰度级,在正比函数下方,使图像变暗。
skimage的exposure模块中包含幂次变换的函数adjust_gamma,可以对图像进行幂次变换,实验代码和实验结果如下,幂次变换为非线性变换,可以看到图像中某些部分可以通过幂次变换凸显出来。
实验结果
源代码
from skimage import data, io, exposure
from matplotlib import pyplot as plt
image = data.coffee()
# 分别计算gamma不同值的图像
image_1 = exposure.adjust_gamma(image, 0.2)
image_2 = exposure.adjust_gamma(image, 0.67)
image_3 = exposure.adjust_gamma(image, 25)
plt.subplot(2, 2, 1)
plt.title("gamma = 1")
io.imshow(image)
plt.subplot(2, 2, 2)
plt.title("gamma = 0.2")
io.imshow(image_1)
plt.subplot(2, 2, 3)
plt.title("gamma = 0.67")
io.imshow(image_2)
plt.subplot(2, 2, 4)
plt.title("gamma = 25")
io.imshow(image_3)
plt.show()
3 图像直方图
直方图中的数值都是统计出来的,描述了该图像中关于颜色的数量特征,可以反映颜色的统计分布和基本色调。
直方图只包含该图像中某一颜色值出现的频数,而丢失了某像素所在的空间位置信息。
任一幅图像都能唯一地给出一幅与它对应的直方图,但不同的图像可能有相同的颜色分布,从而就具有相同的直方图,因此直方图与图像是一对多的关系。
如将图像划分为若干个子区域,所有子区域的直方图之和等于全图直方图。
一般情况下,由于图像上的背景和前景物体颜色分布明显不同,从而在直方图上会出现双峰特性,但背景和前景颜色较为接近的图像不具有这个特性。
颜色直方图分为三类
- 全局直方图
1)定义:反映的是图像中颜色的组成分布,即出现了哪些颜色以及各种颜色出现的概率。
2)特点:其对图像的旋转、平移、缩放和图像质量变化不敏感,比较适合于检索图像的全局颜色相似性,即通过比较颜色直方图的差异衡量两幅图像在颜色全局分布上的差异。 - 累加直方图
1)背景:图像中的特征并不能取遍所有可取值时,统计直方图中会出现一些零值。这些零值的出现会对相似性度量的计算带来影响,从而使得相似性度量并不能正确反映图像之间的颜色差别。
2)适用:累加直方图消除了一般直方图中常见的零值,也克服了一般直方图量化过细、过粗检索效果都会下降的缺陷。 - 主色调直方图
1)原理:一幅图像中,往往少数几种颜色就涵盖了图像的大多数像素,而且不同颜色在图像中的出现概率是不同的,可以通过统计图像中各种颜色出现的概率选出最频繁出现的几种颜色作为主色。
2)具体:颜色直方图可以是基于不同的颜色空间和坐标系。RGB空间结构不符合人们对颜色相似性的主观判断。有人提出了基于HSV空间、Luv空间和Lab空间的颜色直方图,因为它们更接近人们对颜色的主观认识。其中HSV空间是直方图最常用的颜色空间。它的3个分量分别代表色彩(Hue)、饱和度(Saturation)和值(Value)。
计算颜色直方图需要将颜色空间划分成若干个小的颜色区间,每个小区间成为直方图的一个bin。这个过程称为颜色量化(color quantization)。然后,通过计算颜色落在每个小区间内的像素数量可以得到颜色直方图。
彩色图片三通道直方图
下面是绘制直方图的实验:用的是matploglib下的hist方法绘制直方图。
实验结果
期间,还遇到了hist函数中参数错误的问题,原因是官方对其进行了更新,不过问题得以解决。请移步笔者另一篇博文,那里有详细的记录。
python中matplotlib关于直方图AttributeError: ‘Rectangle‘ object has no property ‘normed‘的解决方法
from skimage import data, io
import matplotlib
import matplotlib.pyplot as plt
# 设置matplotlib正常显示中文和负号
matplotlib.rcParams['font.sans-serif']=['SimHei'] # 用黑体显示中文
matplotlib.rcParams['axes.unicode_minus']=False # 正常显示负号
image=data.coffee()
# flatten 将矩阵降维一维
hist_r=image[:,:,0].flatten()
hist_g=image[:,:,1].flatten()
hist_b=image[:,:,2].flatten()
plt.subplot(2, 2, 1)
plt.title("原图")
io.imshow(image)
# data = np.random.randn(10000)
plt.subplot(2, 2, 2)
plt.title("R通道颜色直方图")
plt.hist(hist_r, bins = 40, density=True,facecolor="red", edgecolor="black", alpha=0.7)
plt.subplot(2, 2, 3)
plt.title("G通道颜色直方图")
plt.hist(hist_g, bins = 40, density=True,facecolor="green", edgecolor="black", alpha=0.7)
plt.subplot(2, 2, 4)
plt.title("B通道颜色直方图")
plt.hist(hist_b, bins = 40, density=True,facecolor="blue", edgecolor="black", alpha=0.7)
plt.show()
这幅图和原书中还是很像的,说明实验较为成功!
直方图在图像处理中的常见应用包括:直方图均衡化、直方图拉伸及直方图匹配。
1) 直方图均衡化
直方图均衡化是通过使用累积函数对灰度值进行“调整”,以实现对比度的增强。
直方图均衡化处理的“中心思想”是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。
实际上,直方图均衡化是对图像进行非线性拉伸。
2) 直方图拉伸
直方图拉伸的主要作用是将灰度间隔小的图像的灰度间隔扩大,以便于观察图像。
直方图拉伸是通过对比度拉伸对直方图进行调整,从而“扩大”前景和背景灰度的差别,以达到增强对比度的目的。
3)直方图匹配
直方图匹配又称为直方图规定化,是指把原图像的直方图变换为某种指定形态的直方图或某一种参考图像的直方图,然后按照已知直方图调整原图像各个像元的灰度值,最后得到一幅直方图匹配的图像。
下面是直方图均衡化的实验
实验结果:
我们发现均衡化之后,图片的对比度增强;直方图的对比也可以发现,均衡化后的灰度分布更加均匀。
实验代码:
from skimage import data, exposure
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
img = data.moon()
plt.figure("hist", figsize=(8,8))
arr = img.flatten()
plt.subplot(221)
# 原始图像
plt.imshow(img, plt.cm.gray)
plt.title("原始图像")
plt.subplot(222)
# 原始图像直方图
plt.hist(arr, bins=256, density=True, edgecolor='None',facecolor='red')
plt.title("原始图像直方图")
img1 = exposure.equalize_hist(img)
arr1 = img1.flatten()
plt.subplot(223)
# 均衡化图像
plt.imshow(img1, plt.cm.gray)
plt.title("均衡化图像")
plt.subplot(224)
# 均衡化直方图
plt.hist(arr1, bins=256, density=True, edgecolor='None',facecolor='red')
plt.title("均衡化直方图")
plt.show()
图像卷积操作
图像卷积操作是图像空间域滤波的基础运算,也是当前许多深度特征提取算法的基础。卷积操作就是循环将图像和卷积核逐个元素相乘再求和,结果得到卷积后图像的过程。
如图1-21所示,一幅6×6的图像使用1个3×3的卷积核进行卷积操作,结果得到一个4×4的卷积图像。
假设卷积核使用K表示,大小为(m×n);原始图像表示为S,大小为(M×N);结果图像表示为T,则卷积操作公式如下:
卷积操作中,卷积核在原始图像上做从上到下、从左到右的滑动扫描,每次扫描使用卷积核与其扫描覆盖区域图像做一次卷积运算,然后再移动到下一个位置进行下一次扫描,直到扫描完毕。
图片来源:《数字图像处理与python实现》,下同
大部分Python图像处理相关包均将卷积函数集成到其特征提取或滤波模块中,并对卷积操作进行了许多优化,因此读者可以直接调用,无须自己实现。
参考
[1]python skimage图像处理(一)
[2]岳亚伟《数字图像处理与python实现》
转载:https://blog.csdn.net/shizheng_Li/article/details/115952315