
Теоретическая основа:
Типы изображений:
Необходимые инструменты:
Пошаговая инструкция:
# В PyCharm: File → New Project → Python
# Выбираем интерпретатор Python 3.13
pip install opencv-python numpy
Проверка установки:
import cv2
import numpy as np
print("OpenCV версия:", cv2.__version__)
print("NumPy версия:", np.__version__)
print("Пакеты успешно импортированы!")
Используемые методы:
cv2.imread(path) - загружает изображение из файла
path - путь к файлу изображенияcv2.imshow(window_name, image) - отображает изображение в окне
window_name - название окна для отображенияimage - объект изображения для отображенияcv2.waitKey(delay) - ожидает нажатия клавиши
delay - время ожидания в миллисекундах (0 = бесконечно)imshow для отображения изображенияПрактический пример:
import cv2
# Чтение изображения из файла
img = cv2.imread('resources/lena.png')
# Проверка успешности загрузки
if img is None:
print("Ошибка: изображение не найдено!")
else:
# Отображение изображения
cv2.imshow('Output', img)
# Ожидание нажатия клавиши (0 - бесконечное ожидание)
cv2.waitKey(0)
# Закрытие всех окон OpenCV
cv2.destroyAllWindows()
destroyAllWindows() освобождает все ресурсы, связанные с окнами OpenCVИспользуемые методы:
cv2.VideoCapture(source) - создает объект для захвата видео
source - путь к видеофайлу или ID камерыcap.read() - считывает следующий кадр из видео
success - булево значение, указывающее на успешность чтенияimage - объект изображения (кадр)cap.isOpened() - проверяет, успешно ли открыт источник видеоcap.release() - освобождает ресурсы видеоисточникаПрактический пример:
import cv2
# Захват видео из файла
cap = cv2.VideoCapture('resources/test_video.mp4')
# Проверка успешности открытия
if not cap.isOpened():
print("Ошибка: не удалось открыть видеофайл")
exit()
while True:
# Чтение кадра
success, img = cap.read()
# Проверка успешности чтения кадра
if not success:
print("Видео закончилось или произошла ошибка")
break
# Отображение кадра
cv2.imshow('Video', img)
# Выход при нажатии клавиши 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Очистка ресурсов
cap.release()
cv2.destroyAllWindows()
cv2.waitKey(1) с параметром 1 мс обеспечивает плавное воспроизведение0xFF == ord('q') гарантирует корректную работу на 64-битных системахИспользуемые методы:
cv2.VideoCapture(0) - подключение к веб-камере (ID 0 - камера по умолчанию)cap.set(propId, value) - установка параметров камеры:
propId = 3 - ширина кадраpropId = 4 - высота кадраpropId = 10 - яркостьpropId = 15 - контрастностьПрактический пример:
import cv2
# Захват видео с веб-камеры (ID 0 - камера по умолчанию)
cap = cv2.VideoCapture(0)
# Проверка подключения камеры
if not cap.isOpened():
print("Ошибка: не удалось подключиться к веб-камере")
exit()
# Установка параметров камеры
cap.set(3, 640) # Ширина (ID параметра 3)
cap.set(4, 480) # Высота (ID параметра 4)
cap.set(10, 100) # Яркость (ID параметра 10)
print(f"Разрешение камеры: {cap.get(3)}x{cap.get(4)}")
print(f"Яркость: {cap.get(10)}")
while True:
success, img = cap.read()
if not success:
print("Ошибка: не удалось получить кадр с камеры")
break
cv2.imshow('Webcam', img)
# Выход при нажатии клавиши 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Очистка ресурсов
cap.release()
cv2.destroyAllWindows()
cap.release() для корректного закрытия камерыИспользуемые методы:
cv2.cvtColor(src, code) - конвертация цветового пространства
src - исходное изображениеcode - код преобразования:
cv2.COLOR_BGR2GRAY - BGR в градации серогоcv2.COLOR_BGR2HSV - BGR в HSV (Hue, Saturation, Value)cv2.COLOR_GRAY2BGR - градации серого в BGRПрактический пример:
import cv2
# Чтение изображения
img = cv2.imread('resources/lena.png')
# Конвертация в градации серого
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Отображение результатов
cv2.imshow('Original', img)
cv2.imshow('Gray Image', imgGray)
cv2.waitKey(0)
cv2.destroyAllWindows()
Используемые методы:
cv2.GaussianBlur(src, ksize, sigmaX) - гауссово размытие
src - исходное изображениеksize - размер ядра (кортеж (width, height)), должен быть нечетнымsigmaX - стандартное отклонение по оси X (0 - автоматический расчет)Практический пример:
import cv2
import numpy as np
# Чтение изображения
img = cv2.imread('resources/lena.png')
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Применение гауссова размытия
imgBlur = cv2.GaussianBlur(imgGray, (7, 7), 0) # (7, 7) - размер ядра
# Отображение результатов
cv2.imshow('Gray Image', imgGray)
cv2.imshow('Blur Image', imgBlur)
cv2.waitKey(0)
cv2.destroyAllWindows()
Используемые методы:
cv2.Canny(image, threshold1, threshold2) - детектирование границ методом Canny
image - исходное изображение (лучше использовать размытое изображение)threshold1 - нижний порог градиентаthreshold2 - верхний порог градиентаПрактический пример:
import cv2
# Чтение изображения
img = cv2.imread('resources/lena.png')
# Детектирование границ
imgCanny = cv2.Canny(img, 100, 100) # Базовые пороги
# Улучшенная версия с размытием перед детектированием
imgBlur = cv2.GaussianBlur(img, (7, 7), 0)
imgCannyEnhanced = cv2.Canny(imgBlur, 50, 150)
# Отображение результатов
cv2.imshow('Original', img)
cv2.imshow('Canny Basic', imgCanny)
cv2.imshow('Canny Enhanced', imgCannyEnhanced)
cv2.waitKey(0)
cv2.destroyAllWindows()
Используемые методы:
cv2.dilate(src, kernel, iterations) - дилатация изображения
src - исходное изображение (обычно результат Canny)kernel - структурирующий элемент (матрица из единиц)iterations - количество итераций (степень дилатации)np.ones(shape, dtype) - создание матрицы из единиц
shape - размер матрицы (высота, ширина)dtype - тип данных (np.uint8 для изображений)Практический пример:
import cv2
import numpy as np
# Чтение изображения
img = cv2.imread('resources/lena.png')
imgCanny = cv2.Canny(img, 100, 100)
# Создание ядра для дилатации
kernel = np.ones((5, 5), np.uint8) # Матрица 5x5 из единиц
# Применение дилатации
imgDilation = cv2.dilate(imgCanny, kernel, iterations=1)
# Усиленная дилатация
imgDilationStrong = cv2.dilate(imgCanny, kernel, iterations=3)
# Отображение результатов
cv2.imshow('Canny Image', imgCanny)
cv2.imshow('Dilation (1 iteration)', imgDilation)
cv2.imshow('Dilation (3 iterations)', imgDilationStrong)
cv2.waitKey(0)
cv2.destroyAllWindows()
Используемые методы:
cv2.erode(src, kernel, iterations) - эрозия изображения
Практический пример:
import cv2
import numpy as np
# Чтение изображения
img = cv2.imread('resources/lena.png')
imgCanny = cv2.Canny(img, 100, 100)
kernel = np.ones((5, 5), np.uint8)
# Применение дилатации
imgDilation = cv2.dilate(imgCanny, kernel, iterations=1)
# Применение эрозии к результату дилатации
imgEroded = cv2.erode(imgDilation, kernel, iterations=1)
# Отображение результатов
cv2.imshow('Canny Image', imgCanny)
cv2.imshow('Dilation Image', imgDilation)
cv2.imshow('Eroded Image', imgEroded)
cv2.waitKey(0)
cv2.destroyAllWindows()
Используемые методы:
cv2.resize(src, dsize, fx, fy, interpolation) - изменение размера изображения
src - исходное изображениеdsize - целевой размер (ширина, высота)fx, fy - коэффициенты масштабирования (альтернатива dsize)interpolation - метод интерполяции (по умолчанию cv2.INTER_LINEAR)img.shape - получение размеров изображения
Практический пример:
import cv2
# Чтение изображения
img = cv2.imread('resources/lambo.png')
# Получение и вывод размеров изображения
print("Размер исходного изображения:", img.shape) # (высота, ширина, каналы)
# Изменение размера (ширина, высота)
imgResize = cv2.resize(img, (300, 200)) # Новые размеры: ширина=300, высота=200
# Увеличение размера (может привести к потере качества)
# imgResize = cv2.resize(img, (1000, 500))
# Проверка нового размера
print("Размер измененного изображения:", imgResize.shape)
# Отображение результатов
cv2.imshow('Original Image', img)
cv2.imshow('Resized Image', imgResize)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.INTER_LINEAR - билинейная (по умолчанию, хороша для уменьшения)cv2.INTER_CUBIC - бикубическая (качественная для увеличения)cv2.INTER_NEAREST - ближайший сосед (быстро, но низкое качество)Используемые методы:
img[y1:y2, x1:x2]
y1:y2 - диапазон по вертикали (высота)x1:x2 - диапазон по горизонтали (ширина)Практический пример:
import cv2
# Чтение изображения
img = cv2.imread('resources/lambo.png')
# Обрезка изображения [начало_высоты:конец_высоты, начало_ширины:конец_ширины]
imgCropped = img[0:200, 200:500] # [y1:y2, x1:x2]
# Визуализация точек обрезки на исходном изображении
img_with_rect = img.copy()
cv2.rectangle(img_with_rect, (200, 0), (500, 200), (0, 255, 0), 2)
cv2.putText(img_with_rect, "Область обрезки", (220, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
# Отображение результатов
cv2.imshow('Original Image with Crop Area', img_with_rect)
cv2.imshow('Cropped Image', imgCropped)
cv2.waitKey(0)
cv2.destroyAllWindows()
Используемые методы:
np.zeros(shape, dtype) - создание черного изображения
shape - размеры изображения (высота, ширина, каналы)dtype - тип данных (np.uint8 для 8-битных изображений)cv2.line(img, pt1, pt2, color, thickness) - рисование линии
pt1, pt2 - начальная и конечная точки (x, y)color - цвет в формате BGR (255, 0, 0) для синегоthickness - толщина линииcv2.rectangle(img, pt1, pt2, color, thickness) - рисование прямоугольника
pt1 - верхний левый угол (x1, y1)pt2 - нижний правый угол (x2, y2)thickness = cv2.FILLED для заполнения прямоугольникаcv2.circle(img, center, radius, color, thickness) - рисование круга
center - центр круга (x, y)radius - радиус круга в пикселяхПрактический пример:
import cv2
import numpy as np
# Создание черного изображения (512x512 пикселей, 3 канала)
img = np.zeros((512, 512, 3), np.uint8)
# Рисование линии (изображение, начальная точка, конечная точка, цвет, толщина)
cv2.line(img, (0, 0), (img.shape[1], img.shape[0]), (0, 255, 0), 3) # Зеленая диагональ
# Рисование прямоугольника (изображение, верхний левый угол, нижний правый угол, цвет, толщина)
cv2.rectangle(img, (0, 0), (250, 350), (0, 0, 255), 2) # Красный прямоугольник с контуром
# Заполненный прямоугольник
cv2.rectangle(img, (300, 0), (512, 150), (255, 0, 0), cv2.FILLED) # Синий заполненный прямоугольник
# Рисование круга (изображение, центр, радиус, цвет, толщина)
cv2.circle(img, (450, 50), 30, (255, 255, 0), 5) # Голубой круг с контуром
# Отображение результата
cv2.imshow('Drawing Shapes', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Используемые методы:
cv2.putText(img, text, org, fontFace, fontScale, color, thickness) - добавление текста
text - текстовая строка для отображенияorg - начальная точка текста (нижний левый угол первого символа)fontFace - тип шрифта:
cv2.FONT_HERSHEY_SIMPLEX - простой пропорциональный шрифтcv2.FONT_HERSHEY_PLAIN - компактный шрифтcv2.FONT_HERSHEY_COMPLEX - более сложный шрифтfontScale - масштаб шрифта (1.0 = нормальный размер)thickness - толщина штрихов символовПрактический пример:
import cv2
import numpy as np
# Создание черного изображения
img = np.zeros((512, 512, 3), np.uint8)
# Добавление текста с разными параметрами
cv2.putText(img, "OpenCV", (100, 100), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (255, 255, 255), 3)
cv2.putText(img, "Font Scale 0.5", (100, 150), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
cv2.putText(img, "Font Scale 2.0", (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0, 255), 2)
cv2.putText(img, "FONT_HERSHEY_PLAIN", (100, 250), cv2.FONT_HERSHEY_PLAIN, 2, (255, 0, 255), 2)
cv2.putText(img, "Thickness Demo", (100, 300), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 0), 1)
cv2.putText(img, "Thickness 5", (100, 350), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 0, 0), 5)
# Отображение результата
cv2.imshow('Text on Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Используемые методы:
cv2.getPerspectiveTransform(src, dst) - вычисление матрицы перспективного преобразования
src - координаты четырех точек в исходном изображении (numpy массив)dst - координаты четырех точек в целевом изображении (numpy массив)cv2.warpPerspective(src, M, dsize) - применение перспективного преобразования
M - матрица преобразования от getPerspectiveTransformdsize - размер выходного изображения (ширина, высота)Практический пример:
import cv2
import numpy as np
# Чтение изображения с картой
img = cv2.imread('resources/cards.jpg')
# Определение четырех угловых точек карты на исходном изображении (координаты подбираются вручную)
# Порядок точек: верхний левый, верхний правый, нижний левый, нижний правый
pts1 = np.float32([[111, 219], [287, 188], [154, 482], [352, 440]])
# Определение целевых точек для результата (прямоугольник стандартных размеров)
width, height = 250, 350 # Стандартные размеры игральной карты
pts2 = np.float32([[0, 0], [width, 0], [0, height], [width, height]])
# Получение матрицы преобразования перспективы
matrix = cv2.getPerspectiveTransform(pts1, pts2)
print("Матрица преобразования:")
print(matrix)
# Применение преобразования перспективы
imgOutput = cv2.warpPerspective(img, matrix, (width, height))
# Визуализация исходных точек на оригинальном изображении
img_with_points = img.copy()
for i, point in enumerate(pts1):
x, y = int(point[0]), int(point[1])
cv2.circle(img_with_points, (x, y), 8, (0, 0, 255), cv2.FILLED)
cv2.putText(img_with_points, f"Point {i+1}", (x+10, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# Отображение результатов
cv2.imshow('Original Image with Points', img_with_points)
cv2.imshow('Warped Image (Bird Eye View)', imgOutput)
cv2.waitKey(0)
cv2.destroyAllWindows()
Простой метод (без масштабирования):
import cv2
import numpy as np
# Чтение изображений
img = cv2.imread('resources/lena.png')
# Горизонтальное объединение (требует одинаковой высоты)
imgHor = np.hstack((img, img)) # numpy.hstack для горизонтального стека
# Вертикальное объединение (требует одинаковой ширины)
imgVer = np.vstack((img, img)) # numpy.vstack для вертикального стека
# Отображение результатов
cv2.imshow('Horizontal Stack', imgHor)
cv2.imshow('Vertical Stack', imgVer)
cv2.waitKey(0)
cv2.destroyAllWindows()
Универсальный метод (с масштабированием и разными каналами):
import cv2
import numpy as np
def stackImages(scale, imgArray):
"""
Функция для объединения изображений с возможностью масштабирования
и обработки изображений с разным количеством каналов.
Args:
scale (float): Коэффициент масштабирования
imgArray (list): Массив изображений (может быть 2D массивом для сетки)
Returns:
numpy.ndarray: Объединенное изображение
"""
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range(0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2:
imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank] * rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale)
if len(imgArray[x].shape) == 2:
imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor = np.hstack(imgArray)
ver = hor
return ver
# Использование функции
img = cv2.imread('resources/lena.png')
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgBlur = cv2.GaussianBlur(imgGray, (7, 7), 0)
imgCanny = cv2.Canny(img, 100, 100)
# Создание сетки изображений 2x2
imgStack = stackImages(0.5, (
[img, imgGray],
[imgBlur, imgCanny]
))
# Отображение результата
cv2.imshow('Stacked Images Grid', imgStack)
cv2.waitKey(0)
cv2.destroyAllWindows()
В этом учебном пособии мы рассмотрели основные функции OpenCV для работы с изображениями и видео. Полученные знания позволяют:
Эти навыки являются фундаментом для более сложных задач компьютерного зрения, таких как детектирование объектов, распознавание лиц, трекинг движущихся объектов и создание приложений дополненной реальности.
| ✓ | Задача |
|---|---|
| Установлен Python | |
| Установлен PyCharm Community Edition | |
| Настроены пути (PATH) для Python и PyCharm | |
| Создан виртуальный проект в PyCharm | |
Установлены необходимые библиотеки: opencv-python, numpy |
|
| Проведена проверка установки импортом библиотек и выводом версий |
| ✓ | Задача |
|---|---|
| Понимаю, что такое пиксель и как он представлен в цифровом виде | |
| Знаю разницу между типами изображений: | |
|
|
|
|
|
|
| Знаю стандартные разрешения: VGA (640×480), HD (1280×720), Full HD (1920×1080) | |
| Понимаю, что в OpenCV используется цветовое пространство BGR, а не RGB |
| ✓ | Задача |
|---|---|
Могу загружать изображение с помощью cv2.imread() |
|
Могу отображать изображение с помощью cv2.imshow() |
|
Использую cv2.waitKey(0) для задержки отображения |
|
Знаю, как закрыть окна с помощью cv2.destroyAllWindows() |
|
| Проверяю успешность загрузки изображения (обработка случая, когда файл не найден) |
| ✓ | Задача |
|---|---|
Могу создать объект для захвата видео с помощью cv2.VideoCapture() |
|
Знаю, как считывать кадры с помощью cap.read() |
|
Понимаю структуру возвращаемого значения (success, img) |
|
Использую цикл while для обработки видео покадрово |
|
| Знаю, как добавить выход из цикла по нажатию клавиши 'q' | |
Освобождаю ресурсы с помощью cap.release() после окончания работы |
| ✓ | Задача |
|---|---|
Могу подключиться к веб-камере с помощью cv2.VideoCapture(0) |
|
| Знаю, как установить параметры камеры: | |
Ширина кадра cap.set(3, width) |
|
Высота кадра cap.set(4, height) |
|
Яркость cap.set(10, brightness) |
|
Проверяю успешность подключения камеры с помощью cap.isOpened() |
|
Применяю зеркальное отображение при необходимости cv2.flip(img, 1) |
| ✓ | Задача |
|---|---|
| Конвертация цветовых пространств | |
Могу конвертировать BGR в градации серого cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
|
| Понимаю преимущества работы с изображениями в градациях серого | |
| Размытие изображений | |
Применяю гауссово размытие cv2.GaussianBlur(img, (ksize, ksize), sigmaX) |
|
| Знаю, что размер ядра должен быть нечетным (3, 5, 7...) | |
| Понимаю влияние размытия на качество детектирования границ | |
| Детектирование границ | |
Использую алгоритм Canny cv2.Canny(img, threshold1, threshold2) |
|
| Знаю, как подбирать оптимальные пороговые значения | |
| Понимаю, что размытие перед детектированием улучшает результат | |
| Морфологические операции | |
Создаю ядро для морфологических операций np.ones((5,5), np.uint8) |
|
Применяю дилатацию cv2.dilate(img, kernel, iterations) |
|
Применяю эрозию cv2.erode(img, kernel, iterations) |
|
| Понимаю практическое применение этих операций | |
| ✓ | Задача |
|---|---|
Знаю, как получить размеры изображения img.shape |
|
Могу изменить размер изображения cv2.resize(img, (width, height)) |
|
| Понимаю разницу в порядке параметров (resize: ширина→высота; shape: высота→ширина) | |
Могу обрезать изображение с помощью индексации img[y1:y2, x1:x2] |
|
| Знаю особенности системы координат в OpenCV (начало в левом верхнем углу) |
| ✓ | Задача |
|---|---|
Могу создать черное изображение np.zeros((height, width, 3), np.uint8) |
|
Рисую линии cv2.line(img, pt1, pt2, color, thickness) |
|
Рисую прямоугольники cv2.rectangle(img, pt1, pt2, color, thickness) |
|
Рисую заполненные прямоугольники (thickness=cv2.FILLED или -1) |
|
Рисую окружности cv2.circle(img, center, radius, color, thickness) |
|
Добавляю текст cv2.putText(img, text, org, font, scale, color, thickness) |
|
| Знаю основные шрифты OpenCV: | |
|
|
|
|
|
| ✓ | Задача |
|---|---|
| Создал проект с чтением изображения, применением базовых преобразований и отображением результатов | |
| Реализовал программу для захвата видео с веб-камеры с возможностью выхода по клавише 'q' | |
| Написал программу, которая рисует геометрические фигуры и текст на изображении | |
| Создал функцию для объединения изображений в одну визуализацию | |
| Реализовал базовую обработку изображения (серый → размытие → границы → дилатация) |
| ✓ | Задача |
|---|---|
| Понимаю систему координат в OpenCV (ось Y направлена вниз) | |
| Знаю, как работает цветовое пространство BGR в OpenCV | |
| Понимаю, что изображение в OpenCV — это NumPy массив | |
| Знаю, как правильно освобождать ресурсы после работы с видео и камерой | |
| Понимаю важность предварительной обработки изображений перед детектированием объектов |
| ✓ | Задача |
|---|---|
Все импорты библиотек выполнены корректно (import cv2, import numpy as np) |
|
| Все окна OpenCV закрываются после завершения программы | |
| Проверяю существование файлов перед их чтением | |
| Обрабатываю возможные ошибки при работе с камерой | |
| Использую понятные имена переменных | |
| Добавляю комментарии к коду для объяснения ключевых шагов | |
| Протестировал все функции на разных изображениях | |
| Понимаю, как работают параметры в каждой функции OpenCV |
```
