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,111 +839,110 @@ for(row=rows-1; row>=arow+3; row--)
#define DIVNUM 15
/**
* 2 passes blur filter
* @see http://www.filtermeister.com/tutorials/blur02.html
*/
void blur(int columns, int rows, byte *targa_rgba)
{
int row, column;
float red,green,blue;
float ared,agreen,ablue;
ared=agreen=ablue=128;
// 4x4 kernel
int kernelwidth = 4, kernelheight = 4,
x, y, z, xlook, ylook,
sum, amount,
// number of channels (R,G,B, skip alpha)
channels = 3;
//for(row=rows-1; row>=0; row--)
for(row=0; row<rows; row++)
// Temporary image
byte* t;
// Allocate
t = (byte*)malloc(sizeof(byte)*rows*columns*4);
// First pass
for (y=0; y < rows; y++){
for (x=0; x < columns; x++){
for (z= 0; z < channels; z++) {
sum=0; amount=0;
for (xlook=0; xlook<kernelwidth; xlook++)
{
//pixbuf = targa_rgba + row*columns*4;
for(column=0; column<columns; column++)
{
red=0;
red+=getImageR(targa_rgba,column-1,row-1,columns,rows);
red+=getImageR(targa_rgba,column,row-1,columns,rows);
red+=getImageR(targa_rgba,column+1,row-1,columns,rows);
red+=getImageR(targa_rgba,column-1,row,columns,rows);
red+=getImageR(targa_rgba,column,row,columns,rows);
red+=getImageR(targa_rgba,column+1,row,columns,rows);
red+=getImageR(targa_rgba,column-1,row+1,columns,rows);
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;
gris+=red;
gris+=green;
gris+=blue;
gris/=3;
gris=255-gris;
if(gris<0)
gris=0;
setImageR(targa_rgba, column, row, columns, rows, (byte)gris);
setImageG(targa_rgba, column, row, columns, rows, (byte)gris);
setImageB(targa_rgba, column, row, columns, rows, (byte)gris);
}*/
switch(z){
case 0:
sum += getImageR(targa_rgba, (x+xlook-kernelwidth/2), y, columns, rows);
break;
case 1:
sum += getImageG(targa_rgba, (x+xlook-kernelwidth/2), y, columns, rows);
break;
case 2:
sum += getImageB(targa_rgba, (x+xlook-kernelwidth/2), y, columns, rows);
break;
}
//sum+= src((x+xlook-kernelwidth/2),y,z);
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** 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
mean = (float**)malloc(sizeof(float*)*width2);
@ -1126,7 +1125,7 @@ void kuwahara(int columns, int rows, byte *targa_rgba)
free(variance[index2]);
free(variance);
blur(columns, rows, targa_rgba);
//blur(columns, rows, targa_rgba);
}
//RED