I implemented a new blur algorithm. Works better, but there's something in the second pass that introduces more dots.

git-svn-id: https://svn.code.sf.net/p/q3cellshading/code/trunk@26 db09e94b-7117-0410-a7e6-85ae5ff6e0e9
This commit is contained in:
gmiranda 2006-07-28 12:46:49 +00:00
parent 76b1e0f621
commit 4d69b79ca7
1 changed files with 100 additions and 101 deletions

View File

@ -839,110 +839,109 @@ for(row=rows-1; row>=arow+3; row--)
#define DIVNUM 15 #define DIVNUM 15
/**
* 2 passes blur filter
* @see http://www.filtermeister.com/tutorials/blur02.html
*/
void blur(int columns, int rows, byte *targa_rgba) void blur(int columns, int rows, byte *targa_rgba)
{ {
int row, column;
float red,green,blue; // 4x4 kernel
float ared,agreen,ablue; int kernelwidth = 4, kernelheight = 4,
x, y, z, xlook, ylook,
ared=agreen=ablue=128; sum, amount,
// number of channels (R,G,B, skip alpha)
//for(row=rows-1; row>=0; row--) channels = 3;
for(row=0; row<rows; row++)
{ // Temporary image
//pixbuf = targa_rgba + row*columns*4; byte* t;
for(column=0; column<columns; column++)
{ // Allocate
red=0; t = (byte*)malloc(sizeof(byte)*rows*columns*4);
red+=getImageR(targa_rgba,column-1,row-1,columns,rows);
red+=getImageR(targa_rgba,column,row-1,columns,rows); // First pass
red+=getImageR(targa_rgba,column+1,row-1,columns,rows); for (y=0; y < rows; y++){
red+=getImageR(targa_rgba,column-1,row,columns,rows); for (x=0; x < columns; x++){
red+=getImageR(targa_rgba,column,row,columns,rows); for (z= 0; z < channels; z++) {
red+=getImageR(targa_rgba,column+1,row,columns,rows); sum=0; amount=0;
red+=getImageR(targa_rgba,column-1,row+1,columns,rows); for (xlook=0; xlook<kernelwidth; xlook++)
red+=getImageR(targa_rgba,column,row+1,columns,rows);
red+=getImageR(targa_rgba,column+1,row+1,columns,rows);
red/=9;
red*=2;
red+=ared;
red/=3;
red=(int)red/DIVNUM;
red*=DIVNUM;
red+=(DIVNUM/2);
ared=red;
setImageR(targa_rgba, column, row, columns, rows, (byte)red);
////////////////////
green=0;
green+=getImageG(targa_rgba,column-1,row-1,columns,rows);
green+=getImageG(targa_rgba,column,row-1,columns,rows);
green+=getImageG(targa_rgba,column+1,row-1,columns,rows);
green+=getImageG(targa_rgba,column-1,row,columns,rows);
green+=getImageG(targa_rgba,column,row,columns,rows);
green+=getImageG(targa_rgba,column+1,row,columns,rows);
green+=getImageG(targa_rgba,column-1,row+1,columns,rows);
green+=getImageG(targa_rgba,column,row+1,columns,rows);
green+=getImageG(targa_rgba,column+1,row+1,columns,rows);
green/=9;
green*=2;
green+=agreen;
green/=3;
green=(int)green/DIVNUM;
green*=DIVNUM;
green+=(DIVNUM/2);
agreen=green;
setImageG(targa_rgba, column, row, columns, rows, (byte)green);
////////////////////////
blue=0;
blue+=getImageB(targa_rgba,column-1,row-1,columns,rows);
blue+=getImageB(targa_rgba,column,row-1,columns,rows);
blue+=getImageB(targa_rgba,column+1,row-1,columns,rows);
blue+=getImageB(targa_rgba,column-1,row,columns,rows);
blue+=getImageB(targa_rgba,column,row,columns,rows);
blue+=getImageB(targa_rgba,column+1,row,columns,rows);
blue+=getImageB(targa_rgba,column-1,row+1,columns,rows);
blue+=getImageB(targa_rgba,column,row+1,columns,rows);
blue+=getImageB(targa_rgba,column+1,row+1,columns,rows);
blue/=9;
blue*=2;
blue+=ablue;
blue/=3;
blue=(int)blue/DIVNUM;
blue*=DIVNUM;
blue+=(DIVNUM/2);
ablue=blue;
setImageB(targa_rgba, column, row, columns, rows, (byte)blue);
// "halftoning"
/*if((row%5==0)&&(column%5==1))
{ {
gris=0; switch(z){
gris+=red; case 0:
gris+=green; sum += getImageR(targa_rgba, (x+xlook-kernelwidth/2), y, columns, rows);
gris+=blue; break;
gris/=3; case 1:
sum += getImageG(targa_rgba, (x+xlook-kernelwidth/2), y, columns, rows);
gris=255-gris; break;
if(gris<0) case 2:
gris=0; sum += getImageB(targa_rgba, (x+xlook-kernelwidth/2), y, columns, rows);
break;
setImageR(targa_rgba, column, row, columns, rows, (byte)gris); }
setImageG(targa_rgba, column, row, columns, rows, (byte)gris); //sum+= src((x+xlook-kernelwidth/2),y,z);
setImageB(targa_rgba, column, row, columns, rows, (byte)gris); amount++;
}; //accumulate pixels in a raw
}*/ switch(z){
// R
case 0:
setImageR(t,x,y,columns,rows,(byte)(sum/amount));
break;
// G
case 1:
setImageG(t,x,y,columns,rows,(byte)(sum/amount));
break;
// B
case 2:
setImageB(t,x,y,columns,rows,(byte)(sum/amount));
break;
}
} }
} }
}
// Second pass
for (y=0; y < rows; y++) {
for (x=0; x < columns; x++) {
for (z= 0; z < channels; z++) {
sum=0; amount=0;
for (ylook=0; ylook<kernelheight; ylook++)
{
switch(z){
case 0:
sum+= getImageR(t,x,(y+ylook-kernelheight/2),columns,rows);
break;
case 1:
sum+= getImageG(t,x,(y+ylook-kernelheight/2),columns,rows);
break;
case 2:
sum+= getImageB(t,x,(y+ylook-kernelheight/2),columns,rows);
break;
}
amount++;
}; //accumulate pixels in a column
switch(z){
// R
case 0:
setImageR(targa_rgba,x,y,columns,rows,(byte)(sum/amount)); //divide the sum onto kernel size
break;
// G
case 1:
setImageG(targa_rgba,x,y,columns,rows,(byte)(sum/amount)); //divide the sum onto kernel size
break;
// B
case 2:
setImageB(targa_rgba,x,y,columns,rows,(byte)(sum/amount)); //divide the sum onto kernel size
break;
}
}
}
}
free(t);
} }
@ -1024,7 +1023,7 @@ void kuwahara(int columns, int rows, byte *targa_rgba)
float var, min; float var, min;
float** mean, **variance; float** mean, **variance;
//blur(columns, rows, targa_rgba); blur(columns, rows, targa_rgba);
// I hate malloc I hate malloc I hate malloc I hate malloc I hate malloc I hate malloc // I hate malloc I hate malloc I hate malloc I hate malloc I hate malloc I hate malloc
mean = (float**)malloc(sizeof(float*)*width2); mean = (float**)malloc(sizeof(float*)*width2);
@ -1126,7 +1125,7 @@ void kuwahara(int columns, int rows, byte *targa_rgba)
free(variance[index2]); free(variance[index2]);
free(variance); free(variance);
blur(columns, rows, targa_rgba); //blur(columns, rows, targa_rgba);
} }
//RED //RED