Fixed some bugs and framework for the image filters

This commit is contained in:
Ziver Koc 2009-04-16 20:51:15 +00:00
parent 9f839fd803
commit 1bde5a6977
13 changed files with 342 additions and 266 deletions

View file

@ -65,7 +65,7 @@ public abstract class ImageFilterProcessor {
// converts the img to raw data
int[][][] data = convertToArray(img, cols, rows);
//processes the image
data = process(data, cols, rows);
process(data);
//converts back the image
return convertToImage(data, data[0].length, data.length);
}
@ -147,11 +147,21 @@ public abstract class ImageFilterProcessor {
return img;
}
/**
* Runs the image thrue the processor
* @param data The raw image to apply the effect to
*/
public void process(final int[][][] data){
process(data, 0, 0, data[0].length, data.length);
}
/**
* The underlying effect is run here
* @param data The raw image to apply the effect to
* @param cols Columns of the image
* @param rows Rows of the image
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
*/
public abstract int[][][] process(final int[][][] data, int cols, int rows);
public abstract void process(final int[][][] data, int startX, int startY, int stopX, int stopY);
}

View file

@ -6,18 +6,35 @@ package zutil.image;
*
*/
public class ImageUtil {
/**
* Returns the peek value in the image
*
* @param data The image data
* @param cols The number of columns
* @param rows The number of rows
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @return The peak value of the image
*/
public static int peakValue(int[][][] data, int cols, int rows) {
public static int peakValue(int[][][] data) {
return peakValue(data, 0, 0, data[0].length, data.length);
}
/**
* Returns the peek value in the image
*
* @param data The image data
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @return The peak value of the image
*/
public static int peakValue(int[][][] data, int startX, int startY, int stopX, int stopY) {
int peak = 0;
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
if(data[y][x][1] > peak) peak = data[y][x][1];
if(data[y][x][2] > peak) peak = data[y][x][2];
if(data[y][x][3] > peak) peak = data[y][x][3];
@ -30,13 +47,15 @@ public class ImageUtil {
* Normalizes the image data by the given scale
*
* @param data The image data
* @param cols The number of columns
* @param rows The number of rows
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @param scale The scale to normalize the image by
*/
public static void normalize(int[][][] data, int cols, int rows, double scale) {
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
public static void normalize(int[][][] data, int startX, int startY, int stopX, int stopY, double scale) {
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
data[y][x][1] = (int)(data[y][x][1] * scale);
data[y][x][2] = (int)(data[y][x][2] * scale);
data[y][x][3] = (int)(data[y][x][3] * scale);
@ -49,13 +68,15 @@ public class ImageUtil {
*
* @param output The output data array
* @param data The image data
* @param cols The number of columns
* @param rows The number of rows
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @param scale The scale to normalize the image by
*/
public static void normalize(int[][][] output, int[][][] data, int cols, int rows, double scale) {
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
public static void normalize(int[][][] output, int[][][] data, int startX, int startY, int stopX, int stopY, double scale) {
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
output[y][x][1] = (int)(data[y][x][1] * scale);
output[y][x][2] = (int)(data[y][x][2] * scale);
output[y][x][3] = (int)(data[y][x][3] * scale);
@ -64,19 +85,21 @@ public class ImageUtil {
}
/**
* Returns the rms value of the image
* Returns the RMS value of the image
* (The RMS value is a measure of the width of the color distribution.)
*
* @param data The image data
* @param cols The number of columns
* @param rows The number of rows
* @return The rms value for the image
* @param data is the image data
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @return The RMS value for the image
*/
public static int rms(int[][][] data, int cols, int rows){
public static int rms(int[][][] data, int startX, int startY, int stopX, int stopY){
int pixelCount = 0;
long accum = 0;
for(int y=0; y <rows ;y++){
for(int x=0; x<cols ;x++){
for(int y=startY; y <stopY ;y++){
for(int x=startX; x<stopX ;x++){
accum += data[y][x][1] * data[y][x][1];
accum += data[y][x][2] * data[y][x][2];
accum += data[y][x][3] * data[y][x][3];
@ -92,13 +115,15 @@ public class ImageUtil {
* Multiplies the given image data by the given value
*
* @param data The image data
* @param cols The number of columns
* @param rows The number of rows
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @param scale The number to scale the image by
*/
public static void scale(int[][][] data, int cols, int rows, double scale){
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
public static void scale(int[][][] data, int startX, int startY, int stopX, int stopY, double scale){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
data[y][x][1] *= scale;
data[y][x][2] *= scale;
data[y][x][3] *= scale;
@ -110,15 +135,27 @@ public class ImageUtil {
* Returns the mean value of the given image data
*
* @param data The image data
* @param cols The column count
* @param rows The row count
* @return The mean value of the image
*/
public static int meanValue(int[][][] data,int cols, int rows){
public static int meanValue(int[][][] data){
return meanValue(data, 0, 0, data[0].length, data.length);
}
/**
* Returns the mean value of the given image data
*
* @param data The image data
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @return The mean value of the image
*/
public static int meanValue(int[][][] data, int startX, int startY, int stopX, int stopY){
int pixelCount = 0;
long accum = 0;
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
accum += data[y][x][1];
accum += data[y][x][2];
accum += data[y][x][3];
@ -133,13 +170,15 @@ public class ImageUtil {
* Adds the mean value to the image data
*
* @param data The image data
* @param cols The number of columns
* @param rows The number of rows
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @param mean The mean value
*/
public static void addMeanValue(int[][][] data,int cols, int rows, int mean){
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
public static void addMeanValue(int[][][] data, int startX, int startY, int stopX, int stopY, int mean){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
data[y][x][1] += mean;
data[y][x][2] += mean;
data[y][x][3] += mean;
@ -191,21 +230,48 @@ public class ImageUtil {
* Copies the given array to a new one that it returns
*
* @param data The data to duplicate
* @param cols The amount of columns
* @param rows The amount of rows
* @return an copy of the array
*/
public static int[][][] copyArray(int[][][] data){
return copyArray(data, 0, 0, data[0].length, data.length);
}
/**
* Copies the given array to a new one that it returns
*
* @param data The data to duplicate
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @return The array copy
*/
public static int[][][] copyArray(int[][][] data,int cols,int rows){
int[][][] copy = new int[rows][cols][4];
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
copy[y][x][0] = data[y][x][0];
copy[y][x][1] = data[y][x][1];
copy[y][x][2] = data[y][x][2];
copy[y][x][3] = data[y][x][3];
public static int[][][] copyArray(int[][][] data, int startX, int startY, int stopX, int stopY){
int[][][] copy = new int[data.length][data[0].length][4];
return copyArray(data, copy, startX, startY, stopX, stopY);
}
/**
* Copies the given array to a new one that it returns
*
* @param data The data to duplicate
* @param dest is the array to copy the data to
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @return the dest array
*/
public static int[][][] copyArray(int[][][] data, int[][][] dest, int startX, int startY, int stopX, int stopY){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
dest[y][x][0] = data[y][x][0];
dest[y][x][1] = data[y][x][1];
dest[y][x][2] = data[y][x][2];
dest[y][x][3] = data[y][x][3];
}
}
return copy;
return dest;
}
/**
@ -213,15 +279,17 @@ public class ImageUtil {
* are in the range 0-255
*
* @param data The image data
* @param cols The amount of columns
* @param rows The amount of rows
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
*/
public static void clip(int[][][] data, int cols, int rows){
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
public static void clip(int[][][] data, int startX, int startY, int stopX, int stopY){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
data[y][x][1] = clip(data[y][x][1]);
data[y][x][1] = clip(data[y][x][2]);
data[y][x][1] = clip(data[y][x][3]);
data[y][x][2] = clip(data[y][x][2]);
data[y][x][3] = clip(data[y][x][3]);
}
}
}

View file

@ -28,67 +28,64 @@ public class BlurFilter extends ImageFilterProcessor{
}
@Override
public int[][][] process(final int[][][] data, int cols, int rows) {
int inputPeak = ImageUtil.peakValue(data, cols, rows);
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
int inputPeak = ImageUtil.peakValue(data);
int[][][] output = new int[rows][cols][4];
int[][][] tmpData = ImageUtil.copyArray(data, cols, rows);
int[][][] tmpData = new int[data.length][data[0].length][4];
//Perform the convolution one or more times in succession
int redSum, greenSum, blueSum, outputPeak;
for(int i=0; i<blurValue ;i++){
//Iterate on each pixel as a registration point.
for(int y=0; y<rows ;y++){
setProgress(ZMath.percent(0, (blurValue-1)*(rows-2), i*(rows-2)+y));
for(int x=0; x<cols ;x++){
if(x == 0 || x == cols-1 || y == 0 || y == rows-1){
redSum = tmpData[y][x][1] * 9;
greenSum = tmpData[y][x][2] * 9;
blueSum = tmpData[y][x][3] * 9;
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, (blurValue-1)*(stopY-startY-2), i*(stopY-startY-2)+y));
for(int x=startX; x<stopX ;x++){
if(x == 0 || x == data[0].length-1 || y == 0 || y == data.length-1){
redSum = data[y][x][1] * 9;
greenSum = data[y][x][2] * 9;
blueSum = data[y][x][3] * 9;
}
else{
redSum =
tmpData[y - 1][x - 1][1] +
tmpData[y - 1][x - 0][1] +
tmpData[y - 1][x + 1][1] +
tmpData[y - 0][x - 1][1] +
tmpData[y - 0][x - 0][1] +
tmpData[y - 0][x + 1][1] +
tmpData[y + 1][x - 1][1] +
tmpData[y + 1][x - 0][1] +
tmpData[y + 1][x + 1][1];
data[y - 1][x - 1][1] +
data[y - 1][x - 0][1] +
data[y - 1][x + 1][1] +
data[y - 0][x - 1][1] +
data[y - 0][x - 0][1] +
data[y - 0][x + 1][1] +
data[y + 1][x - 1][1] +
data[y + 1][x - 0][1] +
data[y + 1][x + 1][1];
greenSum =
tmpData[y - 1][x - 1][2] +
tmpData[y - 1][x - 0][2] +
tmpData[y - 1][x + 1][2] +
tmpData[y - 0][x - 1][2] +
tmpData[y - 0][x - 0][2] +
tmpData[y - 0][x + 1][2] +
tmpData[y + 1][x - 1][2] +
tmpData[y + 1][x - 0][2] +
tmpData[y + 1][x + 1][2];
data[y - 1][x - 1][2] +
data[y - 1][x - 0][2] +
data[y - 1][x + 1][2] +
data[y - 0][x - 1][2] +
data[y - 0][x - 0][2] +
data[y - 0][x + 1][2] +
data[y + 1][x - 1][2] +
data[y + 1][x - 0][2] +
data[y + 1][x + 1][2];
blueSum =
tmpData[y - 1][x - 1][3] +
tmpData[y - 1][x - 0][3] +
tmpData[y - 1][x + 1][3] +
tmpData[y - 0][x - 1][3] +
tmpData[y - 0][x - 0][3] +
tmpData[y - 0][x + 1][3] +
tmpData[y + 1][x - 1][3] +
tmpData[y + 1][x - 0][3] +
tmpData[y + 1][x + 1][3];
data[y - 1][x - 1][3] +
data[y - 1][x - 0][3] +
data[y - 1][x + 1][3] +
data[y - 0][x - 1][3] +
data[y - 0][x - 0][3] +
data[y - 0][x + 1][3] +
data[y + 1][x - 1][3] +
data[y + 1][x - 0][3] +
data[y + 1][x + 1][3];
}
output[y][x][0] = tmpData[y][x][0];
output[y][x][1] = redSum;
output[y][x][2] = greenSum;
output[y][x][3] = blueSum;
tmpData[y][x][0] = data[y][x][0];
tmpData[y][x][1] = redSum;
tmpData[y][x][2] = greenSum;
tmpData[y][x][3] = blueSum;
}
}
// getting the new peak value and normalizing the image
outputPeak = ImageUtil.peakValue(output, cols, rows);
ImageUtil.normalize(tmpData, output, cols, rows, ((double)inputPeak)/outputPeak );
}
return tmpData;
outputPeak = ImageUtil.peakValue(tmpData);
ImageUtil.normalize(data, tmpData, startX, startY, stopX, stopY, ((double)inputPeak)/outputPeak );
}
}
}

View file

@ -52,7 +52,7 @@ public class ColorIntensityFilter extends ImageFilterProcessor{
}
@Override
public int[][][] process(final int[][][] data, int cols, int rows) {
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
// making sure the scales are right
if(redScale > 100) redScale = 100;
else if(redScale < 0) redScale = 0;
@ -62,29 +62,26 @@ public class ColorIntensityFilter extends ImageFilterProcessor{
if(blueScale > 100) blueScale = 100;
else if(blueScale < 0) blueScale = 0;
int[][][] output = new int[rows][cols][4];
// Applying the color intensity to the image
for(int y=0; y<rows ;y++){
setProgress(ZMath.percent(0, rows-1, y));
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, stopY-startY-1, y));
for(int x=startX; x<stopX ;x++){
if(!invert){
// inversion
output[y][x][0] = data[y][x][0];
output[y][x][1] = 255 - data[y][x][1] * redScale/100;
output[y][x][2] = 255 - data[y][x][2] * greenScale/100;
output[y][x][3] = 255 - data[y][x][3] * blueScale/100;
data[y][x][0] = data[y][x][0];
data[y][x][1] = 255 - data[y][x][1] * redScale/100;
data[y][x][2] = 255 - data[y][x][2] * greenScale/100;
data[y][x][3] = 255 - data[y][x][3] * blueScale/100;
}
else{
output[y][x][0] = data[y][x][0];
output[y][x][1] = data[y][x][1] * redScale/100;
output[y][x][2] = data[y][x][2] * greenScale/100;
output[y][x][3] = data[y][x][3] * blueScale/100;
data[y][x][0] = data[y][x][0];
data[y][x][1] = data[y][x][1] * redScale/100;
data[y][x][2] = data[y][x][2] * greenScale/100;
data[y][x][3] = data[y][x][3] * blueScale/100;
}
}
}
return output;
}
}

View file

@ -30,18 +30,14 @@ public class ContrastBrightnessFilter extends ImageFilterProcessor{
}
@Override
public int[][][] process(final int[][][] data, int cols, int rows) {
int mean = ImageUtil.meanValue(data, cols, rows);
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
int mean = ImageUtil.meanValue(data);
int[][][] output = ImageUtil.copyArray(data, cols, rows);
ImageUtil.addMeanValue(output, cols, rows, mean*(-1));
ImageUtil.scale(output, cols, rows, contrast);
ImageUtil.addMeanValue(output, cols, rows, (int)(brightness*mean));
ImageUtil.addMeanValue(data, startX, startY, stopX, stopY, mean*(-1));
ImageUtil.scale(data, startX, startY, stopX, stopY, contrast);
ImageUtil.addMeanValue(data, startX, startY, stopX, stopY, (int)(brightness*mean));
ImageUtil.clip(output ,cols, rows);
return output;
ImageUtil.clip(data , startX, startY, stopX, stopY);
}
}

View file

@ -38,36 +38,32 @@ public class DitheringFilter extends ImageFilterProcessor{
}
@Override
public int[][][] process(final int[][][] data, int cols, int rows) {
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
int error, index;
int[] currentPixel;
int[][][] output = ImageUtil.copyArray(data, cols, rows);
for(int y=0; y<rows ;y++){
setProgress(ZMath.percent(0, rows-1, y));
for(int x=0; x<cols ;x++){
currentPixel = output[y][x];
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, stopY-startY-1, y));
for(int x=startX; x<stopX ;x++){
currentPixel = data[y][x];
index = findNearestColor(currentPixel, palette);
output[y][x] = palette[index];
data[y][x] = palette[index];
for (int i = 1; i < 4; i++) {
error = currentPixel[i] - palette[index][i];
if (x + 1 < cols) {
output[y+0][x+1][i] = ImageUtil.clip( output[y+0][x+1][i] + (error*7)/16 );
if (x + 1 < data[0].length) {
data[y+0][x+1][i] = ImageUtil.clip( data[y+0][x+1][i] + (error*7)/16 );
}
if (y + 1 < rows) {
if (y + 1 < data.length) {
if (x - 1 > 0)
output[y+1][x-1][i] = ImageUtil.clip( output[y+1][x-1][i] + (error*3)/16 );
output[y+1][x+0][i] = ImageUtil.clip( output[y+1][x+0][i] + (error*5)/16 );
if (x + 1 < cols)
output[y+1][x+1][i] = ImageUtil.clip( output[y+1][x+1][i] + (error*1)/16 );
data[y+1][x-1][i] = ImageUtil.clip( data[y+1][x-1][i] + (error*3)/16 );
data[y+1][x+0][i] = ImageUtil.clip( data[y+1][x+0][i] + (error*5)/16 );
if (x + 1 < data[0].length)
data[y+1][x+1][i] = ImageUtil.clip( data[y+1][x+1][i] + (error*1)/16 );
}
}
}
}
return output;
}
private static int findNearestColor(int[] color, int[][] palette) {

View file

@ -4,6 +4,7 @@ import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import zutil.image.ImageFilterProcessor;
import zutil.image.ImageUtil;
import zutil.math.ZMath;
public class FaceDetectionFilter extends ImageFilterProcessor{
@ -13,35 +14,37 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
}
@Override
public int[][][] process(int[][][] data, int cols, int rows) {
int[][][] IRgBy = convertARGBToIRgBy(data, cols, rows);
public void process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int[][][] IRgBy = convertARGBToIRgBy(data, startX, startY, stopX, stopY);
MedianFilter median = new MedianFilter(null, 4*getSCALE(cols,rows), new boolean[]{false,false,true,true});
IRgBy = median.process(IRgBy, cols, rows);
MedianFilter median = new MedianFilter(null, 4*getSCALE(stopX-startX, stopY-startY), new boolean[]{false,false,true,true});
median.process(IRgBy);
setProgress(ZMath.percent(0, 4, 1));
//********* Texture Map ********
median = new MedianFilter(null, 8*getSCALE(cols,rows), new boolean[]{false,true,false,false});
int[][][] textureMap = median.process(IRgBy, cols, rows);
median = new MedianFilter(null, 8*getSCALE(stopX-startX, stopY-startY), new boolean[]{false,true,false,false});
int[][][] textureMap = ImageUtil.copyArray(IRgBy);
median.process(IRgBy);
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
textureMap[y][x][1] = Math.abs(IRgBy[y][x][1]-textureMap[y][x][1]);
}
}
median = new MedianFilter(null, 12*getSCALE(cols,rows), new boolean[]{false,true,false,false});
textureMap = median.process(textureMap, cols, rows);
median = new MedianFilter(null, 12*getSCALE(stopX-startX, stopY-startY), new boolean[]{false,true,false,false});
textureMap = ImageUtil.copyArray(IRgBy);
median.process(textureMap);
setProgress(ZMath.percent(0, 4, 2));
//*********** Hue & Saturation *********
int[][] skinMap = new int[rows][cols];
int[][] hueMap = new int[rows][cols];
int[][] saturationMap = new int[rows][cols];
int[][] skinMap = new int[data.length][data[0].length];
int[][] hueMap = new int[data.length][data[0].length];
int[][] saturationMap = new int[data.length][data[0].length];
int hue, saturation;
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
// hue = (atan^2(Rg,By))
hue = (int)( Math.atan2(IRgBy[y][x][2], IRgBy[y][x][3]) * 360/2*Math.PI);
// saturation = sqrt(Rg^2+By^2)
@ -61,28 +64,30 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
setProgress(ZMath.percent(0, 4, 3));
//************** SkinMap dilation ********************
skinMap = dilation(skinMap , cols, rows);
skinMap = dilation(skinMap , startX, startY, stopX, stopY);
//*****************************************************
setProgress(100);
//return convertArrayToARGBchannel(hueMap, cols, rows, -150, 150, 1);
//return convertArrayToARGBchannel(saturationMap, cols, rows, 0, 70, 1);
return convertArrayToARGBchannel(skinMap, cols, rows, 0, 1, 2);
//return convertArrayToARGBchannel(hueMap, startX, startY, stopX, stopY, -150, 150, 1);
//return convertArrayToARGBchannel(saturationMap, startX, startY, stopX, stopY, 0, 70, 1);
ImageUtil.copyArray(
convertArrayToARGBchannel(skinMap, startX, startY, stopX, stopY, 0, 1, 2),
data, startX, startY, stopX, stopY);
}
private int[][] dilation(int[][] data, int cols, int rows){
int[][] output = new int[rows][cols];
private int[][] dilation(int[][] data, int startX, int startY, int stopX, int stopY){
int[][] output = new int[data.length][data[0].length];
int radX = 8;
int radY = 8;
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
if(data[y][x] == 1){
for(int dy=y-radY; dy<y+radY ;dy++){
for(int dx=x-radX; dx<x+radX ;dx++){
if(dy >= 0 && dy < rows && dx >= 0 && dx < cols)
if(dy >= 0 && dy < data.length && dx >= 0 && dx < data[0].length)
output[dy][dx] = 1;
}
}
@ -99,18 +104,20 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
* Converts the given data array to a color image
*
* @param data The 2d data
* @param cols The size of the image data
* @param rows The size of the image data
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @param min The minimum value in the data
* @param max The maximum value in the data
* @param channel The color channel to apply the data to
* @return A ARGB array
*/
public int[][][] convertArrayToARGBchannel(int[][] data, int cols, int rows,int min, int max, int channel){
int[][][] output = new int[rows][cols][4];
public int[][][] convertArrayToARGBchannel(int[][] data, int startX, int startY, int stopX, int stopY,int min, int max, int channel){
int[][][] output = new int[data.length][data[0].length][4];
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
output[y][x][0] = 255;
output[y][x][channel] = (int) ZMath.percent(min, max, data[y][x]);
}
@ -126,15 +133,17 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
* By = L(B)-[L(G)+L(R)]/2
*
* @param data The RGB data
* @param cols The number of columns
* @param rows The number of rows
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @return IRgBy data
*/
public int[][][] convertARGBToIRgBy(int[][][] data, int cols, int rows){
int[][][] output = new int[rows][cols][4];
public int[][][] convertARGBToIRgBy(int[][][] data, int startX, int startY, int stopX, int stopY){
int[][][] output = new int[data.length][data[0].length][4];
for(int y=0; y<rows ;y++){
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
for(int x=startX; x<stopX ;x++){
output[y][x][0] = data[y][x][0];
// I= [L(R)+L(B)+L(G)]/3
output[y][x][1] = (
@ -158,8 +167,8 @@ public class FaceDetectionFilter extends ImageFilterProcessor{
}
private int getSCALE(int cols, int rows){
return (cols+rows)/320;
private int getSCALE(int width, int height){
return (width+height)/320;
}

View file

@ -4,6 +4,7 @@ import java.awt.image.BufferedImage;
import zutil.algo.sort.sortable.SortableDataList;
import zutil.image.ImageFilterProcessor;
import zutil.image.ImageUtil;
import zutil.math.ZMath;
/**
@ -60,44 +61,42 @@ public class MedianFilter extends ImageFilterProcessor{
pixelValue[x][y] := colorArray[window width / 2][window height / 2];
*/
@Override
public int[][][] process(int[][][] data, int cols, int rows) {
int[][][] output = new int[rows][cols][4];
public void process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int[][][] tmpData = ImageUtil.copyArray(data);
int edgeX = windowSize / 2;
int edgeY = windowSize / 2;
int[][] tmpArray = new int[4][256*2];
int pixelCount = 0;
for(int y=0; y<rows ;y++){
setProgress(ZMath.percent(0, rows-1, y));
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, stopY-startY-1, y));
for(int x=startX; x<stopX ;x++){
pixelCount = 0;
for(int fy=0; fy<windowSize ;fy++){
for(int fx=0; fx<windowSize ;fx++){
if(y+fy-edgeY >= 0 && y+fy-edgeY < rows && x+fx-edgeX >= 0 && x+fx-edgeX < cols){
if(y+fy-edgeY >= 0 && y+fy-edgeY < data.length && x+fx-edgeX >= 0 && x+fx-edgeX < data[0].length){
//colorArray[fx][fy] := pixelvalue[x + fx - edgex][y + fy - edgey]
if(channels[0]) tmpArray[0][ getMedianIndex( data[y + fy - edgeY][x + fx - edgeX][0] ) ]++;
if(channels[1]) tmpArray[1][ getMedianIndex( data[y + fy - edgeY][x + fx - edgeX][1] ) ]++;
if(channels[2]) tmpArray[2][ getMedianIndex( data[y + fy - edgeY][x + fx - edgeX][2] ) ]++;
if(channels[3]) tmpArray[3][ getMedianIndex( data[y + fy - edgeY][x + fx - edgeX][3] ) ]++;
if(channels[0]) tmpArray[0][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][0] ) ]++;
if(channels[1]) tmpArray[1][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][1] ) ]++;
if(channels[2]) tmpArray[2][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][2] ) ]++;
if(channels[3]) tmpArray[3][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][3] ) ]++;
pixelCount++;
}
}
}
if(channels[0])output[y][x][0] = findMedian(tmpArray[0], pixelCount/2);
else output[y][x][0] = data[y][x][0];
if(channels[1])output[y][x][1] = findMedian(tmpArray[1], pixelCount/2);
else output[y][x][1] = data[y][x][1];
if(channels[2])output[y][x][2] = findMedian(tmpArray[2], pixelCount/2);
else output[y][x][2] = data[y][x][2];
if(channels[3])output[y][x][3] = findMedian(tmpArray[3], pixelCount/2);
else output[y][x][3] = data[y][x][3];
if(channels[0]) data[y][x][0] = findMedian(tmpArray[0], pixelCount/2);
else data[y][x][0] = tmpData[y][x][0];
if(channels[1]) data[y][x][1] = findMedian(tmpArray[1], pixelCount/2);
else data[y][x][1] = tmpData[y][x][1];
if(channels[2]) data[y][x][2] = findMedian(tmpArray[2], pixelCount/2);
else data[y][x][2] = tmpData[y][x][2];
if(channels[3]) data[y][x][3] = findMedian(tmpArray[3], pixelCount/2);
else data[y][x][3] = tmpData[y][x][3];
}
}
return output;
}
private int getMedianIndex(int i){

View file

@ -3,15 +3,17 @@ package zutil.image.filters;
import java.awt.image.BufferedImage;
import zutil.image.ImageFilterProcessor;
import zutil.image.ImageUtil;
import zutil.math.ZMath;
public class ResizeImage extends ImageFilterProcessor{
private int width;
private int hight;
private int height;
private int[][][] newData;
/**
* Will create a ResizeImage object and fix the hight with the aspect
* Will create a ResizeImage object and fix the height with the aspect
* of the width
*
* @param img The image to resize
@ -26,38 +28,45 @@ public class ResizeImage extends ImageFilterProcessor{
*
* @param img The image to resize
* @param w The new width if -1 then it will be scaled whit aspect of the hight
* @param h The new hight if -1 then it will be scaled whit aspect of the width
* @param h The new height if -1 then it will be scaled whit aspect of the width
*/
public ResizeImage(BufferedImage img, int w, int h){
super(img);
width = w;
hight = h;
height = h;
}
@Override
public int[][][] process(final int[][][] data, int cols, int rows) {
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
if(width < 1){
hight = (int)(((double)width/cols)*rows);
height = (int)(((double)width/(stopX-startX))*(stopY-startY));
}
else if(hight < 1){
width = (int)(((double)hight/rows)*cols);
else if(height < 1){
width = (int)(((double)height/(stopY-startY))*(stopX-startY));
}
int[][][] tmp = new int[hight][width][4];
double xScale = ((double)cols/width);
double yScale = ((double)rows/hight);
newData = new int[height][width][4];
double xScale = ((double)(stopX-startX)/width);
double yScale = ((double)(stopY-startY)/height);
for(int y=0; y<width ;y++){
setProgress(ZMath.percent(0, width-1, y));
for(int x=0; x<hight ;x++){
tmp[y][x][0] = data[(int)(y*yScale)][(int)(x*xScale)][0];
tmp[y][x][1] = data[(int)(y*yScale)][(int)(x*xScale)][1];
tmp[y][x][2] = data[(int)(y*yScale)][(int)(x*xScale)][2];
tmp[y][x][3] = data[(int)(y*yScale)][(int)(x*xScale)][3];
for(int x=0; x<height ;x++){
newData[y][x][0] = data[(int)(y*yScale)][(int)(x*xScale)][0];
newData[y][x][1] = data[(int)(y*yScale)][(int)(x*xScale)][1];
newData[y][x][2] = data[(int)(y*yScale)][(int)(x*xScale)][2];
newData[y][x][3] = data[(int)(y*yScale)][(int)(x*xScale)][3];
}
}
return tmp;
ImageUtil.copyArray(newData, data, 0, 0, width, height);
}
/**
* Returns the resulting image after processing
* @return an image or null if not processed
*/
public int[][][] getResult(){
return newData;
}
}

View file

@ -41,15 +41,14 @@ public class SpotLightFilter extends ImageFilterProcessor{
}
@Override
public int[][][] process(final int[][][] data, int cols, int rows) {
if(xPos < 0) xPos = cols/2;
if(yPos < 0) yPos = rows/2;
public void process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
if(xPos < 0) xPos = data[0].length/2;
if(yPos < 0) yPos = data.length/2;
int[][][] output = new int[rows][cols][4];
double scale, dx, dy, distance;
for(int y=0; y<rows ;y++){
setProgress(ZMath.percent(0, rows-1, y));
for(int x=0; x<cols ;x++){
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, (stopY-startY)-1, y));
for(int x=startX; x<stopX ;x++){
dx = x-xPos;
dy = y-yPos;
@ -62,13 +61,12 @@ public class SpotLightFilter extends ImageFilterProcessor{
scale = 1-(distance/radius);
}
output[y][x][0] = data[y][x][0];
output[y][x][1] = ImageUtil.clip((int)(scale * data[y][x][1]));
output[y][x][2] = ImageUtil.clip((int)(scale * data[y][x][2]));
output[y][x][3] = ImageUtil.clip((int)(scale * data[y][x][3]));
data[y][x][0] = data[y][x][0];
data[y][x][1] = ImageUtil.clip((int)(scale * data[y][x][1]));
data[y][x][2] = ImageUtil.clip((int)(scale * data[y][x][2]));
data[y][x][3] = ImageUtil.clip((int)(scale * data[y][x][3]));
}
}
return output;
}
}
}

View file

@ -58,7 +58,7 @@ public class HttpPrintStream extends PrintStream{
public void sendHeader(String header) throws Exception{
if(cookie == null)
throw new Exception("Header already sent!!!");
super.println(header);
super.print(header+"\n");
}
/**
@ -69,27 +69,25 @@ public class HttpPrintStream extends PrintStream{
}
/**
* NOT TO BE USED!!!!
* use printOrBuffer(String s) instead
* Prints an string
*/
@Deprecated
public void print(String s){
super.print(s);
printOrBuffer(s);
}
/**
* prints to all
*/
public void printOrBuffer(String s){
private void printOrBuffer(String s){
if(buffer_enabled){
buffer.append(s);
}
else{
if(cookie != null){
for(String key : cookie.keySet()){
super.println("Set-Cookie: "+key+"="+cookie.get(key)+"; ");
super.print("Set-Cookie: "+key+"="+cookie.get(key)+"; \n");
}
super.println(" \n");
super.print(" \n");
cookie = null;
}
super.print(s);
@ -115,21 +113,21 @@ public class HttpPrintStream extends PrintStream{
}
public void println(){ println("");}
public void println(boolean x){ println(""+x);}
public void println(char x){ println(""+x);}
public void println(boolean x){ println(String.valueOf(x));}
public void println(char x){ println(String.valueOf(x));}
public void println(char[] x){ println(new String(x));}
public void println(double x){ println(""+x);}
public void println(float x){ println(""+x);}
public void println(int x){ println(""+x);}
public void println(long x){ println(""+x);}
public void println(Object x){ println(""+x);}
public void println(double x){ println(String.valueOf(x));}
public void println(float x){ println(String.valueOf(x));}
public void println(int x){ println(String.valueOf(x));}
public void println(long x){ println(String.valueOf(x));}
public void println(Object x){ println(String.valueOf(x));}
public void print(boolean x){ printOrBuffer(""+x);}
public void print(char x){ printOrBuffer(""+x);}
public void print(boolean x){ printOrBuffer(String.valueOf(x));}
public void print(char x){ printOrBuffer(String.valueOf(x));}
public void print(char[] x){ printOrBuffer(new String(x));}
public void print(double x){ printOrBuffer(""+x);}
public void print(float x){ printOrBuffer(""+x);}
public void print(int x){ printOrBuffer(""+x);}
public void print(long x){ printOrBuffer(""+x);}
public void print(Object x){ printOrBuffer(""+x);}
public void print(double x){ printOrBuffer(String.valueOf(x));}
public void print(float x){ printOrBuffer(String.valueOf(x));}
public void print(int x){ printOrBuffer(String.valueOf(x));}
public void print(long x){ printOrBuffer(String.valueOf(x));}
public void print(Object x){ printOrBuffer(String.valueOf(x));}
}

View file

@ -3,7 +3,6 @@ package zutil.test;
import java.io.IOException;
import java.util.HashMap;
import zutil.FileFinder;
import zutil.network.http.HttpPage;
import zutil.network.http.HttpPrintStream;
import zutil.network.http.HttpServer;

View file

@ -61,13 +61,13 @@ public class ImageProcessorTest implements ProgressListener{
BufferedImage procImg = null;
try {
//ImageFilterProcessor processor = new SpotLightFilter(img,100,100,100);
//ImageFilterProcessor processor = new ContrastBrightnessFilter(img);
//ImageFilterProcessor processor = new BlurFilter(img, 10);
//ImageFilterProcessor processor = new ColorIntensityFilter(img, true);
ImageFilterProcessor processor = new BlurFilter(img, 100);
//ImageFilterProcessor processor = new DitheringFilter(img);
//ImageFilterProcessor processor = new ResizeImage(img,100,100);
//ImageFilterProcessor processor = new ContrastBrightnessFilter(img);
ImageFilterProcessor processor = new DitheringFilter(img);
//ImageFilterProcessor processor = new MedianFilter(img);
//ImageFilterProcessor processor = new ResizeImage(img,100,100);
//ImageFilterProcessor processor = new SpotLightFilter(img,100,100,100);
//ImageFilterProcessor processor = new FaceDetectionFilter(img);
processor.setProgressListener(this);