Работа с изображениями: resize и crop на C++ с OpenCV
В современной разработке приложений, особенно в области компьютерного зрения, веб-скрапинга или обработки медиафайлов, часто возникает необходимость программно изменять размер (resize) и обрезать (crop) изображения. Язык C++ в сочетании с мощной библиотекой OpenCV предоставляет для этого все необходимые инструменты. В данной статье мы подробно разберём, как выполнять эти операции, какие параметры влияют на качество результата, и приведём готовые примеры кода.
Библиотека OpenCV — стандарт де-факто для работы с изображениями на C++
OpenCV (Open Source Computer Vision Library) — это кроссплатформенная библиотека с открытым исходным кодом, содержащая сотни оптимизированных алгоритмов для обработки изображений и видео. Она написана на C++ и имеет привязки для Python, Java и других языков. Для C++ OpenCV является наиболее производительным и функциональным решением.
Основные преимущества OpenCV для задач resize и crop:
- Высокая скорость — все функции используют SIMD-инструкции и многопоточность.
- Гибкость — поддержка различных методов интерполяции (билинейная, бикубическая, метод Ланцоша и др.).
- Удобство — работа с изображениями через класс
cv::Mat, который автоматически управляет памятью.
Установка OpenCV для C++
Для начала работы необходимо установить библиотеку. Наиболее распространённый способ — через менеджер пакетов vcpkg или сборка из исходников. Пример установки через vcpkg:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg install opencv4
После установки подключите библиотеку в вашем CMakeLists.txt:
find_package(OpenCV REQUIRED)
target_link_libraries(your_project ${OpenCV_LIBS})
Изменение размера изображения (resize)
Функция cv::resize() позволяет изменить размеры исходного изображения до заданной ширины и высоты. Синтаксис:
cv::resize(
InputArray src, // исходное изображение
OutputArray dst, // результирующее изображение
Size dsize, // новый размер (ширина, высота)
double fx = 0, // масштаб по X (если dsize не задан)
double fy = 0, // масштаб по Y
int interpolation = INTER_LINEAR // метод интерполяции
);
Параметр interpolation определяет алгоритм, используемый для вычисления новых пикселей. Основные варианты:
INTER_NEAREST— метод ближайшего соседа (быстро, но низкое качество).INTER_LINEAR— билинейная интерполяция (хороший баланс скорости и качества).INTER_CUBIC— бикубическая интерполяция (более качественно, но медленнее).INTER_LANCZOS4— интерполяция Ланцоша (наилучшее качество при увеличении).
Пример увеличения изображения в 2 раза с бикубической интерполяцией:
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
cv::Mat src = cv::imread("input.jpg");
if (src.empty()) {
std::cerr << "Не удалось загрузить изображение" << std::endl;
return -1;
}
cv::Mat dst;
cv::resize(src, dst, cv::Size(), 2.0, 2.0, cv::INTER_CUBIC);
cv::imwrite("output_resized.jpg", dst);
std::cout << "Изображение увеличено и сохранено" << std::endl;
return 0;
}
Обрезка изображения (crop)
В OpenCV нет отдельной функции для обрезки. Вместо этого используется механизм Region of Interest (ROI) — выделение прямоугольной области на изображении. Это выполняется с помощью оператора () или метода cv::Mat::operator().
Синтаксис обрезки:
cv::Rect roi(x, y, width, height);
cv::Mat cropped = original(roi);
Важно: cv::Rect не копирует данные, а создаёт заголовок, указывающий на ту же память. Если нужно получить независимую копию, используйте .clone().
Пример обрезки центральной части изображения:
#include Также в библиотеке
Парсинг HTML в C# (.NET): библиотеки HtmlAgilityPack и AngleSharp
Авторизация и аутентификация в Node.js: JWT, Passport.js, bcrypt
mikro-orm для TypeScript: полное руководство с примерами
ORM для Kotlin: сравнение и примеры (Exposed, Ktorm, Hibernate)
Работа с Apache Kafka в Node.js: библиотека KafkaJS