All Downloads are FREE. Search and download functionalities are using the official Maven repository.

CopyMove.ImageMap Maven / Gradle / Ivy

The newest version!
package CopyMove;

import Utils.Util;

import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * Wrapper/Helper for Masked RGB BufferedImage 
 * 
 * @author Xavier Philippeau
 *
 */
public class ImageMap {

	// image data
	private BufferedImage image;
	public final int W,H;

	// the maximum value returned by MaskedImage.distance()
	public static final int DSCALE = 65535;

	// array for converting distance to similarity
	public static final double[] similarity;

	static {
		// build similarity curve such that similarity[0%]=0.999 and similarity[4%]=0.5
		double s_zero=0.999;
		double t_halfmax=0.10;

		double x = (s_zero-0.5)*2;
		double invtanh = 0.5*Math.log((1+x)/(1-x));
		double coef = invtanh/t_halfmax;

		similarity = new double[DSCALE+1];
		for(int i=0;i=source.W) {distance+=ssdmax; continue;}
				if (yks<0 || yks>=source.H) {distance+=ssdmax; continue;}
				// corresponding pixel in the target patch
				int xkt=xt+dx, ykt=yt+dy;
				if (xkt<0 || xkt>=target.W) {distance+=ssdmax; continue;}
				if (ykt<0 || ykt>=target.H) {distance+=ssdmax; continue;}
				// SSD distance between pixels (each value is in [0,255^2])
				long ssd=0;
				// value distance (weight for R/G/B components = 3/6/1)
				for(int band=0;band<3;band++) {
					int weight = (band==0)?3:(band==1)?6:1;
					double diff2 = (source.getSample(xks, yks, band) - target.getSample(xkt, ykt, band))*(source.getSample(xks, yks, band) - target.getSample(xkt, ykt, band)); // Value
					ssd += weight*diff2;
				}
				// add pixel distance to global patch distance
				distance += ssd;
			}
		}
		return (int)(DSCALE*distance/wsum);
	}

    public static int distance2(ImageMap source,int xs,int ys, ImageMap target,int xt,int yt, int S) {
        long distance=0, wsum=0;
        double ssdmax = 1.9;
        // for each pixel in the source patch
        for(int dy=-S;dy<=S;dy++) {
            for(int dx=-S;dx<=S;dx++) {
                wsum+=ssdmax;
                int xks=xs+dx, yks=ys+dy;
                if (xks<0 || xks>=source.W) {distance+=ssdmax; continue;}
                if (yks<0 || yks>=source.H) {distance+=ssdmax; continue;}
                // corresponding pixel in the target patch
                int xkt=xt+dx, ykt=yt+dy;
                if (xkt<0 || xkt>=target.W) {distance+=ssdmax; continue;}
                if (ykt<0 || ykt>=target.H) {distance+=ssdmax; continue;}
                // SSD distance between pixels (each value is in [0,255^2])
                long ssd=0;
                double s_RGB=source.getSample(xks, yks, 0)+source.getSample(xks, yks, 1)+source.getSample(xks, yks, 2);
                double s_r=source.getSample(xks, yks, 0)/s_RGB;
                double s_g=source.getSample(xks, yks, 1)/s_RGB;
                double s_b=source.getSample(xks, yks, 2)/s_RGB;
                double t_RGB=source.getSample(xks, yks, 0)+source.getSample(xks, yks, 1)+source.getSample(xks, yks, 2);
                double t_r=source.getSample(xks, yks, 0)/t_RGB;
                double t_g=source.getSample(xks, yks, 1)/t_RGB;
                double t_b=source.getSample(xks, yks, 2)/t_RGB;
                double diff2 = (s_r - t_r)*(s_r - t_r) + (s_g - t_g)*(s_g - t_g) + (s_b - t_b)*(s_b - t_b); // Value
                ssd += diff2;
                // add pixel distance to global patch distance
                distance += ssd;
            }
        }
        return (int)(DSCALE*distance/wsum);
    }

	// Helper for BufferedImage resize
	public static BufferedImage resize(BufferedImage input, int newwidth, int newheight) {
		BufferedImage out = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = out.createGraphics();
		java.awt.Image scaled = input.getScaledInstance(newwidth, newheight, java.awt.Image.SCALE_SMOOTH);
		g.drawImage(scaled, 0, 0, out.getWidth(), out.getHeight(), null);
		g.dispose();
		return out;
	}

	// return a copy of the image
	public ImageMap copy() {
		boolean[][] newmask= new boolean[W][H];
		BufferedImage newimage = new BufferedImage(W,H, BufferedImage.TYPE_INT_RGB);
		newimage.createGraphics().drawImage(image, 0, 0, null);
		return new ImageMap(newimage);
	}
	
	// return a downsampled image (factor 1/2)
	public ImageMap downsample() {
		int newW=W/2, newH=H/2;
		// Binomial coefficient kernels
		int[] kernelEven = new int[] {1,5,10,10,5,1}; 
		int[] kernelOdd = new int[] {1,4,6,4,1};
		int[] kernelx = (W%2==0)?kernelEven:kernelOdd;
		int[] kernely = (H%2==0)?kernelEven:kernelOdd;

		ImageMap newimage = new ImageMap(newW, newH);
		for(int y=0,ny=0;y=H) continue;
					for(int dx=0;dx=W) continue;
						
						total++;
						int k = kernelx[dx]*kernely[dy];
						r+= k*this.getSample(xk, yk, 0);
						g+= k*this.getSample(xk, yk, 1);
						b+= k*this.getSample(xk, yk, 2);
						ksum+=k;
					}
				}
				if (ksum>0) {
					newimage.setSample(nx, ny, 0, (int)((double)r/ksum+0.5));
					newimage.setSample(nx, ny, 1, (int)((double)g/ksum+0.5));
					newimage.setSample(nx, ny, 2, (int)((double)b/ksum+0.5));
				}
			}
		}
		return newimage;
	}

	// return an upscaled image
	public ImageMap upscale(int newW,int newH) {
		ImageMap newimage = new ImageMap(newW, newH);
		newimage.image = resize(this.image, newW, newH);
		return newimage;
	}

    //return a local variance map
    public double[][] LocalVariance(int blockSize){
        double[][] GrayscaleIm = new double[W][H];
        double[][] OutputVariance = new double[W][H];

        int R,G,B;
        for (int ii = 0; ii < W; ii++) {
            for (int jj = 0; jj < H; jj++) {
                R = this.getSample(ii, jj, 0);
                G = this.getSample(ii, jj, 1);
                B = this.getSample(ii, jj, 2);
                GrayscaleIm[ii][jj] = 0.2989 * R + 0.5870 * G + 0.1140 * B;
            }
        }

        double[][] BlockVar=Util.BlockVar(GrayscaleIm, blockSize);
		//System.out.println();
		//System.out.println(W+ " " + H + " " + BlockNoiseVar.length + " " + BlockNoiseVar[0].length);

        for (int ii=0; ii<(int)Math.floor(((float)W)/blockSize)*blockSize;ii++){
            for (int jj=0; jj<(int)Math.floor(((float)H)/blockSize)*blockSize;jj++){
                OutputVariance[ii][jj] = BlockVar[(int)Math.floor(((float)ii)/blockSize)][(int)Math.floor(((float)jj)/blockSize)];
            }
        }
        return OutputVariance;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy