Разделение каналов из массива RGB в C ++ без OpenCV

0

Я работаю в C++ с массивом unsigned char, представляющим пиксели в изображении. Каждый пиксель имеет 3 канала (R, G, B). Изображение представлено линейно, вроде как

RGBRGBRGBRGB.....

Как я могу разделить каждый из R, G и B на отдельные массивы эффективно?

Я пытался:

  for(int pos = 0; pos < srcWidth * srcHeight; pos++) {
      int rgbPos = pos * 3;
      splitChannels[0][pos] = rgbSrcData[rgbPos];
      splitChannels[1][pos] = rgbSrcData[rgbPos + 1];
      splitChannels[2][pos] = rgbSrcData[rgbPos + 2];
  }

Но это удивительно медленно.

Благодарю!

  • 1
    Вы проверили, сколько времени занимает запуск этого цикла, не считая другого кода? Не похоже, что это должно быть очень медленно. Кроме того, есть ли причина, по которой вы должны разделить их? Почему бы просто не выполнить цикл и использовать pos <srcWidth * srcHeight * 3 и pos + = 3, если вам нужен определенный цвет?
  • 0
    Да, это медленно. Около 7 миллисекунд для 3-мегапиксельного изображения. Я должен разделить их, чтобы вызвать другую библиотеку.
Показать ещё 3 комментария
Теги:
optimization
image-processing
image

2 ответа

1
Лучший ответ

Моя попытка: загрузить и сохранить байты четыре-четыре. Байт-скремблирование будет утомительным, но, возможно, пропускная способность улучшится.

// Load 4 interleaved pixels
unsigned int RGB0= ((int*)rgbSrcData)[i];
unsigned int RGB1= ((int*)rgbSrcData)[i + 1];
unsigned int RGB2= ((int*)rgbSrcData)[i + 2];

// Rearrange and store 4 unpacked pixels
((int*)splitChannels[0])[j]= 
    (RGB0 & 0xFF) | (RGB0 >> 24) | (RGB1 & 0xFF0000) | ((RGB2 & 0xFF00) << 16);
((int*)splitChannels[1])[j]= 
    ((RGB0 & 0xFF00) >> 8) | (RGB1 & 0xFF) | (RGB1 >> 24) | (RGB2 & 0xFF0000) >> 16;
((int*)splitChannels[2])[j]= 
    ((RGB0 & 0xFF0000) >> 16) | (RGB1 & 0xFF00) | ((RGB2 & 0xFF) >> 16) | (RGB2 & 0xFF000000);

(ПРЕДОСТЕРЕЖЕНИЕ: не отключено!) Возможна также версия с поддержкой сдвига.

Решение SSE было бы более сложным (шаг 3 не сочетается с степенями 2).

  • 0
    спасибо, это отличная идея Я попробовал это, и это примерно на 10% быстрее. трудно разобраться со всем порядком.
  • 0
    Здорово ! Я был не уверен, что это будет эффективно, учитывая большие накладные расходы. Даже если код содержит ошибки, измерения времени должны быть ориентировочными. Так что, возможно, стоит поцарапать код и сэкономить несколько циклов ...
Показать ещё 2 комментария
0

Отличная методика, используемая для ускорения работы, - это цикл размотки. Вы можете прочитать об этом здесь: http://en.wikipedia.org/wiki/Loop_unwinding

  • 0
    Это не помогло. Я думаю, компилятор уже делает это, когда -O3 включен?
  • 0
    каков был твой фактор раскрутки?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню