предисловие
В области глубокого обучения для решения задачи классификации изображений наиболее часто используется сверточная нейронная сеть (Convolutional Neural Network), сокращенно CNN. Причина, по которой ее называют сверточной нейронной сетью, заключается в том, что она использует сверточный слой в скрытом слое для обработки данных двумерного (оттенки серого) или трехмерного (RGB) изображения. Каждый сверточный слой состоит из множества фильтров (Filter), каждому фильтру соответствует небольшая матрица (количество строк и столбцов обычно 2 или 3), матрица строится по строкам и столбцам изображения, умножается и суммируются последовательно в соответствии с определенным размером шага. , получают новые данные изображения, этот процесс является процессом свертки изображения.
В применении сверточной нейронной сети изображение свертывается для получения нового изображения (если размер шага больше 1, новое изображение будет уменьшено), которое обычно используется для извлечения признаков изображения, и каждый фильтр также называется картой признаков. Однако свертка изображений используется не только в глубоких нейронных сетях для извлечения признаков.До приложений глубокого обучения свертка изображений широко использовалась в области обработки изображений. Например, в известном программном обеспечении для обработки изображений, таком как PhotoShop, размытие, повышение резкости, тиснение, контур и обнаружение краев также реализуются посредством свертки изображения. Отличие в том, что значение матрицы свертки глубокого обучения обучается моделью и не имеет правил, в то время как при обработке изображений значение матрицы регулярное, а форма обычно 3 строки и 3 столбца. Мы также называем эту матрицу ядром изображения (фактически, параметры сверточного слоя в Keras также используют ядро для обозначения размера фильтра).
Название этой статьи «Визуализация сверточных нейронных сетей». На самом деле, это также иллюстрирует, что, хотя параметры нейронной сети подобны черным ящикам и не могут быть объяснены, выходные данные сверточных слоев можно визуализировать. В этой статье объясняется визуальный вывод различных ядер изображений, используемых для свертки изображений, с точки зрения обработки изображений.
1. Импортируйте библиотеку
from PIL import Image, ImageDraw
import numpy as np
import matplotlib.pyplot as plt
# %matplotlib inline
2. Реализовать операцию ядра изображения
2.1 Вспомогательные функции
Укажите путь к изображению и используйте PIL.Image для чтения цветного изображения или изображения в градациях серого.
def read_img(imgpath, gray=True):
img = Image.open(imgpath)
if gray:
img = img.convert("L")
return img
Укажите ширину изображения для пропорционального масштабирования изображения.
def resize_width(img, width):
w, h = img.size
height = int(width * h / w)
return img.resize((width, height))
Вырежьте квадратное изображение из середины по самой короткой стороне изображения.
def crop_center(img):
w, h = img.size
c_x, c_y = w/2, h/2
offset = min(w, h) / 2
crop_box = (c_x-offset, c_y-offset, c_x+offset, c_y+offset)
return img.crop(crop_box)
2.2 Указываем ядро для обработки изображений
img — это объект Image; kernel — матрица для операции свертки; strides — размер одного шага преобразования операции свертки; когда mean имеет значение False, вычисляется сумма, а когда True — вычисляется среднее значение.
def apply_img_kernel(img, kernel, strides=1, mean=False):
img = np.asarray(img)
h, w = img.shape[:2]
k_h, k_w = kernel.shape[:2]
x_range = range(0, w - k_w + 1, strides)
y_range = range(0, h - k_h + 1, strides)
if mean:
prosum = lambda a,b: min((a*b).mean(), 255)
else:
prosum = lambda a,b: min((a*b).sum(), 255)
cal = lambda img: np.array([[prosum(img[i:i+k_h, j:j+k_w], kernel)
for j in x_range]
for i in y_range]).astype(np.uint8)
if len(img.shape) == 2:
data = cal(img)
return Image.fromarray(data)
elif len(img.shape) == 3:
r, g, b = np.transpose(img, (2, 0, 1))
_r, _g, _b = cal(r), cal(g), cal(b)
return Image.merge('RGB', [Image.fromarray(d) for d in [_r, _g, _b]])
3. Ядро изображения с различными эффектами
Осветление, Резкость, Размытие, Тиснение, Контур, Граница. Каждое ядро представляет собой функцию, параметры можно настраивать, параметры по умолчанию взяты с сайтаЦвет для разбрызгивания. IO/EV/image-can…
3.1 Осветление
def identity_kernel(iden=1.0):
return np.array([[0, 0, 0],
[0, iden, 0],
[0, 0, 0]])
3.2 Заточка
def sharpen_kernel(inner=5.0, edge=-1.0):
return np.array([[0, edge, 0],
[edge, inner, edge],
[0, edge, 0]])
3.3 Размытие
def blur_kernel(inner=0.25, edge=0.125, corner=0.0625):
return np.array([[corner, edge, corner],
[edge, inner, edge],
[corner, edge, corner]])
3.4 Рельеф
def emboss_kernel(diag=2.0, iden=1.0):
return np.array([[-diag, -iden, 0],
[-iden, iden, iden],
[0, iden, diag]])
3.5 Схема
def outline_kernel(inner=8.0, outer=-1.0):
return np.array([[outer, outer, outer],
[outer, inner, outer],
[outer, outer, outer]])
3.6 Обнаружение края
def sobel_kernel(direction, base=None, edge=2.0, corner=1.0):
if base is not None:
edge = base
corner = base / 2
if direction == 'top':
return np.array([[corner, edge, corner], [0, 0, 0], [-corner, -edge, -corner]])
elif direction == 'bottom':
return np.array([[-corner, -edge, -corner], [0, 0, 0], [corner, edge, corner]])
elif direction == 'left':
return np.array([[corner, 0, -corner], [edge, 0, -edge], [corner, 0, -corner]])
elif direction == 'right':
return np.array([[-corner, 0, corner], [-edge, 0, edge], [-corner, 0, corner]])
return identity_kernel()
4. Используйте эффект
Считайте изображение и выполните масштабирование и обрезку. (Снимок, сделанный мобильным телефоном, слишком велик, время расчета велико, а отображение изображения также занимает много места)
подсказки: для параметра серого установлено значение True, чтобы читать изображения в градациях серого. Здесь демонстрируется эффект цветного изображения.
img = read_img('yuki.jpeg', gray=False)
img = crop_center(resize_width(img, 320))
Вспомогательная функция: отображает две картинки в одной строке для сравнения изменений до и после внедрения ядра.
def show2imgs(img1, img2, title=None):
fig = plt.figure(figsize=(10, 5))
if title is not None:
fig.suptitle(title)
plt.subplot(121)
plt.axis('off')
plt.imshow(img1)
plt.subplot(122)
plt.axis('off')
plt.imshow(img2)
plt.show()
4.1 Осветление
img_identity = apply_img_kernel(img, identity_kernel(1.6))
show2imgs(img, img_identity)
4.2 Заточка
img_sharpen = apply_img_kernel(img, sharpen_kernel(inner=1.7, edge=-0.08))
show2imgs(img, img_sharpen)
4.3 Размытие
img_blur = apply_img_kernel(img, blur_kernel())
show2imgs(img, img_blur)
4.4 Рельеф
img_emboss = apply_img_kernel(img, emboss_kernel())
show2imgs(img, img_emboss)
4.5 Схема
img_outline = apply_img_kernel(img, outline_kernel(inner=8.9, outer=-1.29), mean=True)
show2imgs(img, img_outline)
4.6 Обнаружение границ
img_sobel_top = apply_img_kernel(img, sobel_kernel('top', 0.03))
img_sobel_bottom = apply_img_kernel(img, sobel_kernel('bottom', 0.03))
img_sobel_left = apply_img_kernel(img, sobel_kernel('left', 0.03))
img_sobel_right = apply_img_kernel(img, sobel_kernel('right', 0.03))
show2imgs(img_sobel_top, img_sobel_bottom)
show2imgs(img_sobel_left, img_sobel_right)
5. Открытый исходный код
Код этой статьи является открытым исходным кодом и может быть загружен с github:GitHub.com/Ken Ratio в порядке...
Вы также можете использовать pip для прямой установки (использование см. на домашней странице github):
pip install imgkernel
Отсканируйте QR-код в WeChat, чтобы получить оригиналы новейших технологий