Сверточные нейросети

Тематический кейс

1. Как библиотека MediaPipe распознаёт положение пальцев и какие точки используются в этой программе?

MediaPipe использует обученную нейросеть, которая анализирует изображение с камеры и находит на руке 21 ключевую точку (суставы и кончики пальцев). По этим точкам программа понимает положение каждого пальца. В этой программе используются две точки: кончик указательного пальца (id = 8) и кончик большого пальца (id = 4). По координате указательного пальца двигается курсор, а расстояние между двумя пальцами используется для определения клика.


2. Зачем нужна интерполяция координат np.interp, и что произойдёт без неё?

Камера и экран имеют разные размеры и координаты. Например, камера может быть 640×480, а экран — 1920×1080. Интерполяция np.interp переводит координаты пальца из системы координат камеры в систему координат экрана. Если её убрать, курсор будет двигаться неправильно: он сможет перемещаться только в маленькой области экрана или будет прыгать.


3. Как реализуется контроль курсора с помощью одной координаты?

MediaPipe возвращает координаты пальца x и y. Эти координаты переводятся в координаты экрана, и программа вызывает функцию:

pyautogui.moveTo(screen_x, screen_y)

Это перемещает курсор мыши туда, где находится указательный палец. Поэтому, когда человек двигает пальцем перед камерой, курсор повторяет это движение.


4. Почему щелчок мыши реализован через расстояние между пальцами, а не через отдельную команду?

Камера не может получать команды как клавиатура или кнопка. Поэтому программе нужен жест, который можно увидеть на изображении. Когда большой и указательный пальцы сближаются, расстояние между ними становится маленьким. Это легко вычислить математически, поэтому этот жест удобно использовать как “виртуальный клик”.


5. Как обеспечить устойчивую работу системы при дрожании руки или резких движениях?

Можно использовать несколько способов:

Это сделает управление более плавным.


6. Какие параметры можно оптимизировать для лучшего отклика?

Несколько параметров сильно влияют на работу системы:

Подбор этих параметров помогает сделать систему быстрее и удобнее.


7. В чём преимущества этой системы по сравнению с физическим управлением мышью?

Главное преимущество — контакт не требуется. Человек может управлять компьютером, не касаясь устройств. Это полезно:

Также такой интерфейс может быть удобен людям с ограниченной подвижностью.


8. Где в реальных условиях может пригодиться такое решение?

Такие системы могут использоваться:


9. Какие ограничения есть у системы без предварительного обучения?

Без дополнительного обучения система может иметь ограничения:

То есть система не “учится” новым жестам сама.


10. Как можно дополнительно расширить функциональность?

Систему можно сделать намного мощнее, добавив новые жесты:

Например:

Также можно добавить распознавание нескольких рук или жесты для запуска программ.

Теория

1. Что такое нейросеть
Нейросеть — это компьютерная программа, которая учится находить закономерности в данных примерно так же, как человек учится на опыте. Ей показывают много примеров (например, фотографий кошек и собак), и постепенно она начинает понимать, чем они отличаются. После обучения нейросеть может сама смотреть на новое изображение и пытаться угадать, что на нём изображено.

2. Что такое функция активации — это правило внутри нейросети, которое решает, насколько сильно нейрон должен “сработать” и передать сигнал дальше. Можно представить это как переключатель или регулятор силы сигнала: если значение маленькое, сигнал может почти не передаваться, а если большое — передаётся дальше по сети.

3. Что такое сверточная нейросеть
Сверточная нейросеть — это особый тип нейросети, который создан специально для работы с изображениями. Она не смотрит на всю картинку сразу, а как будто рассматривает её маленькими участками, постепенно находя линии, формы и детали. Благодаря этому она лучше понимает изображения и работает быстрее, чем обычные нейросети.

4. Зачем нужны сверточные нейросети
Сверточные нейросети помогают компьютерам распознавать изображения и видео. Например, они могут находить лица на фотографии, распознавать дорожные знаки для беспилотных машин или определять предметы на картинках. Благодаря таким сетям работают многие современные технологии: фильтры в телефонах, системы безопасности и медицинская диагностика.

5. Почему полносвязные сети быстро перегружаются информацией
Полносвязная нейросеть соединяет каждый пиксель изображения со всеми нейронами следующего слоя. Если картинка большая, получается огромное количество связей и вычислений. Из-за этого сеть становится очень тяжёлой, медленной и требует много памяти. Сверточные сети решают эту проблему, потому что работают только с небольшими участками изображения.

6. Что такое компьютерное зрение
Компьютерное зрение — это область технологий, которая учит компьютеры понимать изображения и видео. Например, компьютер может определить, где на фотографии человек, машина или животное. Это похоже на человеческое зрение, только вместо глаз и мозга используются камеры и программы.

7. Как работает сверточный слой
Сверточный слой работает как маленькое окошко, которое медленно двигается по изображению. Внутри этого окошка выполняется простая математическая операция, которая помогает обнаружить линии, границы или другие детали. Когда это окошко проходит по всей картинке, получается новое изображение, показывающее, где были найдены нужные признаки.

8. Сколько слоев может быть в сверточной нейросети
В сверточной нейросети может быть разное количество слоёв: от нескольких до десятков и даже сотен. Чем больше слоёв, тем более сложные признаки сеть может находить. Обычно первые слои ищут простые линии и края, а более глубокие слои начинают распознавать части объектов и сами объекты.

9. Что такое фильтры
Фильтр — это небольшой набор чисел (маленькая матрица), который помогает находить определённые детали на изображении. Один фильтр может искать вертикальные линии, другой — горизонтальные, третий — текстуры. Когда фильтр проходит по изображению, он показывает, где именно встречается этот признак.

10. Что такое дополненная реальность
Дополненная реальность — это технология, которая добавляет виртуальные объекты в реальный мир через камеру телефона или очки. Например, когда приложение рисует на лице маску или показывает виртуального персонажа на столе. Камера видит реальный мир, а программа добавляет к нему цифровые элементы.

11. Что такое карта признаков
Карта признаков — это изображение, которое получается после того, как фильтр обработал исходную картинку. Она показывает, где на изображении были найдены определённые признаки, например линии или границы. В нейросети обычно создаётся много таких карт, каждая из которых отвечает за свой тип признака.

12. Что такое дополненная реальность (AR) — это технология наложения виртуальных объектов на изображение из реального мира. Благодаря AR, пользователь видит дополненную сцену: на изображение с камеры «накладываются» 3D-объекты, текст, эффекты или подсказки. 

13. Что такое OpenCV
OpenCV — это специальная библиотека программирования, которая помогает работать с изображениями и видео. С её помощью можно загружать фотографии, находить объекты, выделять контуры и многое другое. Её часто используют вместе с нейросетями для создания систем компьютерного зрения. Для создания таких проектов часто используется OpenCV

14. Что такое пулинг
Пулинг — это операция, которая уменьшает размер изображения внутри нейросети. Она берёт небольшой участок изображения и оставляет только самое важное значение. Благодаря этому сеть работает быстрее и запоминает только самые значимые признаки.

15. Что такое нормализация
Нормализация — это процесс, который приводит данные к удобному диапазону значений, например от 0 до 1. Это помогает нейросети учиться быстрее и стабильнее. Можно представить, что мы приводим все числа к одному масштабу, чтобы их было легче сравнивать.

16. Что такое тензор
Тензор — это просто способ хранить данные в виде многомерной таблицы чисел. Например, изображение можно представить как таблицу пикселей, а цветное изображение — как несколько таких таблиц. В нейросетях почти вся информация хранится и передаётся именно в виде тензоров.

17. Что такое Conv2d
Conv2d — это операция в программировании нейросетей, которая выполняет двумерную свёртку над изображением. Она берёт фильтр и двигает его по картинке, находя нужные признаки. Именно эта операция лежит в основе работы сверточных нейросетей при обработке изображений.

Интегрированная среда разработки

Задача 1

Разберём функцию по шагам и максимально просто, чтобы это можно было объяснить даже детям.

def apply_kernel_rgb(image, kernel):
result = np.empty_like(image, dtype=float)

for c in range(3):
result[:, :, c] = convolve(image[:, :, c], kernel, mode='reflect')

return np.clip(result, 0, 1)

1. Что делает эта функция в целом

Эта функция применяет свёрточный фильтр (kernel) к цветному изображению.

Но цветное изображение состоит из трёх каналов:

  • R — красный

  • G — зелёный

  • B — синий

Поэтому фильтр нужно применить к каждому каналу отдельно, а потом собрать их обратно.


2. Аргументы функции

image

Это изображение в виде массива NumPy.

Его форма примерно такая:

(высота, ширина, 3)

Например:

(300, 451, 3)

3 — это каналы RGB.


kernel

Это матрица свёртки 3×3, например:

Такой фильтр делает резкость.


3. Создание массива результата

result = np.empty_like(image, dtype=float)

Создаётся новый массив, куда мы будем записывать результат обработки.

empty_like означает:

создать массив такого же размера как image.

То есть:

result.shape == image.shape

4. Цикл по каналам RGB

for c in range(3):

Цикл выполняется 3 раза:

c = 0 → канал R
c = 1 → канал G
c = 2 → канал B

5. Выбор одного канала изображения

image[:, :, c]

Это означает:

все строки
все столбцы
канал c

То есть мы берём одно чёрно-белое изображение канала.

Например:

image[:, :, 0] → красный канал

6. Применение свёртки

convolve(image[:, :, c], kernel, mode='reflect')

Функция convolve:

  • двигает ядро kernel по изображению

  • вычисляет новое значение пикселя

  • создаёт новое изображение

mode='reflect' означает:

если фильтр выходит за край картинки,
пиксели зеркально отражаются, чтобы не было обрезки.


7. Запись результата

result[:, :, c] = ...

Получившийся обработанный канал записывается обратно в результат.

В итоге:

result[:,:,0] → новый красный канал
result[:,:,1] → новый зелёный
result[:,:,2] → новый синий

8. Ограничение значений пикселей

np.clip(result, 0, 1)

После свёртки значения могут выйти за пределы:

< 0
> 1

Но изображение должно иметь диапазон:

0 → чёрный
1 → белый

clip обрезает значения:

меньше 0 → 0
больше 1 → 1

9. Что возвращает функция

Функция возвращает новое RGB-изображение, к которому применён фильтр.

Например:

  • фильтр резкости

  • фильтр размытия

  • фильтр контуров


10. Простая аналогия

Можно представить это так:

RGB картинка

разделяем на 3 слоя
R G B
↓ ↓ ↓
применяем фильтр
↓ ↓ ↓
собираем обратно

новое изображение

Вот что можно изменить в коде Задачи 1, чтобы результаты картинок заметно менялись

1) Менять силу яркости

Где: filt_brighter, filt_darker

  • Поиграть с delta: 0.05, 0.2, 0.4

  • Объяснение: мы просто прибавляем/вычитаем число ко всем пикселям.

Filter("Ярче", "...", lambda img: filt_brighter(img, delta=0.35))
Filter("Темнее", "...", lambda img: filt_darker(img, delta=0.35))

2) Менять силу контраста

Где: filt_contrast(img, factor)

  • Поиграть с factor: 0.4 (очень мягко), 1.0 (без изменений), 2.5 (очень жёстко)

Filter("Контраст ↑↑", "Очень жёстко", lambda img: filt_contrast(img, 2.5))
Filter("Контраст ↓↓", "Очень мягко", lambda img: filt_contrast(img, 0.4))

3) “Тёплый/холодный” тон и сила эффекта

Где: filt_warm

  • Поиграть с коэффициентами каналов: усилить синий (холодно), усилить красный (тепло).

Пример “Холодный тон”:

def filt_cold(img):
result = img.copy()
result[:, :, 2] = np.clip(result[:, :, 2] * 1.15 + 0.02, 0, 1) # B ↑
result[:, :, 0] = np.clip(result[:, :, 0] * 0.90, 0, 1) # R ↓
return result

И добавить в FILTERS.

4) Сделать “свой ч/б”

Где: filt_gray

Сейчас используется color.rgb2gray (умное преобразование). Можно дать ребятам 2 варианта:

  • Среднее: (R+G+B)/3

  • Только один канал: например только R

def filt_gray_avg(img):
gray = img.mean(axis=2)
return np.stack([gray, gray, gray], axis=2)

def filt_red_only(img):
gray = img[:, :, 0]
return np.stack([gray, gray, gray], axis=2)

Это прям классно показывает, что “цвет = три слоя”.

5) Менять ядро резкости (самое интересное)

Где: SHARPEN_KERNEL

Сейчас ядро такое:

Пусть попробуют:

  • “резче” (центр больше): 7 или 9

  • “мягче” (центр меньше): 3

SHARPEN_KERNEL_STRONG = np.array(, float)
SHARPEN_KERNEL_SOFT = np.array(, float)

Добавить 2 фильтра и сравнить глазами.

6) Добавить размытие 3×3 (очень наглядно)

Новый фильтр: “Blur”.

BLUR_KERNEL = np.ones((3,3), dtype=float) / 9.0

def filt_blur(img):
return apply_kernel_rgb(img, BLUR_KERNEL)

И добавить в FILTERS. Ребята сразу увидят, что свёртка может “мылить”.

7) Сделать “выделение контуров” другим ядром (не только Sobel)

Можно добавить простой Laplacian:

LAPLACIAN = np.array(, float)

def filt_edges_laplacian(img):
gray = color.rgb2gray(img)
e = convolve(gray, LAPLACIAN, mode='reflect')
e = np.abs(e)
e /= e.max() + 1e-8
return np.stack([e, e, e], axis=2)

Так дети поймут: “контуры можно искать разными способами”.

8) Поиграть с режимом краёв у свёртки

Где: convolve(..., mode='reflect')

Попробовать:

  • 'reflect' (как сейчас)

  • 'nearest' (берёт ближайший пиксель)

  • 'constant' (за краем считает нули — часто даёт рамку)

Это хороший эксперимент “почему края ведут себя странно”.

9) Поменять изображение

Где: data.chelsea()

Пусть попробуют другие встроенные картинки:

img_color = img_as_float(data.astronaut())
# или
img_color = img_as_float(data.coffee())

Или загрузка из файла (если в окружении можно).

10) Сделать “постеризацию” (меньше цветов)

Это прикольный эффект и очень простой:

def filt_posterize(img, levels=4):
return np.round(img * (levels - 1)) / (levels - 1)

Задача 2

1) Выбор фото

Самое простое и наглядное:

PHOTO_PATH = r"Resource_3_4/student2.jpg"

Пусть прогонят все 4 фотографии и сравнят: где лучше детектируются лица/глаза/рот и почему (свет, ракурс, масштаб, повороты).


Параметры каскадов: как ими управлять

2) FACE_SCALE_FACTOR и FACE_MIN_NEIGHBORS

Это отвечает за поиск лиц.

  • FACE_SCALE_FACTOR (например 1.1–1.8)

    • меньше (1.1–1.3): ищет тщательнее, но медленнее, может найти больше лиц

    • больше (1.6–2.0): быстрее, но может пропускать лица

  • FACE_MIN_NEIGHBORS (например 3–8)

    • меньше: больше находок, но больше “ложных лиц”

    • больше: меньше шума, но можно потерять реальные лица

Эксперимент для ребят:

  • Поставить FACE_MIN_NEIGHBORS = 3 и увидеть “лишние лица”.

  • Поставить FACE_MIN_NEIGHBORS = 8 и увидеть пропуски.


3) EYE_* параметры (глаза)

Особенно часто ломаются на фото с бликами/очками/поворотами головы.

  • EYE_SCALE_FACTOR: 1.05–1.4

  • EYE_MIN_NEIGHBORS: 4–12

Эксперимент:

  • Сделать EYE_MIN_NEIGHBORS ниже и увидеть, как каскад начинает принимать за глаз “что угодно”.


4) MOUTH_* параметры (рот)

Рот часто определяется хуже всего. Важны:

  • MOUTH_MIN_NEIGHBORS (6–15)

  • minSize=(30,15) можно тоже менять (например (40, 20))

Эксперимент:

  • Уменьшить minSize, увидеть, что “рот” находится на подбородке/носу/складках.

  • Увеличить minSize, увидеть, что рот иногда перестаёт находиться.


Параметры “посадки” аксессуаров

5) Коэффициенты ширины

GLASSES_WIDTH_K = 0.50
MOUST_WIDTH_K = 0.60
  • Очки обычно: 0.55–0.80 от ширины лица (зависит от PNG)

  • Усы: 0.40–0.75

Эксперимент:

  • Сделать очки “слишком большими” (0.9) и “слишком маленькими” (0.3) — легко увидят масштабирование.


6) Смещения (самый понятный рычаг)

GLASSES_OFFSET_K = 0.20
MOUST_OFFSET_K = 0.01

Смещение измеряется как доля face_h, поэтому для разных лиц ведёт себя похожим образом.

Эксперимент:

  • Очки: 0.05 / 0.20 / 0.35 (опускаются на нос)

  • Усы: 0.00 / 0.05 / 0.10 (поднимаются к носу)


7) Как выбирать “правильные” глаза из найденных

Сейчас берёте два самых левых:

sorted(eyes, key=lambda e: e[0])[:2]

Это иногда неверно (каскад может найти “глаз” на брови или тени).

Идея улучшения для ребят (простая логика):

  • выбирать два глаза, которые:

    • примерно на одной высоте (abs(y1 - y2) маленькое)

    • имеют похожий размер (abs(w1 - w2) маленькое)

    • находятся достаточно далеко друг от друга (иначе это не “два глаза”)

Это прям хорошая мини-задача на фильтрацию.


8) Устойчивость к “ложному рту”

Сейчас выбирается “самый большой прямоугольник”:

max(mouths, key=lambda m: m[2] * m[3])

Иногда “самый большой” — это вообще не рот.

Улучшение:

  • искать рот ближе к центру нижней половины лица

  • отбрасывать слишком высоко/низко найденные области


9) Визуальная отладка: добавить подписи и центры

Очень полезно для обучения:

  • рисовать точки центра глаз

  • рисовать линию между глазами

  • рисовать вектор p_up

Чтобы дети увидели: “ага, вот откуда берётся угол, вот почему усы едут вбок”.