Билеты по Компьютерному Зрению

1. Преобразование цветов. Блендинг (Color Transformation. Blending)

Объяснение темы:

### Введение: Что такое цвет и как его видит компьютер?

**Физика и восприятие:**
Чтобы понять, как компьютер работает с цветом, нужно сначала понять, что такое цвет для человека. Цвет — это не неотъемлемое свойство объекта, а результат сложного процесса. Свет представляет собой электромагнитное излучение, и видимый нами спектр — это лишь узкая полоса длин волн. Когда свет от источника (например, солнца) попадает на объект, часть волн поглощается, а часть отражается. Отраженные волны попадают в наш глаз на сетчатку, где находятся миллионы светочувствительных клеток-фоторецепторов. Среди них есть 'палочки' (отвечают за зрение в сумерках, не различают цвета) и 'колбочки'. Существует три типа колбочек, каждый из которых наиболее чувствителен к своему диапазону длин волн: коротковолновому (синий), средневолновому (зеленый) и длинноволновому (красный). Мозг получает и анализирует интенсивность сигналов от этих трех типов колбочек и интерпретирует их комбинацию как определенный цвет. Этот трехкомпонентный механизм восприятия называется трихроматизмом и является основой для большинства цифровых цветовых моделей.

**Цифровое представление:**
Компьютер имитирует этот процесс. Цифровое изображение — это двумерная сетка (матрица) пикселей. Для каждого пикселя компьютер должен хранить информацию о его цвете. Основываясь на трихроматической теории, самый распространенный способ — хранить три числа, представляющие интенсивность красной, зеленой и синей компонент. Этот метод называется представлением в цветовом пространстве RGB. Каждое число (компонента) обычно кодируется 8 битами, что дает 2^8 = 256 возможных уровней интенсивности (от 0 до 255). Когда у нас есть три таких компоненты, мы получаем 256 x 256 x 256 ≈ 16.7 миллионов комбинаций, что составляет так называемый 'True Color' — палитру, достаточную для фотореалистичного отображения.

### Часть 1: Преобразование цветов (Color Transformation)

Преобразование цветов — это математическая процедура пересчета цветовых значений пикселя из одной цветовой модели (пространства) в другую. Это не изменение самого видимого цвета, а изменение способа его числового описания. Разные цветовые модели были разработаны для разных целей, и каждая из них имеет свои сильные и слабые стороны. Выбор правильной модели может кардинально упростить решение задачи компьютерного зрения. Например, если нам нужно найти все ярко-красные яблоки на фото, в модели RGB нам пришлось бы подбирать сложные диапазоны для R, G и B, которые сильно зависят от освещения. Преобразовав изображение в модель HSV, мы можем просто задать узкий диапазон для компоненты Hue (тон), соответствующей красному цвету, и более широкие диапазоны для Saturation (насыщенность) и Value (яркость), что сделает наш алгоритм гораздо более устойчивым к теням и бликам.

#### Глубокое погружение в цветовые пространства (Color Spaces)

**1. RGB и BGR: Модель для экранов**
Это аддитивная цветовая модель. 'Аддитивная' означает, что цвета получаются путем сложения (add) световых потоков. Представьте три прожектора — красный, зеленый и синий, светящие на белый экран. В месте, где их лучи пересекаются, цвета смешиваются. R+G = Желтый, G+B = Циан, B+R = Маджента. R+G+B = Белый. Отсутствие света (все компоненты равны 0) дает черный цвет. Эта модель идеально соответствует физическому устройству большинства экранов, каждый пиксель которых состоит из трех крошечных субпикселей: красного, зеленого и синего.
**Нюанс OpenCV:** Критически важный аспект при работе с библиотекой OpenCV: по историческим причинам стандартный порядок каналов в OpenCV — это BGR (Blue, Green, Red), а не RGB. Если вы загружаете изображение с помощью `cv2.imread()` и передаете его в другую библиотеку (например, Matplotlib), которая ожидает RGB, цвета будут искажены. Всегда необходимо помнить о конвертации `cv2.cvtColor(image, cv2.COLOR_BGR2RGB)`.
**Ограничения:** Главный недостаток RGB для анализа изображений — сильная корреляция между каналами и смешение информации о яркости и цвете. Небольшое изменение освещения меняет все три значения (R, G, B) одновременно, что усложняет создание робастных алгоритмов.

**2. Grayscale: Упрощение ради анализа**
Это модель, в которой цвет полностью отсутствует, и каждый пиксель описывается единственным значением — его яркостью (интенсивностью). Преобразование из цветного изображения в серое — это не простое усреднение, а взвешенная сумма, основанная на чувствительности человеческого глаза: `Luminance = 0.299*R + 0.587*G + 0.114*B`. Использование Grayscale значительно снижает сложность вычислений, фокусируясь на форме и текстуре.

**3. HSV и HSL: Интуитивные модели для человека**
Эти модели разделяют информацию о цвете на компоненты, которые более интуитивно понятны: 'какой цвет?', 'насколько он сочный?' и 'насколько он светлый/темный?'.
- **Hue (Тон):** Угол на цветовом круге (0-360°). Отвечает на вопрос 'какой это цвет?'. В OpenCV диапазон сжат до 0-179 для хранения в 8-битном значении.
- **Saturation (Насыщенность):** 'Чистота' или 'сочность' цвета (0-255). 0 — оттенок серого, 255 — самый чистый цвет.
- **Value (Значение, HSV) vs Lightness (Светлота, HSL):** Высота вдоль оси яркости. В HSV, Value=max может быть любым ярким цветом. В HSL, Lightness=max всегда белый. Для задач компьютерного зрения HSV часто удобнее.

**4. CIE L*a*b*: Перцепционно-однородная модель**
Разработана так, что числовое расстояние между двумя цветами хорошо коррелирует с воспринимаемой человеком разницей. Это пространство независимо от устройства.
- **L* (Lightness):** Ось яркости от 0 (черный) до 100 (белый).
- **a*:** Ось от зеленого (отрицательные значения) до красного (положительные значения).
- **b*:** Ось от синего (отрицательные значения) до желтого (положительные значения).
Идеально для измерения цветовых различий.

**5. YCrCb / YUV: Модели для сжатия**
Эти модели разделяют яркостную (люма - Y) и цветовую (хрома - Cr, Cb) информацию. Так как глаз менее чувствителен к деталям цвета, чем к деталям яркости, это позволяет сжимать цветовую информацию с меньшим разрешением (цветовая субдискретизация), что широко используется в форматах JPEG и MPEG.

#### Преобразования интенсивности (Point Processing) и Гамма-коррекция

Это техники, где значение каждого пикселя в выходном изображении зависит **только** от значения соответствующего пикселя во входном (`s = T(r)`). Они используются для улучшения контраста и коррекции яркости.

**Гамма-коррекция:**
Нелинейное преобразование, описываемое степенной функцией: `I_out = 255 * (I_in / 255)^γ`. Эта операция позволяет изменять соотношение между темными и светлыми тонами.
- `γ < 1`: Осветляет изображение, 'проявляя' детали в тенях. Используется для коррекции темных снимков.
- `γ > 1`: Затемняет изображение, 'приглушая' пересвеченные области. Используется для коррекции слишком светлых снимков.
Для эффективного вычисления используется **таблица подстановки (Look-Up Table, LUT)**.

**Другие преобразования:**
- **Растяжение контраста (Contrast Stretching):** Линейное преобразование, которое 'растягивает' диапазон яркостей изображения на всю доступную шкалу (0-255). Реализуется через `cv2.normalize`.
- **Эквализация гистограммы (Histogram Equalization):** Нелинейное преобразование, которое перераспределяет интенсивности так, чтобы гистограмма стала равномерной, что автоматически улучшает глобальный контраст. Более продвинутая версия - **CLAHE** (адаптивная эквализация), которая работает с локальными регионами и дает более естественные результаты.

### Часть 2: Блендинг изображений (Image Blending)

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

**Математические основы:**
- **Взвешенная сумма:** Основа большинства операций блендинга, формула: `dst(I) = α * src1(I) + β * src2(I) + γ`. OpenCV предоставляет функцию `cv2.addWeighted`. Важным аспектом является **насыщение (saturation)**: функции OpenCV автоматически обрезают результат до диапазона [0, 255], чтобы избежать артефактов переполнения.
- **Альфа-канал:** Дополнительный канал в изображении (RGBA), который определяет степень непрозрачности каждого пикселя. **Альфа-композитинг** — это процесс наложения одного изображения (переднего плана, FG) на другое (фона, BG) с учетом прозрачности по формуле: `Output = α_fg * FG + (1 - α_fg) * BG`.

**Продвинутые техники:**
- **Режимы наложения:** Различные математические формулы для смешивания пикселей, знакомые по графическим редакторам, такие как **Multiply** (Умножение, для затемнения), **Screen** (Экран, для осветления), **Overlay** (Перекрытие, для увеличения контраста).
- **Маскирование и побитовые операции:** Побитовые операции (`AND`, `OR`, `XOR`, `NOT`) позволяют с помощью бинарных масок точно контролировать, какие части изображений будут скомбинированы. Это позволяет вставлять объекты сложной формы с одного изображения на другое.

### Заключение и области применения

Преобразование цветов и блендинг являются фундаментальными кирпичиками, из которых строятся практически все сложные системы компьютерного зрения. Понимание того, как цвет представлен в цифровом виде и как можно манипулировать этим представлением, открывает огромные возможности для анализа. Блендинг же дает инструменты для творческого и функционального синтеза новых изображений. Области применения включают:
- **Компьютерное зрение:** Сегментация по цвету для отслеживания объектов.
- **Медицинская визуализация:** Усиление контраста на снимках МРТ.
- **Дополненная реальность:** Наложение виртуальных объектов на реальный мир.
- **Видеопроизводство:** Хромакей (замена зеленого фона), создание переходов.
- **Фотография и дизайн:** Цветокоррекция, фотомонтаж, создание коллажей.

Методы и Примеры:

Преобразование цветового пространства (Color Space Conversion)

Описание: Это операция изменения цветовой модели изображения. Библиотека OpenCV предоставляет универсальную и высокооптимизированную функцию `cv2.cvtColor` для этой цели, поддерживающую более 150 различных преобразований.

Пример кода:

import cv2
import numpy as np

# Создаем простое цветное изображение (OpenCV использует BGR по умолчанию)
image_bgr = np.zeros((100, 300, 3), dtype=np.uint8)
image_bgr[:, :100] = [255, 0, 0]   # Синий
image_bgr[:, 100:200] = [0, 255, 0] # Зеленый
image_bgr[:, 200:] = [0, 0, 255]   # Красный

# 1. Преобразование из BGR в Grayscale
gray_image = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)

# 2. Преобразование из BGR в HSV
hsv_image = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)

# 3. Пример использования HSV для сегментации по цвету (поиск красного)
# В HSV красный цвет находится на границе диапазона Hue (около 0 и 179 в OpenCV)
lower_red1 = np.array([0, 120, 70])
upper_red1 = np.array([10, 255, 255])
mask_red1 = cv2.inRange(hsv_image, lower_red1, upper_red1)

lower_red2 = np.array([170, 120, 70])
upper_red2 = np.array([179, 255, 255])
mask_red2 = cv2.inRange(hsv_image, lower_red2, upper_red2)

# Объединение масок
red_mask = cv2.bitwise_or(mask_red1, mask_red2)

# Применение маски для выделения красных областей
result_red_only = cv2.bitwise_and(image_bgr, image_bgr, mask=red_mask)

Объяснение кода: - `cv2.cvtColor(source_image, flag)`: Основная функция. Первый аргумент — исходное изображение, второй — специальный флаг, указывающий тип преобразования (`cv2.COLOR_BGR2GRAY`, `cv2.COLOR_BGR2HSV` и т.д.).
- `cv2.inRange(hsv_image, lower_bound, upper_bound)`: Создает бинарную маску. Для каждого пикселя проверяет, лежит ли значение каждого из его каналов в заданном диапазоне. Если да, пиксель в маске становится белым (255), иначе — черным (0).
- `cv2.bitwise_or(mask1, mask2)`: Побитовая операция "ИЛИ", используется для объединения двух масок.
- `cv2.bitwise_and(src, src, mask=mask)`: Применяет маску к изображению. Пиксели `src` остаются без изменений там, где маска `mask` белая.

Пример из реальной жизни: **Отслеживание объектов по цвету:** Робот может отслеживать желтый мяч, используя HSV, чтобы быть устойчивым к теням (изменение V) и бликам (изменение S). **Сегментация кожи:** В HSV или YCrCb существуют определенные диапазоны значений, соответствующие цвету человеческой кожи, что используется для обнаружения лиц и рук.

Гамма-коррекция с помощью Look-Up Table (LUT)

Описание: Применение нелинейного преобразования интенсивности для осветления или затемнения изображения. Для эффективности используется предварительно вычисленная таблица подстановки (LUT), которая сопоставляет каждое из 256 возможных исходных значений яркости с новым значением.

Пример кода:

import cv2
import numpy as np

def adjust_gamma(image, gamma=1.0):
    # Создаем LUT. Мы используем 1/gamma, чтобы gamma > 1 осветляло изображение.
    invGamma = 1.0 / gamma
    table = np.array([((i / 255.0) ** invGamma) * 255
                      for i in np.arange(0, 256)]).astype("uint8")
    # Применяем LUT к изображению
    return cv2.LUT(image, table)

# Создадим темное изображение с градиентом
dark_image = np.zeros((100, 256), dtype=np.uint8)
dark_image[0:100, 0:256] = np.arange(0, 256)
dark_image = (dark_image * 0.5).astype('uint8') # Делаем его темнее

# Осветляем изображение с помощью гамма-коррекции
gamma_brightened = adjust_gamma(dark_image, gamma=2.0)

Объяснение кода: - `adjust_gamma(image, gamma)`: Функция, которая принимает изображение и значение гаммы.
- `table = np.array([...])`: Создается LUT. Цикл `for i in np.arange(0, 256)` проходит по всем возможным значениям пикселя, вычисляет новое значение по формуле гамма-коррекции и сохраняет его в массив `table`.
- `cv2.LUT(image, table)`: Высокооптимизированная функция OpenCV, которая для каждого пикселя `image` находит его значение, использует это значение как индекс в `table` и заменяет пиксель на значение из `table`.

Пример из реальной жизни: **Улучшение фотографий:** Осветление недоэкспонированных (слишком темных) снимков, особенно для 'вытягивания' деталей из теней. **Компьютерная графика:** Использование линейного рабочего процесса (Linear Workflow) для физически корректного рендеринга.

Блендинг изображений (линейный и с помощью масок)

Описание: Комбинирование двух изображений. `cv2.addWeighted` используется для создания полупрозрачного наложения (плавного перехода). Побитовые операции с масками используются для точного 'вклеивания' объекта сложной формы с одного изображения на другое.

Пример кода:

import cv2
import numpy as np

# --- Пример 1: Плавный переход с cv2.addWeighted ---
# img1 = cv2.imread('image1.jpg')
# img2 = cv2.imread('image2.jpg')
# # ... (код изменения размера, если нужно)
# blended_image = cv2.addWeighted(img1, 0.5, img2, 0.5, 0)

# --- Пример 2: Наложение логотипа с помощью маски ---
# main_image = cv2.imread('main_image.jpg')
# logo = cv2.imread('logo.png')
# if main_image is not None and logo is not None:
#     rows, cols, _ = logo.shape
#     roi = main_image[0:rows, 0:cols]
#     logo_gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)
#     ret, mask = cv2.threshold(logo_gray, 10, 255, cv2.THRESH_BINARY)
#     mask_inv = cv2.bitwise_not(mask)
#     main_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
#     logo_fg = cv2.bitwise_and(logo, logo, mask=mask)
#     dst = cv2.add(main_bg, logo_fg)
#     main_image[0:rows, 0:cols] = dst

Объяснение кода: - `cv2.addWeighted(src1, alpha, src2, beta, gamma)`: Смешивает два изображения с заданными весами `alpha` и `beta`.
- **Побитовые операции для маскирования:**
- `cv2.threshold`: Используется для создания бинарной маски из серого изображения логотипа.
- `cv2.bitwise_not(mask)`: Инвертирует маску (черное становится белым и наоборот).
- `cv2.bitwise_and(src1, src2, mask=mask)`: Выполняет побитовое "И" между `src1` и `src2`, но только в тех местах, где пиксели маски `mask` не равны нулю.
- `cv2.add(img1, img2)`: Простое поэлементное сложение, удобное для совмещения 'вырезанных' частей.

Пример из реальной жизни: **Создание водяных знаков:** Полупрозрачный логотип накладывается на фото с помощью `addWeighted`. **Видеопереходы:** Плавный переход от одной сцены к другой. **Фотомонтаж:** Вставка объекта с одного изображения на другое с использованием масок и побитовых операций.