Автор Тема: Скоростное преобразование цветного изображения в черно-белое  (Прочитано 1396 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Vespen

  • Коллежский регистратор
  • *
  • Сообщений: 2
  • Репутация: 0
Привет, разбирался с этим вопросом, написал простенькую функцию которая преобразует цветное изображение TBitmap в черно-белое по-пиксельно. Проблема в том, что данный алгоритм очень долго обрабатывается =( Как можно значительно ускорить данный процесс? Я работаю с изображением разрешения 1280х1024, это аж 1310720 итераций цикла(( Может кто подскажет способ пореальнее.

Моя функция:
Цитировать
void FadeImage(Graphics::TBitmap *MyImage) {
int Height = 0, Width = 0;
TColor Color;
unsigned Grey, Red, Green, Blue;

Height = MyImage->Height;
Width = MyImage->Width;

        for (int Y=0; Y<=Height; Y++) {
                for (int X=0; X<=Width; X++) {
                Color = MyImage->Canvas->Pixels[X][Y];
                Red = GetRValue(Color);
                Green = GetGValue(Color);
                Blue = GetBValue(Color);
                Grey = Blue*0.11 + Green*0.59 + Red*0.3;
                Color = (TColor)RGB(Grey, Grey, Grey);
                MyImage->Canvas->Pixels[X][Y] = Color;
                }
        }
}

Оффлайн Alexiski

  • Любитель давать советы
  • Надворный советник
  • *****
  • Сообщений: 307
  • Репутация: 15
  • Пол: Мужской
Посмотрите свойство ScanLine. С его использованием доступ к пикселям значительно быстрее, чем через свойство Pixels

Оффлайн Vespen

  • Коллежский регистратор
  • *
  • Сообщений: 2
  • Репутация: 0
Вот так чтоли? Помоему скорость такая же будет...

Цитировать
void FadeImage(Graphics::TBitmap *MyImage) {
int Height = 0, Width = 0;
unsigned Grey, Red, Green, Blue;

Height = MyImage->Height;
Width = MyImage->Width;

        for (int Y=0; Y<Height; Y++) {
        unsigned char * MyLine = static_cast<unsigned char*>(MyImage->ScanLine[Y]);
                for(int X=0; X<Width; X++) {
                Red = MyLine[X*3+2];
                Green = MyLine[X*3+1];
                Blue = MyLine[X*3+0];
                Grey = Red*0.3 + Green*0.59 + Blue*0.11;
                }
        }
}

Как применить полученный массив с цветом (MyLine) к моему изображению?

Оффлайн Alexiski

  • Любитель давать советы
  • Надворный советник
  • *****
  • Сообщений: 307
  • Репутация: 15
  • Пол: Мужской
Примерно так, только насчет смещений/шага не могу сказать точно, нет под рукой исходника.
Назад -  там же по месту и править. Это выдается прямая ссылка в область хранения битмапа.
Скорость возрастает значительно, проверено.
Просто свойство Pixels реализовано очень неэффективно для массовых операций.

Оффлайн VC15

  • Коллежский регистратор
  • *
  • Сообщений: 2
  • Репутация: 0
  • Пол: Мужской
Цитировать
Я работаю с изображением разрешения 1280х1024, это аж 1310720 итераций цикла
Как ни крути, а каждый пиксель тебе всё равно надо обработать, поэтому не надо страшиться такого количества итераций цикла. Из этого также следует, что повышеня скорости ты можешь добиться только за счёт создания эффективной реализации.
Кстати, при наличии неплохой видеокарты можно воспользоваться OpenGL. Я не совсем уверен, но по логике должно получиться быстро. Идея в следующем:
1) Создаешь в OpenGL FBO размером с твоё изображение;
2) Настраиваешь пиксельный маппинг цветовых каналов, вызвав glPixelTransferi(GL_MAP_COLOR, GL_TRUE), а затем glPixelMap для каждого канала;
3) Выводишь картинку с помощью glDrawPixels;
4) Читаешь получившуюся картинку в буфер.

Извини, что не очень подробно, но если заинтересовало, тебе лучше будет самому изучить материалы по OpenGL. К тому же я не уверен, что это даст огромный прирост производительности, но по логике на видеокарте такие опреации должны выполняться быстрее.
« Последнее редактирование: °ТУгбв 28, 2009, 03:19:20 pm от VC15 »