From 1bde5a69778b42be79445e7351e0be023bff4941 Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Thu, 16 Apr 2009 20:51:15 +0000 Subject: [PATCH] Fixed some bugs and framework for the image filters --- src/zutil/image/ImageFilterProcessor.java | 18 +- src/zutil/image/ImageUtil.java | 180 ++++++++++++------ src/zutil/image/filters/BlurFilter.java | 91 +++++---- .../image/filters/ColorIntensityFilter.java | 27 ++- .../filters/ContrastBrightnessFilter.java | 16 +- src/zutil/image/filters/DitheringFilter.java | 30 ++- .../image/filters/FaceDetectionFilter.java | 85 +++++---- src/zutil/image/filters/MedianFilter.java | 41 ++-- src/zutil/image/filters/ResizeImage.java | 43 +++-- src/zutil/image/filters/SpotLightFilter.java | 24 ++- src/zutil/network/http/HttpPrintStream.java | 42 ++-- src/zutil/test/HTTPGuessTheNumber.java | 1 - src/zutil/test/ImageProcessorTest.java | 10 +- 13 files changed, 342 insertions(+), 266 deletions(-) diff --git a/src/zutil/image/ImageFilterProcessor.java b/src/zutil/image/ImageFilterProcessor.java index edd0e8e..20472f7 100644 --- a/src/zutil/image/ImageFilterProcessor.java +++ b/src/zutil/image/ImageFilterProcessor.java @@ -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); } diff --git a/src/zutil/image/ImageUtil.java b/src/zutil/image/ImageUtil.java index e46eede..b5df54c 100644 --- a/src/zutil/image/ImageUtil.java +++ b/src/zutil/image/ImageUtil.java @@ -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 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 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 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) { diff --git a/src/zutil/image/filters/FaceDetectionFilter.java b/src/zutil/image/filters/FaceDetectionFilter.java index 1f7dfcf..f1c76d6 100644 --- a/src/zutil/image/filters/FaceDetectionFilter.java +++ b/src/zutil/image/filters/FaceDetectionFilter.java @@ -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= 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= 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){ diff --git a/src/zutil/image/filters/ResizeImage.java b/src/zutil/image/filters/ResizeImage.java index 5a1b133..c81e9be 100644 --- a/src/zutil/image/filters/ResizeImage.java +++ b/src/zutil/image/filters/ResizeImage.java @@ -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