在python中进行图像处理,我们有三个好工具:OpenCV, SciKit-Image 和 Pillow。但是在本文中,为了理解一些简单图像处理技术的基础,我们将使用numpy。所以这也是练习numpy的良好教程。
涵盖知识:
图像读取与裁剪,通道分离,颜色变换(爱因斯坦求和约定),动态gif生成,灰阶转换
图像卷积, 图像分割(大津二值,KMeans像素聚类),图像矢量化(轮廓提取,内边缘判断,轮廓填充)
导入库并加载图像
import numpy as np
import matplotlib.pylab as plt
# 加载图像
im = plt.imread("BTD.jpg") # 加载当前文件夹中名为BTD.jpg的图片
print(im.shape) # 输出图像尺寸
# (4608, 2592, 3)即(y轴像素点数, x轴像素点数,图像通道数)
# 这里用的是RGB三通道图像,通道数为3
裁剪图像
def plti(im, **kwargs):
"""
画图的辅助函数
"""
plt.imshow(im, interpolation="none", **kwargs)
plt.axis('off') # 去掉坐标轴
plt.show() # 弹窗显示图像
im = im[400:3800,:2000,:] # 直接切片对图像进行裁剪
plti(im)
分离各通道的图像
fig, axs = plt.subplots(nrows=1, ncols=3, figsize=(15,5))
# 将一张图分为1x3个子图,axs为各子图对象构成的列表。figsize为显示窗口的横纵比。
for c, ax in zip(range(3), axs): # 使用zip来同时循环3通道和3个子图对象
tmp_im = np.zeros(im.shape) # 初始化一个和原图像大小相同的三维数组
# 注意 tmp_im 仍然是三通道
tmp_im[:,:,c] = im[:,:,c] # 只复制某一通道
one_channel = im[:,:,c].flatten() # 索引该通道并展平至一维
print("channel", c, " max = ", max(one_channel), "min = ", min(one_channel)) # 输出该通道最大最小的像素值
ax.imshow(tmp_im) # 在子图上绘制
ax.set_axis_off() # 去掉子图坐标轴
# 注意以上 tmp_im 采用的是切片复制
plt.show()
#输出:
#channel 0 max = 220 min = 11
#channel 1 max = 203 min = 10
#channel 2 max = 185 min = 0