Более быстрое преобразование упакованного BGR в формат планарных пикселей RGB.

Из SDK я получаю изображения, упакованные в формате пикселей BGR, то есть BGRBGRBGR. Для другого приложения мне нужно преобразовать этот формат в планарный RGB RRRGGGBBB.

Я использую С# .NET 4.5 32bit, и данные находятся в байтовых массивах одинакового размера.

Прямо сейчас я перебираю исходный массив и присваиваю значения BGR соответствующим местам в целевом массиве, но это занимает слишком много времени (180 мс для 1,3-мегапиксельного изображения). Процессор, на котором выполняется код, имеет доступ к MMX, SSE, SSE2, SSE3, SSSE3.

Есть ли способ ускорить конвертацию?

изменить: вот преобразование, которое я использую:

// the array with the BGRBGRBGR pixel data
byte[] source;
// the array with the RRRGGGBBB pixel data
byte[] result;
// the amount of pixels in one channel, width*height
int imageSize;

for (int i = 0; i < source.Length; i += 3)
{
    result[i/3] = source[i + 2]; // R
    result[i/3 + imageSize] = source[i + 1]; // G
    result[i/3 + imageSize * 2] = source[i]; // B
}

редактировать: я попытался разделить доступ к исходному массиву на три цикла, по одному для каждого канала, но это не очень помогло. Так что я открыт для предложений.

for (int i = 0; i < source.Length; i += 3)
{
    result[i/3] = source[i + 2]; // R
}

for (int i = 0; i < source.Length; i += 3)
{
    result[i/3 + imageSize] = source[i + 1]; // G
}

for (int i = 0; i < source.Length; i += 3)
{
    result[i/3 + imageSize * 2] = source[i]; // B
}

Bump, потому что вопрос до сих пор без ответа. Любой совет очень ценится!


person RBS    schedule 12.12.2014    source источник
comment
Кому-либо было бы трудно увидеть, можно ли сделать более быстрое преобразование, когда исходное преобразование недоступно.   -  person Sayse    schedule 12.12.2014
comment
Пожалуйста, покажите код для вашего текущего подхода   -  person HimBromBeere    schedule 12.12.2014
comment
Голосуйте за открытие. Серьезно, он не просит библиотеку. Даже учитывая код, я вижу пару способов ускорить его - ЗНАЧИТЕЛЬНО - переписав его. На это есть действительные ответы в рамках .NET framework/стандартной экосистемы Visual Studio БЕЗ сторонней библиотеки.   -  person TomTom    schedule 12.12.2014
comment
Для справки, я поставил vtc, потому что без примера кода это было неясно. Проголосовали за открытие   -  person Sayse    schedule 12.12.2014
comment
Мне бы очень хотелось услышать ваши идеи, TomTom. Но видимо вернуть вопрос в тему не получится?   -  person RBS    schedule 12.12.2014
comment
Умножение обычно выполняется быстрее, чем деление, поэтому я советую использовать i++ и i*3, а не i+=3 и i/3. Также стоит учитывать: выполнять вышеупомянутую математическую операцию только один раз за итерацию и сохранять ее в переменной, а не выполнять ее три раза.   -  person Nyerguds    schedule 05.01.2018


Ответы (2)


Вы можете попробовать использовать инструкцию SSE3 PSHUFB — Packed Shuffle Bytes. Убедитесь, что вы используете выровненное чтение/запись памяти. Вам придется сделать что-то хитрое, чтобы справиться с последним оборванным значением B в каждом блоке размера XMMWORD. Может быть сложно сделать это правильно, но должно быть огромное ускорение. Вы также можете поискать код библиотеки. Я предполагаю, что вам нужно будет создать DLL C или C++ и использовать P/Invoke, но, возможно, есть способ использовать инструкции SSE из C#, о котором я не знаю.

редактировать - этот вопрос немного другая проблема, ARGB для BGR, но используемые методы аналогичны тому, что вам нужно.

person japreiss    schedule 12.12.2014
comment
Спасибо за помощь, но мне, к сожалению, не хватает знаний о встроенных функциях, поэтому код мне мало чем поможет, а использование библиотек только для этой небольшой задачи не может быть и речи. - person RBS; 17.12.2014

У компании Basler есть SDK для своих камер под названием Basler Pylon, работающий в Windows и Linux.
В этом SDK есть API для C++, C# и т. д.
Он имеет класс преобразования изображений PixelDataConverter, который, похоже, вам подходит. необходимость.

person Tobias Knauss    schedule 07.03.2017