Название: QPixmap blur effect Отправлено: andrew.k от Декабрь 18, 2010, 18:29 С рисованием плохо знаком. У меня есть QPixmap на нем граб главной формы, мне нужно применить к нему эффект размытия или в принципе любой другой, но чтобы содержимое стало нечитаемым.
Qt 4.4.3 поэтому QGraphicsBlurEffect там нет. Вторая проблема, я не могу понять, как полученным пиксмапом зарисовать форму. Пиксмап который я отрисовываю в paintEvent оказывается как бы на заднем плане. А почти все элементы управления все равно отрисовывают себя поверх. Название: Re: QPixmap blur effect Отправлено: Drafter от Декабрь 19, 2010, 00:02 Цитировать Пиксмап который я отрисовываю в paintEvent оказывается как бы на заднем плане. А почти все элементы управления все равно отрисовывают себя поверх. Эта проблема решается написанием своего виджета (с нужной полупрозрачностью), который размещается поверх других (и включается-выключается по необходимости). Что же касается эффектов - боюсь, Вам придётся "размывать" ручками, если нет возможности перейти на более современную версию Qt. Название: Re: QPixmap blur effect Отправлено: andrew.k от Декабрь 19, 2010, 02:37 Цитировать Пиксмап который я отрисовываю в paintEvent оказывается как бы на заднем плане. А почти все элементы управления все равно отрисовывают себя поверх. Эта проблема решается написанием своего виджета (с нужной полупрозрачностью), который размещается поверх других (и включается-выключается по необходимости). Что же касается эффектов - боюсь, Вам придётся "размывать" ручками, если нет возможности перейти на более современную версию Qt. Так что вопрос в том, каким образом теперь разместить этот QLabel "поверх других" и чтобы он растягивался по размеру формы, как будто в лэйауте? Название: Re: QPixmap blur effect Отправлено: Igors от Декабрь 19, 2010, 13:02 Некоторое подобие размытия я сделал (для каждого пиксела посчитал среднее значение его и всех соседних). И таких три прохода. Получилось уродское подобие размытия. Пока сойдет. Другого не слишком сложного алгоритма не нашел. Все размывают Гауссом и никому от этого плохо не стало. Два и более прохода не нужно, просто возьмите больше соседей для осреднения. А самое главное - не "каждый пиксель" (долго) а сначала "по строкам" а затем "по столбцам" (ну или наоборот, дело вкуса)Название: Re: QPixmap blur effect Отправлено: andrew.k от Декабрь 19, 2010, 21:49 Некоторое подобие размытия я сделал (для каждого пиксела посчитал среднее значение его и всех соседних). И таких три прохода. Получилось уродское подобие размытия. Пока сойдет. Другого не слишком сложного алгоритма не нашел. Все размывают Гауссом и никому от этого плохо не стало. Два и более прохода не нужно, просто возьмите больше соседей для осреднения. А самое главное - не "каждый пиксель" (долго) а сначала "по строкам" а затем "по столбцам" (ну или наоборот, дело вкуса)Название: Re: QPixmap blur effect Отправлено: Igors от Декабрь 20, 2010, 18:22 Повторюсь: блюрьте сначала строки, потом столбцы (а не всех соседей - это медленно)
Название: Re: QPixmap blur effect Отправлено: andrew.k от Декабрь 20, 2010, 21:43 Гаусс тоже медленный на самом деле. Чтобы заблюрить до нормального уровня, нужно много времени.
Сделал через т.н. быстрый блюр. Центральный пиксел игнорируется, берется среднее значение 8 пикселов вокруг центрального. Работает очень быстро. 10 проходов изображение 1280х1024 (4Метра РГБА) фильтруется за 0.5 сек. Название: Re: QPixmap blur effect Отправлено: Igors от Декабрь 21, 2010, 10:36 Гаусс тоже медленный на самом деле. Чтобы заблюрить до нормального уровня, нужно много времени. Проход 1: создаете новый имедж (по размерам такой же). Каждый пиксель нового имеджа вычисляется как среднее по строке старого имеджа. (напр сумма 4 слева и 4 справа, итого 9). Новый имедж будет заблюрен "по строкам"Проход 2: используя имедж первого прохода повторяете все то же по столбцам (напр 4 сверху и 4 снизу) Итого каждый пиксель потребовал 9 + 9 = 18 сложений. Если же Вы просто "осредняете всех соседей", то надо 9 * 9 = 81 сложений Название: Re: QPixmap blur effect Отправлено: andrew.k от Декабрь 21, 2010, 10:58 Гаусс тоже медленный на самом деле. Чтобы заблюрить до нормального уровня, нужно много времени. Проход 1: создаете новый имедж (по размерам такой же). Каждый пиксель нового имеджа вычисляется как среднее по строке старого имеджа. (напр сумма 4 слева и 4 справа, итого 9). Новый имедж будет заблюрен "по строкам"Проход 2: используя имедж первого прохода повторяете все то же по столбцам (напр 4 сверху и 4 снизу) Итого каждый пиксель потребовал 9 + 9 = 18 сложений. Если же Вы просто "осредняете всех соседей", то надо 9 * 9 = 81 сложений интересно откуда у пиксела 81 сосед? у тебя 5D монитор или 6D? На моем двумерном мониторе у каждого пиксела (если не считать крайних) по 8 соседей. Соответственно пиксел нового изображения формируется сложением из этих 8 соседей и вместо деления на 8, можно использовать сдвиг вправо <<3, для скорости. Откуда 81? Загадка. Название: Re: QPixmap blur effect Отправлено: Igors от Декабрь 21, 2010, 12:00 Какая-то невероятно хитрая математика. 8 = "число ближайших" соседей, + сам пиксель, итого 9. То есть Вы осредняете матрицу 3х3. Чтобы заблюрить больше, надо взять матрицу больше, напр 9x9. Но складывать не все 81 точки а 18 как писалось вышеинтересно откуда у пиксела 81 сосед? у тебя 5D монитор или 6D? На моем двумерном мониторе у каждого пиксела (если не считать крайних) по 8 соседей. Соответственно пиксел нового изображения формируется сложением из этих 8 соседей и вместо деления на 8, можно использовать сдвиг вправо <<3, для скорости. Откуда 81? Загадка. Название: Re: QPixmap blur effect Отправлено: Kolobok от Декабрь 21, 2010, 12:02 Откуда 81? Загадка. Igors взял по 4 пикселя с каждой стороны. Это квадрат 9х9. Правда сложений будет 80 ( это я так, занудствую ). В твоем случае квадрат 3х3 = 9 пикселей - 8 сложений * 10 проходов = те же 80 сложений. Название: Re: QPixmap blur effect Отправлено: andrew.k от Декабрь 21, 2010, 18:45 Тогда я вообще не понял о чем был его пост.
И так понятно, что если взять меньше точек, то будет быстрее работать, чем если взять больше точек :) Название: Re: QPixmap blur effect Отправлено: Igors от Декабрь 22, 2010, 11:39 Igors взял по 4 пикселя с каждой стороны. Это квадрат 9х9. Правда сложений будет 80 Да НЕТ же, всего 18, (9 в первом проходе и 9 во втором). Сначала (первый проход) блюрите каждый пиксель только по (одной) строке, потом, используя результат первого прохода, только по (одному) столбцу. Устал я объяснять :) Название: Re: QPixmap blur effect Отправлено: andrew.k от Декабрь 22, 2010, 12:17 Главное, чтобы ты понимал, что ты с чем складываешь.
В алгоритме блюра по Гауссу, делается точно так же. Сначала по строкам, потом по столбцам. Конечно матрицу никто не общитывает. Он не из-за этого медленный, а из-за коэффициентов на которые приходится умножать соседние пикселы. Название: Re: QPixmap blur effect Отправлено: Igors от Декабрь 22, 2010, 12:50 В алгоритме блюра по Гауссу, делается точно так же. Сначала по строкам, потом по столбцам. Конечно матрицу никто не общитывает. Если не обсчитывает, то чего Вы складываете 8 соседей (хотя можете сложить 2 + 2)? И чего вы берете 3х3 и делаете 10 проходов если можно просто взять матрицу больше? Гаусс здесь значит просто "колокольчик" (ближние пиксели берутся с большим весом, дальние с меньшим). А сама техника блюра (по строкам, потом по столбцам) используется с любым типом фильтра, напр. "box" (просто осреднение).Он не из-за этого медленный, а из-за коэффициентов на которые приходится умножать соседние пикселы. Так может Вы их просто не предвычислили? Или натыкали классов в цикле по пикселю? Если хотите давайте посмотрим код - явно что-то не так, PShop блюрит в real-time даже на скромной машине Название: Re: QPixmap blur effect Отправлено: andrew.k от Декабрь 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 проходов выполняются меньше половины секунды. В принципе скорость приемлемая так и оставил. Или ты можешь еще ускорить? :) Название: Re: QPixmap blur effect Отправлено: andrew.k от Декабрь 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 ); } Название: Re: QPixmap blur effect Отправлено: Kolobok от Декабрь 22, 2010, 13:58 Igors взял по 4 пикселя с каждой стороны. Это квадрат 9х9. Правда сложений будет 80 Да НЕТ же, всего 18, (9 в первом проходе и 9 во втором). Сначала (первый проход) блюрите каждый пиксель только по (одной) строке, потом, используя результат первого прохода, только по (одному) столбцу. Устал я объяснять :) Всё я понял правильно. 80 будет если всю матрицу 9х9 обсчитывать. А если строки/столбцы то 16. Сложений на одно меньше, чем слагаемых. Это я имел ввиду. :) Название: Re: QPixmap blur effect Отправлено: Igors от Декабрь 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" Название: Re: QPixmap blur effect Отправлено: andrew.k от Декабрь 22, 2010, 17:58 Во-первых, я ни разу не хамил.
Во-вторых, я нигде не сказал, что гаусс дает качество хуже. Я сказал, что Гаусс работает медленнее, чем Quick Blur. Читать надо внимательно. Мне требуется размыть до состояния, чтобы текст не читался, а качество не важно. Соответственно, я сравниваю результат и время его достижения разными методами. Так один проход гаусса с сигма=3 работает дольше, чем 10 проходов быстрого блюра, а получаемый результат примерно сопоставим (качество не в счет). В-третьих, твоя таблица не позволяет сделать полезных выводов. Зачем ты потратил на это время? Что такое Гаусс 19х19??? У Гаусса есть параметр сигма, который влияет на степень размытия и соответственно время выполнения. В самом начале темы, я написал, что я в этом не разбираюсь, но по ходу развития темы искал материал, разбирался. Поэтому что ты подразумеваешь под SimpleBlur, я могу только догадываться и чем он отличается от box blur. Ты сказал, давай сюда код, у тебя классов понатыкано, я мол лучше могу сделать. Я тебе дал. В результате, какая-то бесполезная таблица. Тебя не учили в универе, что нужно после лабораторной работы писать обоснованный вывод? И подпись под таблицей гласящая: "да ты там вообще у себя поковыряй лучше и вообще мудак ты". <- Это хамство вместе с таблицей без объяснений. |