Python的图像处理
| 分类: 教育信息化 |
Python的图像处理
本文将介绍一个图像调整算法,它对大多数读者来说可能是直观的。与我们目前讨论过的其他图像调整算法(如RGB通道调整和直方图处理)不同,该方法将使用图像中可用的实际颜色。
我们开始吧!
一如既往,我们须导入所需的Python库。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from skimage.io import imread, imshow
import skimage.io as skio
from skimage import img_as_ubyte, img_as_float
现在我们看看正在处理的图像。
overcast = imread("image_overcast.PNG")
plt.figure(num=None, figsize=(8, 6), dpi=80)
imshow(overcast);
图像明显有一个颜色阴影。现在让我们试着调整一下,使得图像不那么黑。
开始,我们必须首先选择想要的特定区域。为此,我们可以使用NumPy中提供的矩形函数。
fig, ax = plt.subplots(1,1, figsize=(8, 6), dpi = 80)
patch = Rectangle((70,175), 10, 10, edgecolor='r', facecolor='none')
ax.add_patch(patch)
ax.imshow(overcast);
可以看到图像左上角的红色矩形,大多数人可能都怀疑这不是最好的区域,原因是区域的颜色跟其他部分的颜色明显不同。然而出于教学上的原因,我们将使用这个正方形区域并根据它调整图像。
我们先近距离观察这个区域。为此,我们必须使用NumPy中的get_bbox和get_points函数。
coord = Rectangle.get_bbox(patch).get_points()
print(coord)
现在可以使用这个坐标数组来切片。
fig, ax = plt.subplots(1,1, figsize=(8, 6), dpi = 80)
ax.imshow(overcast[int(coord[0][1]):int(coord[1][1]),
int(coord[0][0]):int(coord[1][0])]);
正如我们所看到的,区域远不是单调的颜色。在它里面有多种颜色的棕色和黑色(这证明了人类肉眼看不到很多细节)。
现在让我们根据区域调整图像。我们将使用区域的最大值和平均值。
image_patch = overcast[int(coord[0][1]):int(coord[1][1]),
int(coord[0][0]):int(coord[1][0])]
image_max = (overcast / image_ patch.max(axis=(0, 1))).clip(0, 1)
image_mean = ((overcast * image_ patch.mean())
/ overcast.mean(axis=(0, 1))).clip(0,255).astype(int)
fig, ax = plt.subplots(1,2, figsize=(15, 10), dpi = 80)
f_size = 19
ax[0].imshow(image_max)
ax[0].set_title('Max Adjusted', fontsize = f_ size)
ax[0].set_axis_off()
ax[1].set_title('Mean Adjusted', fontsize = f_ size)
ax[1].imshow(image_mean);
ax[1].set_axis_off()
fig.tight_layout()
可以看到,这两种调整都相当糟糕。Max adjusted的图像(虽然明显曝光过度)确实突出了左侧植物的绿色以及右侧车厢驾驶员的蓝色帽子。Mean adjusted的图像(虽然非常褪色)在图像的整体清晰度方面做得更好。但我可以肯定地说,这些调整都不是特别好。为了弥补这一点,我们回到区域的选择。
fig, ax = plt.subplots(1,1, figsize=(8, 6), dpi = 80)
patch1 = Rectangle((100,300), 10, 10, edgecolor='r',
facecolor='none')
patch2 = Rectangle((200,250), 10, 10, edgecolor='r',
facecolor='none')
patch3 = Rectangle((200,190), 10, 10, edgecolor='r',
facecolor='none')
ax.add_patch(patch1)
ax.add_patch(patch2)
ax.add_patch(patch3)
ax.imshow(overcast);
虽然不必这样做,但我们绘制出区域就可以知道它们是什么样子的。
coor1 = Rectangle.get_bbox(patch1).get_points()
coor2 = Rectangle.get_bbox(patch2).get_points()
coor3 = Rectangle.get_bbox(patch3).get_points()
image_patch1 = overcast[int(coor1[0][1]):int(coor1[1][1]),
int(coor1[0][0]):int(coor1[1][0])]
image_patch2 = overcast[int(coor2[0][1]):int(coor2[1][1]),
int(coor2[0][0]):int(coor2[1][0])]
image_patch3 = overcast[int(coor3[0][1]):int(coor3[1][1]),
int(coor3[0][0]):int(coor3[1][0])]
fig, ax = plt.subplots(1,3, figsize=(15, 12), dpi = 80)
ax[0].imshow(image_patch1)
ax[1].imshow(image_patch2)
ax[2].imshow(image_patch3);
就像第一个区域,这些区域也显示了一系列的颜色。现在用每一个来调整图像。为了帮助实现这一点,我们首先使用Python的列表生成式来创建调整后图像的列表。
patch_list = [image_patch1, image_patch2, image_patch3]
image_max_list = [(overcast / patch.max(axis=(0, 1))).clip(0, 1) for
patch in patch_list]
image_mean_list = [((overcast * patch.mean()) / overcast.mean(axis=(0, 1))).clip(0, 255).astype(int) for
patch in patch_list]
现在可以简单地显示这些图像。
开始吧。
def patch_plotter(max_patch, mean_patch) :
fig, ax = plt.subplots(1,2, figsize=(15, 10), dpi = 80)
f_size = 19
ax[0].imshow(max_patch)
ax[0].set_title('Max Adjusted Patch' , fontsize = f_size)
ax[0].set_axis_off()
ax[1].set_title('Mean Adjusted Patch' , fontsize = f_size)
ax[1].imshow(mean_patch);
ax[1].set_axis_off()
fig.tight_layout()
for i in range(3):
patch_plotter(image_max_list[i], image_mean_list[i])
第一个区域:
第二个区域:
第三个区域:
从结果中可以看出,Max adjusted的图比Mean adjusted的斑块表现得更好。此外,似乎第二个最好。这似乎表明,最好的区域是米色。作为最后的练习,我们选择符合特定描述的区域。此外,还应减小区域的大小,以减少区域中颜色变化的数量。
下面是一个可以调整图像的函数。我们只需要提供图像、区域的名称(用于标记)和区域坐标。
def ground_truth(image, patch_ names, patch_coordinates):
f_size = 25
figure_size = (17,12)
patch_dict = dict(zip(patch_ names, patch_coordinates))
coord = []
fig1, ax_1 = plt.subplots(1, 3, figsize = figure_ size)
for n, ax in enumerate(ax_1.flatten()):
# 创建矩形
key = list(patch_dict.keys())[n]
patch = Rectangle(patch_dict[key], 5, 5, edgecolor='r',
facecolor='none')
coord.append(Rectangle.get_bbox(patch).get_points())
ax.add_patch(patch);
# 显示和格式化化图像
ax.imshow(image)
ax.set_title(f'{key}', fontsize = f_ size)
ax.set_axis_off()
fig1.tight_layout()
fig2, ax_2 = plt.subplots(1, 3, figsize = figure_ size)
for n, ax in enumerate(ax_2.flatten()):
# 显示和格式化化图像
key = list(patch_dict.keys())[n]
ax.imshow(image[int(coord[n][0][1]) : int(coord[n][1][1]),
int(coord[n][0][0]) : int(coord[n][1][0])]);
ax.set_title(key, fontsize = f_ size)
ax.set_axis_off()

加载中…