Russian Qt Forum
Ноябрь 01, 2024, 20:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: QPixmap blur effect  (Прочитано 9936 раз)
andrew.k
Гость
« Ответ #15 : Декабрь 22, 2010, 13:24 »

В алгоритме блюра по Гауссу, делается точно так же. Сначала по строкам, потом по столбцам. Конечно матрицу никто не общитывает.
Если не обсчитывает, то чего Вы складываете 8 соседей (хотя можете сложить 2 + 2)? И чего вы берете 3х3 и делаете 10 проходов если можно просто взять матрицу больше? Гаусс здесь значит просто "колокольчик" (ближние пиксели берутся с большим весом, дальние с меньшим). А сама техника блюра (по строкам, потом по столбцам) используется с любым типом фильтра, напр. "box" (просто осреднение).

Он не из-за этого медленный, а из-за коэффициентов на которые приходится умножать соседние пикселы.
Так может Вы их просто не предвычислили? Или натыкали классов в цикле по пикселю? Если хотите давайте посмотрим код - явно что-то не так, PShop блюрит в real-time даже на скромной машине
Я подозреваю, что ты очень умный. А так же я подозреваю, что ты не один такой в этом мире. Поэтому имей это ввиду как можно чаще.
Теперь по теме.
Я поясню, для тебя, потому что ты тему читал по диагонали.
Экскурс. Когда мне потребовалось отфильтровать, я сделал среднее значение из 9 пикселов. Так как при одном проходе было размыто слабо, сделал несколько проходов. Конкретно 3. А не 10.
Если расширять квадрат квадрат, то расширять нужно до 5х5 или больше, чтобы достигнуть того же уровня размытия.
И прироста скорости это совсем не даст.
Дальше я решил попробовать блюр гаусса, чтобы улучшить вид размытия. Там сделал естественно по строчкам и столбцам.
И естественно коэффициенты не рассчитываются в цикле двадцать тысяч раз. А один раз в начале.
Но понятно, что умножение на float не способствует производительности. А хорошее размытие получается только при больших сигма и соответственно большем окне (в районе 15 точно не помню сколько меня устроило).
В любом случае все варианты выполнялись дольше секунды.
Потом пришел мой товарищ и сказал мне да сделай "обычным" быстрым фильтром.
Там берется 8 соседних точек, значение самого пиксела отбрасывается. А так как соседей восем, то вместо деления можно использовать сдвиг на 3 вправо. Это быстрее, чем деление.
Сила размытия, достигается количеством проходов.
Этот фильтр я и стал использовать. Требуемый уровень размытия достигался за 10 проходов. Эти 10 проходов выполняются меньше половины секунды. В принципе скорость приемлемая так и оставил. Или ты можешь еще ускорить? Улыбающийся
Записан
andrew.k
Гость
« Ответ #16 : Декабрь 22, 2010, 13:32 »

Сейчас не могу посмотреть реальные цифры (на реальной машине). Под виртуалкой все тормозит.
Под виртуалкой цифры такие: быстрый блюр: 1.3 сек (10 проходов). Гаусс: 5.4 ( сигма = 3 ), Гаусс: 6.9 (сигма = 4)


Вот код Гаусса. Оптимизируй.
void blurGauss( QImage &img, float sigma, bool horisontalOnly = false )
{
    QTime begin = QTime::currentTime();
    QImage newimg( img.size(), img.format() );
    int n = (int)ceil( sigma * 3 );
    double * window = new double[ n + 1 ];
    window[ 0 ] = 1.0;
    for ( int i = 1; i < n + 1; ++i )
   window[ i ] = exp( -i * i / ( 2 * sigma * sigma ) );

    unsigned short r, g, b;
    unsigned int pixel;
    float sum;
    int width = img.width();
    int height = img.height();
    unsigned int * src = ( unsigned int * )img.bits();
    unsigned int *data = new unsigned int[ width * height ];
    for ( int y = 0; y < height; ++y )
   for ( int x = 0; x < width; ++x )
        {
       sum = 0;
       r = g = b = 0;
       for ( int k = -n; k < n + 1; ++k )
       {
      if ( x + k >= 0 && x + k < width )
      {
          pixel = src[ y * width + x + k ];
          r += (unsigned short ) ( qRed( pixel ) * window[ abs( k ) ] );
          g += (unsigned short ) ( qGreen( pixel ) * window[ abs( k ) ] );
          b += (unsigned short ) ( qBlue( pixel ) * window[ abs( k ) ] );
          sum += window[ abs( k ) ];
      }
       }
       r = (unsigned short )( r / sum );
       g = (unsigned short )( g / sum );
       b = (unsigned short )( b / sum );
       data[ y * width + x] = qRgba( r, g, b, 255 );
        }
    img = QImage( (uchar *) data, width, height, QImage::Format( 4 ) ).copy();
    src = ( unsigned int *)img.bits();
    if ( horisontalOnly )
    {
   delete[] window;
   delete[] data;
   return;
    }

    for ( int x = 0; x < width; ++x )
   for ( int y = 0; y < height; ++y )
        {
       sum = 0;
       r = g = b = 0;
       for ( int k = -n; k < n + 1; ++k )
       {
      if ( y + k >= 0 && y + k < height )
      {
          pixel = src[ ( y + k ) * width + x ];
          r += (unsigned short ) ( qRed( pixel ) * window[ abs( k ) ] );
          g += (unsigned short ) ( qGreen( pixel ) * window[ abs( k ) ] );
          b += (unsigned short ) ( qBlue( pixel ) * window[ abs( k ) ] );
          sum += window[ abs( k ) ];
      }
       }
       r = (unsigned short )( r / sum );
       g = (unsigned short )( g / sum );
       b = (unsigned short )( b / sum );
       data[ y * width + x] = qRgba( r, g, b, 255 );
        }

    img = QImage( (uchar *) data, width, height, QImage::Format( 4 ) ).copy();
    delete[] window;
    delete[] data;
    qDebug() << "Blur time(sec): " << QString( "%1.%2" ).arg( begin.secsTo( QTime::currentTime() ) )
                     .arg( begin.msecsTo( QTime::currentTime() ) % 1000 );
}
Записан
Kolobok
Гость
« Ответ #17 : Декабрь 22, 2010, 13:58 »

Igors взял по 4 пикселя с каждой стороны. Это квадрат 9х9. Правда сложений будет 80
Да НЕТ же, всего 18, (9 в первом проходе и 9 во втором). Сначала (первый проход) блюрите каждый пиксель только по (одной) строке, потом, используя результат первого прохода, только по (одному) столбцу.
Устал я объяснять  Улыбающийся

Всё я понял правильно. 80 будет если всю матрицу 9х9 обсчитывать. А если строки/столбцы то 16. Сложений на одно меньше, чем слагаемых. Это я имел ввиду. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Декабрь 22, 2010, 16:19 »

Под виртуалкой цифры такие: быстрый блюр: 1.3 сек (10 проходов). Гаусс: 5.4 ( сигма = 3 ),
У меня такие результаты

Цитировать
image 2048 x 2048

Gauss size = 19 x 19
Gauss Blur time(sec):  "2.81"

Box size = 19 x 19
Box Blur time(sec):  "1.313"

Simple blur passes = 10
Simple Blur time(sec):  "2.18"

Gauss size = 13 x 13
Gauss Blur time(sec):  "1.633"

Box size = 13 x 13
Box Blur time(sec):  "1.173"
И если Вы хотите рассказать что, мол, Гаусс дает качество хуже - то не стоит, это Ваш косяк. А больше с человеком который хамит, я разговаривать не стану. Будьте здоровы
Записан
andrew.k
Гость
« Ответ #19 : Декабрь 22, 2010, 17:58 »

Во-первых, я ни разу не хамил.
Во-вторых, я нигде не сказал, что гаусс дает качество хуже. Я сказал, что Гаусс работает медленнее, чем Quick Blur.
Читать надо внимательно. Мне требуется размыть до состояния, чтобы текст не читался, а качество не важно.
Соответственно, я сравниваю результат и время его достижения разными методами. Так один проход гаусса с сигма=3 работает дольше, чем 10 проходов быстрого блюра, а получаемый результат примерно сопоставим (качество не в счет).
В-третьих, твоя таблица не позволяет сделать полезных выводов. Зачем ты потратил на это время?
Что такое Гаусс 19х19??? У Гаусса есть параметр сигма, который влияет на степень размытия и соответственно время выполнения. В самом начале темы, я написал, что я в этом не разбираюсь, но по ходу развития темы искал материал, разбирался. Поэтому что ты подразумеваешь под SimpleBlur, я могу только догадываться и чем он отличается от box blur.
Ты сказал, давай сюда код, у тебя классов понатыкано, я мол лучше могу сделать.
Я тебе дал. В результате, какая-то бесполезная таблица. Тебя не учили в универе, что нужно после лабораторной работы писать обоснованный вывод?
И подпись под таблицей гласящая: "да ты там вообще у себя поковыряй лучше и вообще мудак ты". <- Это хамство вместе с таблицей без объяснений.
« Последнее редактирование: Декабрь 22, 2010, 18:07 от andrew.k » Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.084 секунд. Запросов: 22.