Я совершенно новичок в технике и алгоритмах сшивания изображений. Что мне нужно, это сшить несколько изображений (от 2 до 20). Размер изображения составляет около 4-5 МБ, а разрешение — 4000×3000.
Так как у меня есть .NET фон, я попробовал пример сшивания EmguCV, который идет в комплекте с установочным пакетом. Но все время я получаю исключение OutOfMemory или не могу выделить ххххх байт. После этого я попытался написать нативное консольное приложение C ++, которое использует OpenCV, и получил те же результаты. Итак, проблема в реализации сшивания или, может быть, мне нужно установить некоторые специальные настройки для класса Stitcher?
Пробовал разные версии Emgu — 2.9, 2.4.2 и 2.4, OpenCV — 2.4.7
Изменение размера изображения до 800×600 не помогает. Когда это довольно маленькая библиотека, возвращаем 0 в качестве результата.
Я тестировал его на двух разных машинах: Windows 8 x64 с 8 ГБ оперативной памяти и Windows 7 x64 с 16 ГБ. В обоих случаях приложение пытается использовать всю свободную память, а затем вылетает.
Кто-нибудь знает, какой максимальный размер изображения может обрабатывать эта библиотека? Какие настройки я должен использовать, чтобы уменьшить использование памяти? Кто-нибудь смог прошить большие изображения?
Буду признателен за любую помощь или совет.
Спасибо!
Код EmguCV C # (на самом деле это код из примера приложения EmguCV Image Stitching)
private void selectImagesButton_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.CheckFileExists = true;
dlg.Multiselect = true;
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
sourceImageDataGridView.Rows.Clear();
Image<Bgr, Byte>[] sourceImages = new Image<Bgr, byte>[dlg.FileNames.Length];
for (int i = 0; i < sourceImages.Length; i++)
{
sourceImages[i] = new Image<Bgr, byte>(dlg.FileNames[i]);
using (Image<Bgr, byte> thumbnail = sourceImages[i].Resize(200, 200, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, true))
{
DataGridViewRow row = sourceImageDataGridView.Rows[sourceImageDataGridView.Rows.Add()];
row.Cells["FileNameColumn"].Value = dlg.FileNames[i];
row.Cells["ThumbnailColumn"].Value = thumbnail.ToBitmap();
row.Height = 200;
}
}
try
{
using (Stitcher stitcher = new Stitcher(true))
{
Image<Bgr, Byte> result = stitcher.Stitch(sourceImages);
resultImageBox.Image = result;
}
}
finally
{
foreach (Image<Bgr, Byte> img in sourceImages)
{
img.Dispose();
}
}
}
}
Код OpenCV C ++:
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"#include "opencv2/features2d/features2d.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/calib3d/calib3d.hpp"#include <opencv2\stitching\stitcher.hpp>
using namespace cv;
using namespace std;
int main()
{
Stitcher stitcher = Stitcher::createDefault();
vector<Mat> images;
Mat img1 = imread("1.jpg");
Mat img2 = imread("2.jpg");
if(!img1.data && !img2.data)
{
cout<<"Error!\n";
return -1;
}
Mat Result;
//add images to the array
images.push_back(img1);
images.push_back(img2);
cout<<"Stitching started...\n";
Stitcher::Status status = stitcher.stitch(images, Result);
if (status != Stitcher::OK)
{
cout << "Can't stitch images, error code = " << status << endl;
}
imwrite("result.jpg",Result);
return 0;
}
ОБНОВИТЬ:
После отключения Wave Corerection в брошюровщике я смог обработать большие файлы, и он не заполняет всю свободную оперативную память.
Мне также интересно, что будет лучшим способом для обработки нескольких изображений. Сшивать их одно за другим или помещать все изображения в массив и возложить всю ответственность за обработку на библиотеку OpenCV?
Есть ли описание алгоритма сшивания, которое реализовано в библиотеке OpenCV?
Я только что нашел эту диаграмму http://docs.opencv.org/modules/stitching/doc/introduction.html
Я хочу знать и понимать все детали сцены, потому что я буду обрабатывать разные изображения с разным разрешением и размером. Поэтому для меня важно балансировать между производительностью и качеством.
Спасибо!
Задача ещё не решена.
Других решений пока нет …