Я хочу знать, есть ли способ выполнять операции над двумя изображениями, не анализируя их попиксельно. Я пытаюсь сделать смешанный вид с двух камер в режиме реального времени. Поэтому операции должны выполняться со скоростью не менее 10 кадров в секунду.
Первая версия моей программы выглядит так:
CPylonImage im1;
CPylonImage im2;
uint32_t width = im2.GetWidth();
uint32_t height = im2.GetHeight();
uint8_t* buffer1 = static_cast<uint8_t*>( im1.GetBuffer());
uint8_t* p1 = buffer1;
uint8_t* buffer2 = static_cast<uint8_t*>( im2.GetBuffer());
uint8_t* p2 = buffer2;
for (uint32_t y = 0; y < height; ++y)
{
for (uint32_t x = 0; x < width; ++x, ++p1)
{
*p2 = (uint8_t)*p1+*p2;
++p2;
}
}
ShowImage( im2, "Mixed image");
Но это было слишком медленно.
Буду очень признателен за любой ответ.
Код, которым вы поделились, имеет много проблем, и в разделе комментариев вы заявляете, что он даже не работает. Я думаю, что вы должны сосредоточиться на решении одной проблемы за раз, и когда код действительно работает, то имеет смысл попытаться сделать это быстрее.
Ваше приложение получает width
из одного изображения и тому height
с другой. Это редко приводит к хорошим вещам.
uint32_t width = im1.GetWidth();
uint32_t height = im2.GetHeight();
Хорошо, так buffer1
указывает на im1
, а также p1
указывает на buffer1
, Я думаю, что вам не нужно p1
Просто используйте buffer1
вместо.
uint8_t* buffer1 = static_cast<uint8_t*>( im1.GetBuffer());
uint8_t* p1 = buffer1;
И сейчас buffer2
а также p2
указывает на im1
, Какие?! Не должно ли это быть im2
??? Вам не нужно p2
,
uint8_t* buffer2 = static_cast<uint8_t*>( im1.GetBuffer());
uint8_t* p2 = buffer2;for (uint32_t y = 0; y < height; ++y)
{
Следующий цикл увеличивается p
, которая является переменной, которая не была объявлена. Я полагаю, вы пытались увеличить p1
,
for (uint32_t x = 0; x < width; ++x, ++p)
{
*p2 = (uint8_t)*p1+*p2;
++p2;
}
}
Сейчас показывать не имеет смысла im2
так как это не было изменено кодом.
ShowImage( im2, "Mixed image");
Еще одна вещь, если im1
а также im2
имеют разные размеры, это может привести к аварии.
Я настоятельно рекомендую вам взглянуть на следующий пост, чтобы узнать, как лучше задавать вопросы и попросить людей помочь вам: Короткий, Автономный, Правильный (Компилируемый), Пример
Существует несколько технологий, которые могут ускорить обработку этих арифметических операций:
Прежде чем начать оптимизацию, убедитесь, что ваш вывод правильный!
Выражение
*p2 = (uint8_t)*p1+*p2;
переполнится и даст вам неправильные результаты. В ролях (uint8_t)
не будет волшебно
обрезать ваши значения в допустимый диапазон, но только конвертировать ваш результат сложения.
В этом случае приведение ничего не делает, так как операнды — это uint8_t.
const uint16_t a = *p1;
const uint16_t b = *p2;
const uint16_t sum = a+b;
*p2 = static_cast<uint8_t>( sum > 255 ? 255 : sum );
Еще лучше, добавить результаты и разделить на два, таким образом, вы остаетесь в допустимом диапазоне,
только потерять LSB, и это без ответвления.
*p2 = static_cast<uint8_t>( sum >> 1 );
Еще несколько советов, которые вы можете попробовать, прежде чем использовать другую технику.
const
а также restrict
,например
void add( const CPylonImage& im1, CPylonImage& im2 )
{
const int w = 1294; //im1.width();
const int h = 964; //im1.height();
const uint8_t* restrict buffer1 = static_cast<uint8_t*>( im1.getBuffer() );
uint8_t* restrict buffer2 = static_cast<uint8_t*>( im2.getBuffer() );
for( int i = 0; i < w*h; i++ )
{
const uint16_t a = buffer1[i];
const uint16_t b = buffer2[i];
const uint16_t sum = a+b >> 1;
buffer2[i] = static_cast<uint8_t>( sum );
}
}