import java.applet.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.util.*; import java.io.*; import java.util.Arrays.*; /** *AdapThresh is an algorithm to apply adaptive thresholding to an image. *@author Timothy Sharman *@see code.iface.adapthresh */ public class AdapThresh extends Thread{ //the width and height of this image in pixels private int i_w, i_h; //pixel arrays for input and output images private int[] src_1d; private int[] dest_1d; /** *Applies the adaptive thresholding operator to the specified image array *using the mean function to find the threshold value * *@param src pixel array representing image to be thresholded *@param width width of the image in pixels *@param height height of the image in pixels *@param size the size of the neigbourhood used in finding the threshold *@param con the constant value subtracted from the mean *@return a thresholded pixel array of the input image array */ public int [] mean_thresh(int [] src, int width, int height, int size, int con){ i_w = width; i_h = height; src_1d = new int[i_w * i_h]; dest_1d = new int[i_w * i_h]; int mean = 0; int count = 0; src_1d = src; int [][] tmp_2d = new int[i_w][i_h]; //First convert input array from 1_d to 2_d for ease of processing for(int i = 0; i < i_w; i++){ for(int j = 0; j < i_h; j++){ tmp_2d[i][j] = src_1d[i+(j*i_w)] & 0x000000ff; } } //Now find the sum of values in the size X size neigbourhood for(int j = 0; j < i_h; j++){ for(int i = 0; i < i_w; i++){ mean = 0; count = 0; //Check the local neighbourhood for(int k = 0; k < size; k++){ for(int l = 0; l < size; l++){ try{ mean = mean + tmp_2d[(i-((int)(size/2))+k)] [(j-((int)(size/2))+l)]; count++; } //If out of bounds then ignore pixel catch(ArrayIndexOutOfBoundsException e){ } } } //Find the mean value mean = (int)(mean /count) - con; //Threshold below the mean if(tmp_2d[i][j] > mean){ dest_1d[i+(j*i_w)] = 0xffffffff; } else { dest_1d[i+(j*i_w)] = 0xff000000; } } } return dest_1d; } /** *Applies the adaptive thresholding operator to the specified image array *using the median function to find the threshold value * *@param src pixel array representing image to be thresholded *@param width width of the image in pixels *@param height height of the image in pixels *@param size the size of the neigbourhood used in finding the threshold *@param con the constant value subtracted from the median *@return a thresholded pixel array of the input image array */ public int [] median_thresh(int [] src, int width, int height, int size, int con){ i_w = width; i_h = height; src_1d = new int[i_w * i_h]; dest_1d = new int[i_w * i_h]; int median = 0; int [] values = new int[size*size]; int count = 0; src_1d = src; int [][] tmp_2d = new int[i_w][i_h]; //First convert input array from 1_d to 2_d for ease of processing for(int i = 0; i < i_w; i++){ for(int j = 0; j < i_h; j++){ tmp_2d[i][j] = src_1d[i+(j*i_w)] & 0x000000ff; } } //Now find the values in the size X size neigbourhood for(int j = 0; j < i_h; j++){ for(int i = 0; i < i_w; i++){ median = 0; count = 0; values = new int[size*size]; //Check the local neighbourhood for(int k = 0; k < size; k++){ for(int l = 0; l < size; l++){ try{ values[count] = tmp_2d[(i-((int)(size/2))+k)] [(j-((int)(size/2))+l)]; count++; } //If out of bounds then ignore pixel catch(ArrayIndexOutOfBoundsException e){ } } } //Find the median value //First Sort the array Arrays.sort(values); //Then select the median count = count / 2; median = values[count] - con; //Threshold below the median if(tmp_2d[i][j] >= median){ dest_1d[i+(j*i_w)] = 0xffffffff; } else { dest_1d[i+(j*i_w)] = 0xff000000; } } } return dest_1d; } /** *Applies the adaptive thresholding operator to the specified image array *using the mean of max & min function to find the threshold value * *@param src pixel array representing image to be thresholded *@param width width of the image in pixels *@param height height of the image in pixels *@param size the size of the neigbourhood used in finding the threshold *@param con the constant value subtracted from the mean *@return a thresholded pixel array of the input image array */ public int [] meanMaxMin_thresh(int [] src, int width, int height, int size, int con){ i_w = width; i_h = height; src_1d = new int[i_w * i_h]; dest_1d = new int[i_w * i_h]; int mean = 0; int max, min; int [] values = new int[size*size]; src_1d = src; int [][] tmp_2d = new int[i_w][i_h]; //First convert input array from 1_d to 2_d for ease of processing for(int i = 0; i < i_w; i++){ for(int j = 0; j < i_h; j++){ tmp_2d[i][j] = src_1d[i+(j*i_w)] & 0x000000ff; } } int tmp; //Now find the max and min of values in the size X size neigbourhood for(int j = 0; j < i_h; j++){ for(int i = 0; i < i_w; i++){ mean = 0; max = tmp_2d[i][j]; min = tmp_2d[i][j]; //Check the local neighbourhood for(int k = 0; k < size; k++){ for(int l = 0; l < size; l++){ try{ tmp = tmp_2d[(i-((int)(size/2))+k)] [(j-((int)(size/2))+l)]; if(tmp > max){ max = tmp; } if(tmp < min){ min = tmp; } } //If out of bounds then ignore pixel catch(ArrayIndexOutOfBoundsException e){ } } } //Find the mean value tmp = max + min; tmp = tmp / 2; mean = tmp - con; //Threshold below the mean if(tmp_2d[i][j] >= mean){ dest_1d[i+(j*i_w)] = 0xffffffff; } else { dest_1d[i+(j*i_w)] = 0xff000000; } } } return dest_1d; } }