Вопрос или проблема
Я работаю над проектом на C++, в котором мне нужно соединить несколько 16-битных изображений, которые перекрываются горизонтально и вертикально, а затем сохранить объединенное изображение. Есть ли библиотека, которую я могу использовать для выполнения этой задачи?
Я пытался использовать объект Stitcher из OpenCV, но безуспешно, потому что было выброшено следующее исключение:
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.0.1) /home/rar/opencv_build/opencv/modules/stitching/src/exposure_compensate.cpp:317: error: (-215:Assertion failed) _image.type() == CV_8UC3 in function 'apply'
Вот мой фрагмент кода, который выполняет сшивание:
// вектор, содержащий 16-битные изображения
std::vector<cv::UMat> images;
cv::Ptr<cv::Stitcher> stitcher = cv::Stitcher::create();
cv::UMat stitched;
cv::Stitcher::Status status = stitcher->stitch(images, stitched); // Выполняет сшивание изображений и выводит статус
Другие люди, похоже, столкнулись с той же проблемой, с которой столкнулся я [https://answers.opencv.org/question/34795/stitching-16bits-greyscale-images/]
Существует по крайней мере 2 типа 16-битных изображений: градации серого и RGB.
Компания, в которой я работаю, имеет SDK для обработки изображений, который поддерживает оба типа и может сшивать 2 (или более) изображения, используя код на C/C++ таким образом:
BITMAPHANDLE smallBmp1 = {0}, smallBmp2 = {0}, bigBmp = {0};
int ByteOrder = ORDER_GRAY; // измените на ORDER_BGR, если изображения цветные, а не градации серого
//загрузить 2 входных изображения
L_LoadBitmap(imageFile1, &smallBmp1, sizeof BITMAPHANDLE, 16, ByteOrder, 0, 0);
L_LoadBitmap(imageFile2, &smallBmp2, sizeof BITMAPHANDLE, 16, ByteOrder, 0, 0);
//убедитесь, что оба битмапа имеют одну и ту же перспективу просмотра (ориентацию)
L_ChangeBitmapViewPerspective(0, &smallBmp1, sizeof BITMAPHANDLE, TOP_LEFT);
L_ChangeBitmapViewPerspective(0, &smallBmp2, sizeof BITMAPHANDLE, TOP_LEFT);
//подготовить большое изображение для удержания результата
L_CreateBitmap(&bigBmp, sizeof BITMAPHANDLE, TYPE_CONV,
BITMAPWIDTH(&smallBmp1) + BITMAPWIDTH(&smallBmp2), //ширина - это общая ширина
max(BITMAPHEIGHT(&smallBmp1), BITMAPHEIGHT(&smallBmp2)), //высота - больше из двух
16, ByteOrder, 0, TOP_LEFT, 0, 0);
//сошить 2 изображения на большое изображение
L_CombineBitmap(&bigBmp, 0, 0, BITMAPWIDTH(&smallBmp1), BITMAPHEIGHT(&smallBmp1), &smallBmp1, 0, 0, CB_OP_ADD | CB_DST_0 | CB_RAWCOMBINE, 0);
L_CombineBitmap(&bigBmp, BITMAPWIDTH(&smallBmp1), 0, BITMAPWIDTH(&smallBmp2), BITMAPHEIGHT(&smallBmp2), &smallBmp2, 0, 0, CB_OP_ADD | CB_DST_0 | CB_RAWCOMBINE, 0);
//сохранить результат
L_SaveBitmap(outputFile, &bigBmp, FILE_TIFLZW, 16, 0, 0);
//освободить память
L_FreeBitmap(&smallBmp1);
L_FreeBitmap(&smallBmp2);
L_FreeBitmap(&bigBmp);
Функция, которая выполняет само сшивание задокументирована здесь.
Если вы хотите попробовать инструмент, есть бесплатная версия для оценки, которую вы можете загрузить здесь.
Ответ или решение
Библиотеки для сшивания 16-битных изображений на C++
В вашей C++ проекте, где требуется сшивание нескольких 16-битных изображений, существует два основных подхода: использовать известные библиотеки, такие как OpenCV, или специализированные решения, такие как LEADTOOLS. Мы рассмотрим оба варианта, с фокусом на проблемы и решения, с которыми вы столкнулись.
Проблема с OpenCV
Вы попытались использовать объект Stitcher из OpenCV, но столкнулись с ошибкой, связанной с типом изображения. Дело в том, что текущая версия OpenCV (4.0.1 и новее) не поддерживает 16-битные изображения для сшивания. На данный момент OpenCV работает преимущественно с 8-битными изображениями (тип CV_8UC3). Поэтому для вашего случая использование OpenCV в этом направлении нецелесообразно.
° Хотя OpenCV предоставляет мощные инструменты для обработки изображений, для конкретных задач, связанных со сшиванием 16-битных изображений, она может оказаться недостаточно гибкой.
Альтернативный вариант: LEADTOOLS
Вы упомянули наличие SDK для изображений у вашей компании, который поддерживает как 16-битные градации серого, так и цветные изображения. LEADTOOLS – это отличное решение для таких задач. Эта библиотека предлагает широкий функционал для обработки изображений и сшивания, а также поддерживает 16-битные изображения.
Пример использования LEADTOOLS для сшивания
Ваш приведённый код помогает продемонстрировать, как использовать LEADTOOLS для сшивания изображений. Ниже приведены ключевые моменты, которые стоит отметить:
-
Загрузка изображений: Функция
L_LoadBitmap
позволяет загружать 16-битные изображения, поддерживая как градации серого, так и цветные форматы. -
Проверка перспективы: Перед сшиванием следует удостовериться, что изображения имеют одинаковую перспективу. Это можно сделать с помощью
L_ChangeBitmapViewPerspective
. -
Создание результирующего изображения: Функция
L_CreateBitmap
позволяет создать большое изображение, в которое будут сшиты несколько меньших изображений. -
Сшивание изображений: С помощью функции
L_CombineBitmap
возможно сшивание изображений с указанными параметрами, такими как положение и режим комбинирования. -
Сохранение результата: После сшивания сформированное изображение может быть сохранено с помощью функции
L_SaveBitmap
.
// Пример сшивания изображений с использованием LEADTOOLS
BITMAPHANDLE smallBmp1 = {0}, smallBmp2 = {0}, bigBmp = {0};
int ByteOrder = ORDER_GRAY; // Для цветных изображений используйте ORDER_BGR
// Загрузка изображений
L_LoadBitmap(imageFile1, &smallBmp1, sizeof BITMAPHANDLE, 16, ByteOrder, 0, 0);
L_LoadBitmap(imageFile2, &smallBmp2, sizeof BITMAPHANDLE, 16, ByteOrder, 0, 0);
// Изменение перспективы
L_ChangeBitmapViewPerspective(0, &smallBmp1, sizeof BITMAPHANDLE, TOP_LEFT);
L_ChangeBitmapViewPerspective(0, &smallBmp2, sizeof BITMAPHANDLE, TOP_LEFT);
// Создание итогового изображения
L_CreateBitmap(&bigBmp, sizeof BITMAPHANDLE, TYPE_CONV,
BITMAPWIDTH(&smallBmp1) + BITMAPWIDTH(&smallBmp2),
max(BITMAPHEIGHT(&smallBmp1), BITMAPHEIGHT(&smallBmp2)),
16, ByteOrder, 0, TOP_LEFT, 0, 0);
// Сшивание изображений
L_CombineBitmap(&bigBmp, 0, 0, BITMAPWIDTH(&smallBmp1), BITMAPHEIGHT(&smallBmp1), &smallBmp1, 0, 0, CB_OP_ADD | CB_DST_0 | CB_RAWCOMBINE, 0);
L_CombineBitmap(&bigBmp, BITMAPWIDTH(&smallBmp1), 0, BITMAPWIDTH(&smallBmp2), BITMAPHEIGHT(&smallBmp2), &smallBmp2, 0, 0, CB_OP_ADD | CB_DST_0 | CB_RAWCOMBINE, 0);
// Сохранение результата
L_SaveBitmap(outputFile, &bigBmp, FILE_TIFLZW, 16, 0, 0);
// Очистка
L_FreeBitmap(&smallBmp1);
L_FreeBitmap(&smallBmp2);
L_FreeBitmap(&bigBmp);
Заключение
Если ваша цель — сшивание 16-битных изображений, такие инструменты, как LEADTOOLS, предлагают более подходящее решение, чем OpenCV. Важно отметить, что использование специализированных библиотек может значительно облегчить вашу работу и избавить от возникновения ошибок, связанных с несовместимостью форматов изображений.
Ресурсы
- LEADTOOLS SDK: Бесплатная оценочная версия для знакомства с функциями библиотеки.
- Документация LEADTOOLS: Полное руководство по функциям сшивания и обработки изображений.
Эти ресурсы помогут вам эффективно реализовать сшивание изображений в вашем проекте.