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
|
#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;
|
|
||||||
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--)
|
// Temporary image
|
||||||
for(row=0; row<rows; row++)
|
byte* t;
|
||||||
{
|
|
||||||
//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;
|
// Allocate
|
||||||
red*=2;
|
t = (byte*)malloc(sizeof(byte)*rows*columns*4);
|
||||||
red+=ared;
|
|
||||||
red/=3;
|
|
||||||
|
|
||||||
red=(int)red/DIVNUM;
|
// First pass
|
||||||
red*=DIVNUM;
|
for (y=0; y < rows; y++){
|
||||||
red+=(DIVNUM/2);
|
for (x=0; x < columns; x++){
|
||||||
ared=red;
|
for (z= 0; z < channels; z++) {
|
||||||
|
sum=0; amount=0;
|
||||||
setImageR(targa_rgba, column, row, columns, rows, (byte)red);
|
for (xlook=0; xlook<kernelwidth; xlook++)
|
||||||
////////////////////
|
|
||||||
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);
|
||||||
|
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;
|
||||||
|
|
||||||
gris=255-gris;
|
}
|
||||||
if(gris<0)
|
}
|
||||||
gris=0;
|
}
|
||||||
|
}
|
||||||
setImageR(targa_rgba, column, row, columns, rows, (byte)gris);
|
// Second pass
|
||||||
setImageG(targa_rgba, column, row, columns, rows, (byte)gris);
|
for (y=0; y < rows; y++) {
|
||||||
setImageB(targa_rgba, column, row, columns, rows, (byte)gris);
|
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
|
||||||
|
|
Loading…
Reference in New Issue