Обработка видео на C++ OpenCV
Обработка видео означает обработку и анализ каждого кадра видеопоследовательности.
OpenCV предоставляет мощные инструменты для обработки видеоданных, включая чтение видео, обработку кадров, сохранение видео и обработку видео в реальном времени.
Сценарии применения обработки видео
Видеонаблюдение:
Используйте вычитание фона для обнаружения движущихся объектов.
Используйте оптический поток для анализа траекторий движения объектов.
Анализ видео:
Извлекайте ключевые кадры из видео.
Анализируйте поведение объектов в видео.
Обработка в реальном времени:
Видеофильтры в реальном времени (например, обнаружение границ, размытие и т. д.).
Обнаружение и отслеживание объектов в реальном времени.
Чтение и отображение видео
Чтение видеофайлов (VideoCapture)
В OpenCV,VideoCaptureкласс используется для чтения видеокадров из видеофайлов или с камер.
Чтобы прочитать видеофайл, сначала создайтеVideoCaptureобъект и укажите путь к видеофайлу.
Пример
using namespace cv;
int main() {
// Создайте объект VideoCapture и откройте видеофайл
VideoCapture cap("example.mp4");
// Проверьте, успешно ли открылось видео
if (!cap.isOpened()) {
std::cerr << "Ошибка: не удалось открыть видеофайл." << std::endl;
return -1;
}
// Код чтения и отображения видео будет представлен ниже
return 0;
}
Отображение видеокадров
После чтения видеофайла вы можете считывать видео кадр за кадром в цикле и использоватьimshowфункцию для отображения каждого кадра.
Пример
while (true) {
// Считать следующий кадр
cap >> frame;
// Если кадр пуст, видео закончилось
if (frame.empty()) {
break;
}
// Отобразить текущий кадр
imshow("Video", frame);
// Подождать 30 миллисекунд, нажмите ESC для выхода
if (waitKey(30) == 27) {
break;
}
}
// Освободить объект VideoCapture
cap.release();
// Закрыть все окна
destroyAllWindows();
Сохранение видео (VideoWriter)
Если вы хотите сохранить обработанное видео в файл, можно использоватьVideoWriterкласс. Сначала нужно указать выходной файл, формат кодирования, частоту кадров и размер кадра.
Пример
double fps = cap.get(CAP_PROP_FPS);
Size frameSize(cap.get(CAP_PROP_FRAME_WIDTH), cap.get(CAP_PROP_FRAME_HEIGHT));
// Создать объект VideoWriter
VideoWriter writer("output.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, frameSize);
while (true) {
cap >> frame;
if (frame.empty()) {
break;
}
// Записать кадры в выходной видеофайл
writer.write(frame);
imshow("Video", frame);
if (waitKey(30) == 27) {
break;
}
}
// Освободить объекты VideoCapture и VideoWriter
cap.release();
writer.release();
destroyAllWindows();
Обработка видеокадров
Покадровая обработка видео
При обработке видео обычно необходимо выполнять определённые операции обработки над каждым кадром. Например, можно преобразовать каждый кадр в оттенки серого, выполнить обнаружение краёв и т. д.
Пример
cap >> frame;
if (frame.empty()) {
break;
}
// Преобразовать кадр в изображение в оттенках серого
Mat grayFrame;
cvtColor(frame, grayFrame, COLOR_BGR2GRAY);
// Отобразить кадр в оттенках серого
imshow("Серое видео", grayFrame);
if (waitKey(30) == 27) {
break;
}
}
Обработка видеокадров в реальном времени
При обработке видеокадров в реальном времени обычно необходимо применять к каждому кадру некоторые алгоритмы обработки в реальном времени. Например, обнаруживать движущиеся объекты в видео в реальном времени.
Пример
cap >> prevFrame;
cvtColor(prevFrame, prevFrame, COLOR_BGR2GRAY);
while (true) {
cap >> nextFrame;
if (nextFrame.empty()) {
break;
}
cvtColor(nextFrame, nextFrame, COLOR_BGR2GRAY);
// Вычислить разницу между кадрами
absdiff(prevFrame, nextFrame, diffFrame);
// Отобразить разностный кадр
imshow("Обнаружение движения", diffFrame);
// Обновить предыдущий кадр
prevFrame = nextFrame.clone();
if (waitKey(30) == 27) {
break;
}
}
Обработка камеры в реальном времени
Открытие камеры
ИспользуяVideoCaptureкласс, вы можете не только читать видеофайлы, но и открывать камеру для обработки видеопотока в реальном времени. Чтобы открыть камеру, просто установитеVideoCaptureпараметр в 0 (что указывает на камеру по умолчанию).
Пример
if (!cap.isOpened()) {
std::cerr << "Error: Could not open camera." << std::endl;
return -1;
}
Обработка видеопотоков в реальном времени
После открытия камеры вы можете обрабатывать видеопоток в реальном времени покадрово, так же, как и видеофайл. Например, вы можете применить алгоритм обнаружения границ к видеопотоку в реальном времени.
Пример
cap >> frame;
if (frame.empty()) {
break;
}
// Применить обнаружение границ Canny
Mat edges;
Canny(frame, edges, 100, 200);
// Отобразить результат обнаружения границ
imshow("Края", edges);
if (waitKey(30) == 27) {
break;
}
}
cap.release();
destroyAllWindows();
Продвинутые методы обработки видео
Вычитание фона в видео
Вычитание фона используется для извлечения объектов переднего плана из видео.
Пример
#include <iostream>
using namespace cv;
using namespace std;
int main() {
// Открыть видеофайл или камеру
VideoCapture cap("video.mp4");
if (!cap.isOpened()) {
cout << "Ошибка: не удалось открыть видеофайл или камеру!" << endl;
return -1;
}
// Создать вычитатель фона
Ptr<BackgroundSubtractor> bgSubtractor = createBackgroundSubtractorMOG2();
// Обработать кадры видео
Mat frame, fgMask;
while (true) {
cap >> frame;
if (frame.empty()) break;
// Применить вычитание фона
bgSubtractor->apply(frame, fgMask);
// Вывести результат
imshow("Кадр", frame);
imshow("Маска переднего плана", fgMask);
// Нажмите ESC для выхода
if (waitKey(30) == 27) break;
}
// Освободить ресурсы
cap.release();
destroyAllWindows();
return 0;
}
Вычисление оптического потока
Оптический поток используется для вычисления движения объектов в видеокадрах.
Разреженный оптический поток (метод Лукаса — Канаде):
Пример
#include <iostream>
using namespace cv;
using namespace std;
int main() {
// Открыть видеофайл или камеру
VideoCapture cap("video.mp4");
if (!cap.isOpened()) {
cout << "Ошибка: не удалось открыть видеофайл или камеру!" << endl;
return -1;
}
// Прочитать первый кадр
Mat oldFrame, oldGray;
cap >> oldFrame;
cvtColor(oldFrame, oldGray, COLOR_BGR2GRAY);
// Выбрать особые точки
vector<Point2f> oldPoints;
goodFeaturesToTrack(oldGray, oldPoints, 100, 0.3, 7);
// Обработать кадры видео
Mat frame, gray;
while (true) {
cap >> frame;
if (frame.empty()) break;
// Преобразовать в оттенки серого
cvtColor(frame, gray, COLOR_BGR2GRAY);
// Вычислить оптический поток
vector<Point2f> newPoints;
vector<uchar> status;
vector<float> err;
calcOpticalFlowPyrLK(oldGray, gray, oldPoints, newPoints, status, err);
// Нарисовать траектории оптического потока
for (size_t i = 0; i < oldPoints.size(); i++) {
if (status[i]) {
line(frame, oldPoints[i], newPoints[i], Scalar(0, 255, 0), 2);
circle(frame, newPoints[i], 3, Scalar(0, 0, 255), -1);
}
}
// Обновить кадры и характерные точки
oldGray = gray.clone();
oldPoints = newPoints;
// Вывести результат
imshow("Оптический поток", frame);
// Нажмите ESC для выхода
if (waitKey(30) == 27) break;
}
// Освободить ресурсы
cap.release();
destroyAllWindows();
return 0;
}