// mean deviation calculation
// Press et al., Numerical Recipes, The Art of Scientific Computing, 472-4
// argument
//     region size: the nonlinear filter calculates the mean deviation of the pixel gray levels
//                  within small regions (default:4*4)
package yi.iu.processor.contour;

import java.awt.*;
import yi.iu.processor.*;
import yi.iu.processor.channel.*;
import yi.iu.processor.channel.IntensityMaker;

public class MeanDeviationMaker extends yi.iu.processor.ImageProcessor
{
    int regionSize= 4;
    
    public MeanDeviationMaker() {};
    public MeanDeviationMaker(int rs) {regionSize=4;}
    
    public int[] getProcessedPseudoColor(int source[], Dimension d)
    {
        int[] result=new int[source.length];
        int[] res= getProcessed(source,d);
        int width=d.width, height=d.height;
        for (int i=0;i<width*height;i++){
            int t=res[i];
            if (t>255) t=255;
            result[i]=255<<24|t<<16|t<<8|t;
        }
        return res;
    }

    public int[] getProcessed(int source[], Dimension d)
    {
        int width=d.width, height=d.height;
        int rw=width/regionSize, rh=height/regionSize;      // num of regions :width, height
        int iw=rw*regionSize, ih=rh*regionSize;             // num of real considered pixels
        int[] avg= new int[rw*rh];
        int[] dev= new int[rw*rh];
        
        IntensityMaker im= new IntensityMaker();
        int[] in= im.getProcessed(source, d);
        
        for (int i=0;i<ih;i++)
            for (int j=0;j<iw;j++)
                avg[(i/regionSize)*rw+(j/regionSize)]+= in[i*width+j];
        
        for (int i=0;i<rh;i++)
            for (int j=0;j<rw;j++) {
                avg[i*rw+j]=(int)((double)avg[i*rw+j]/(regionSize*regionSize)+0.5);
            }
        
        for (int i=0;i<ih;i++)
            for (int j=0;j<iw;j++) {
                int temp= avg[(i/regionSize)*rw+(j/regionSize)]-in[i*width+j];
                if (temp<0) temp= -temp;
                dev[(i/regionSize)*rw+(j/regionSize)]+= temp;
            }
                
        for (int i=0;i<rh;i++)
            for (int j=0;j<rw;j++) {
                if (avg[i*rw+j]==0) dev[i*rw+j]=0;
                else
                    dev[i*rw+j]=(int)((double)128*dev[i*rw+j]/avg[i*rw+j]+0.5);
            }
                
        d.width=rw; d.height=rh;
        return dev;
    }

}