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:
parent
76b1e0f621
commit
4d69b79ca7
|
@ -839,110 +839,109 @@ 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;
|
||||
|
||||
//for(row=rows-1; row>=0; row--)
|
||||
for(row=0; row<rows; row++)
|
||||
{
|
||||
//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))
|
||||
|
||||
// 4x4 kernel
|
||||
int kernelwidth = 4, kernelheight = 4,
|
||||
x, y, z, xlook, ylook,
|
||||
sum, amount,
|
||||
// number of channels (R,G,B, skip alpha)
|
||||
channels = 3;
|
||||
|
||||
// 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++)
|
||||
{
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue