Быстрая вставка линий пикселей в изображение - PullRequest
2 голосов
/ 18 декабря 2009

Моя текущая дилемма заключается в следующем:

У меня есть 2550x3300 tiff. В определенные (переменные) точки в моем tiff мне нужно вставить строку пикселей из другого места в tiff. например Мне нужно вставить 12 копий в строку строки 100 между строками 500 и 501.

Я уже несколько дней ищу разные методы обработки изображений и не могу найти никого, кто бы занимался подобными вещами, заставляя меня поверить, что я, вероятно, поступаю неправильно.

В качестве альтернативы, если то, что я делаю, просто очень медленно и нет лучшего способа сделать это, то какой самый быстрый способ сделать это? Используя GDI +, у меня уходит около 12 секунд, чтобы добавить 1330 строк, 7,7 секунды, если я использую «unsafe» (я делаю все это в C # прямо сейчас), и если я использую FreeImage dll, я могу уменьшить его примерно до 2,5 секунд.

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 19 декабря 2009

Возможно, вам было бы лучше взглянуть на структуры данных. Если бы вы имели дело только с одним измерением, B-дерево было бы очень эффективным способом вставить столько раз, сколько вам хотелось бы, с логарифмической стоимостью. Если вам нужно вставить столбцы и строки, вам понадобится нечто более сложное, но если вы вставляете и удаляете строки, то ваша жизнь может быть относительно простой.

Было бы полезно, если бы вы могли дать описание изображения в виде абстрактного типа данных с всеми операциями, которые вы хотите выполнить, и некоторым представлением о том, какими должны быть затраты.

Если вам нужно готовое решение, попробуйте представить строки изображения в виде записей в таблице базы данных. Или другой вариант - обработать ваши ряды пикселей как строки, и тогда вы можете попробовать библиотеку «C-шнуры», описанную в статье Бема, Аткинсона и Пласса . Он описывает структуру данных для эффективного управления очень большими строками.

0 голосов
/ 21 декабря 2009

Мне кажется, вы, вероятно, максимально использовали FreeImage.

Источник FreeImage (http://freeimage.sourceforge.net/download.html, BitmapAccess.cpp :: FreeImage_AllocateT), по-видимому, неправильно размещает хранилище изображений как одномерный массив:

unsigned dib_size = FreeImage_GetImageSize(width, height, bpp); 

bitmap->data = (BYTE *)FreeImage_Aligned_Malloc(dib_size * sizeof(BYTE), FIBITMAP_ALIGNMENT);

Здесь dib_size - это «размер битмапа, не зависящий от устройства», а bpp - «бит на пиксель».

Я предполагаю, что вы используете PixelAccess.cpp :: FreeImage_GetScanLine (), чтобы получить строку для копирования:

BYTE * DLL_CALLCONV
FreeImage_GetScanLine(FIBITMAP *dib, int scanline) {
 return (dib) ? CalculateScanLine(FreeImage_GetBits(dib), FreeImage_GetPitch(dib), scanline) : NULL;
}

который звонит

inline unsigned char *
CalculateScanLine(unsigned char *bits, unsigned pitch, int scanline) {
 return (bits + (pitch * scanline));
}

, который выглядит как O (1) для поиска на основе массива.

Поскольку FreeImage внутренне использует хранилище статических одномерных массивов, не совсем понятно, как вы достигнете производительности, превышающей O (n), при увеличении изображения (например, при вставке копий строк). Мне кажется, что лучшее, что может сделать FreeImage, - это внутренне малокое новое хранилище, достаточное для увеличения изображения, а затем копирования данных изображения из источника в новое изображение. Казалось бы, это O (n).

Использование новой структуры данных (такой как B-дерево) потребует некоторых усилий, но даст вам лучшие характеристики времени вставки (O (log (n))). Однако компромисс для ускорения - увеличенное пространство хранения. Вы будете хранить каждый пиксель в большем количестве места.

Поскольку GDI + кажется закрытым исходным кодом, я не уверен, как он реализует растровые изображения, но, учитывая характеристики производительности, он кажется хуже, чем FreeImage.

0 голосов
/ 18 декабря 2009

Если только это не является проблемой производительности для использования, я бы придерживался GDI + просто потому, что он встроен в среду и снижает зависимости. Если вам действительно нужна производительность, используйте библиотеку FreeImage.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...