Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Фильтр Гаусса


Автор: TupleCa 9.4.2007, 14:02
изображение хранится в виде массива w*h*3. 
3 т.к хранится красный, зеленый, голубой. все значения принадлежат [0;255]. 

потом формируется новое изображение: 

Код: 
Код


        double o = 5; 
        int n=3,m=3; 
        double d=0; 
        for(int x=n;x<w-n;x++){ 
            for(int y=m;y<h-m;y++){ 
                int SumR=0; 
                int SumG=0; 
                int SumB=0; 
                for(int l=-n;l<=n;l++){ 
                    double sumr=0; 
                    double sumg=0; 
                    double sumb=0; 
                    for(int k=-m;k<=m;k++){ 
                        d=java.lang.Math.sqrt((double)(l*l+k*k)); 
                        sumr+=OR[x-l][y-k]*(1/(java.lang.Math.sqrt(6.28)*o))*java.lang.Math.pow(2.71,-(d*d)/(2*o*o)); 
                        sumg+=OG[x-l][y-k]*(1/(java.lang.Math.sqrt(6.28)*o))*java.lang.Math.pow(2.71,-(d*d)/(2*o*o)); 
                        sumb+=OB[x-l][y-k]*(1/(java.lang.Math.sqrt(6.28)*o))*java.lang.Math.pow(2.71,-(d*d)/(2*o*o)); 
                    } 
                    SumR+=(int)sumr; 
                    SumG+=(int)sumg; 
                    SumB+=(int)sumb; 
                } 
                NR[x][y] = SumR; 
                NG[x][y] = SumG; 
                NB[x][y] = SumB; 
            } 
        } 
 

в OR OG OB хранится исходник в NR(G,B) новое "изображение" 

и вот когда o меняю (o - это сигма), или n и m меняю или просто картинку. то часто SumR, SumG или SumB превышают 255. причем очень прилично превышают (по 350 есть и даже по 400). соответсвенно вывести на экран изображение не получается. 

Это так и должно быть, что иногда получается иногда нет. (в зависимости от o n m и картинки). Или это я ошибся где-то?

Автор: maxim1000 9.4.2007, 15:17
для двумерного фильтра Гаусса нужно два раза умножать на нормализирующий множитель (по сути, просто в квадрат его возвести), тогда, по идее, за пределы выходить не должно

Автор: TupleCa 9.4.2007, 15:34
Цитата(maxim1000 @  9.4.2007,  15:17 Найти цитируемый пост)
для двумерного фильтра Гаусса нужно два раза умножать на нормализирующий множитель (по сути, просто в квадрат его возвести), тогда, по идее, за пределы выходить не должно 


хм. вообще, теперь, не выходит за пределы. но изображение СИЛЬНО темнеет.

Автор: esperant0 9.4.2007, 16:27
Не могли бы вы формулу дать.

Известный мне фильт гауса не меняет светность картинки, и не дает значения пикселей большие чем было.

Автор: TupleCa 9.4.2007, 16:54
Цитата(esperant0 @  9.4.2007,  16:27 Найти цитируемый пост)
Известный мне фильт гауса не меняет светность картинки, и не дает значения пикселей большие чем было. 

формулу известного фильтра? или "неизвестного" ))) т.е как я делаю???

Автор: esperant0 9.4.2007, 17:14
Цитата(TupleCa @ 9.4.2007,  16:54)
Цитата(esperant0 @  9.4.2007,  16:27 Найти цитируемый пост)
Известный мне фильт гауса не меняет светность картинки, и не дает значения пикселей большие чем было. 

формулу известного фильтра? или "неизвестного" ))) т.е как я делаю???

Формулу вашего фильтра или алгоритм.

Автор: TupleCa 9.4.2007, 17:26
Цитата(esperant0 @  9.4.2007,  17:14 Найти цитируемый пост)
Формулу вашего фильтра или алгоритм.


я код привел же.
ну щас поподроюнее напишу
Код

        double o = 5; //сигма
        double g=0;
        double t=0;
        int n=3,m=3;
        double d=0;
       
        //два внешних цикла. тут обоходится каждая точка изображения (кроме крайних)
        for(int x=n;x<w-n;x++){
            for(int y=m;y<h-m;y++){
                double SumR=0;
                double SumG=0;
                double SumB=0;
                //тут обходится область точки
                for(int l=-n;l<=n;l++){
                    for(int k=-m;k<=m;k++){
                        d=java.lang.Math.sqrt((double)(l*l+k*k));
                        g=java.lang.Math.pow(2.71,-(d*d)/(2*o*o));
                        t=(1/(java.lang.Math.sqrt(6.28)*o));
                        
                        SumR+=OR[x-l][y-k]*t*t*g*g;
                        SumG+=OG[x-l][y-k]*t*t*g*g;
                        SumB+=OB[x-l][y-k]*t*t*g*g;
                    }
                }
                NR[x][y] = (int)SumR;
                NG[x][y] = (int)SumG;
                NB[x][y] = (int)SumB;
            }
        }
        
    }


вообщем формула такая:
(если таким языком понятно будет)))
I'(i,j) = СУММА( l=[-n;n])СУММА(k=[-m;m]) I(i-l)(i-k)*{[1/(корень(2*пи)*сигма)]*e^((-d*d)/(2*сигма*сигма))}^2

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)