/** * Fills the whole image with the specified value * * @param input An image. * @param value The value that the image is being filled with. */ public static void fill(GrayF64 input, double value) { for (int y = 0; y < input.height; y++) { int index = input.getStartIndex() + y * input.getStride(); Arrays.fill(input.data,index,index+input.width, value); } }
/** * Flips the image from top to bottom */ public static void flipVertical( GrayF64 input ) { int h2 = input.height/2; for( int y = 0; y < h2; y++ ) { int index1 = input.getStartIndex() + y * input.getStride(); int index2 = input.getStartIndex() + (input.height - y - 1) * input.getStride(); int end = index1 + input.width; while( index1 < end ) { double tmp = input.data[index1]; input.data[index1++] = input.data[index2]; input.data[index2++] = (double)tmp; } } }
/** * Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max. */ public static void addUniform(GrayF64 input, Random rand , double min , double max) { double range = max-min; double[] data = input.data; for (int y = 0; y < input.height; y++) { int index = input.getStartIndex() + y * input.getStride(); for (int x = 0; x < input.width; x++) { double value = data[index] + rand.nextDouble()*range+min; data[index++] = value; } } }
/** * Flips the image from left to right */ public static void flipHorizontal( GrayF64 input ) { int w2 = input.width/2; for( int y = 0; y < input.height; y++ ) { int index1 = input.getStartIndex() + y * input.getStride(); int index2 = index1 + input.width-1; int end = index1 + w2; while( index1 < end ) { double tmp = input.data[index1]; input.data[index1++] = input.data[index2]; input.data[index2--] = (double)tmp; } } }
} /** * Sets each value in the image to a value drawn from an uniform distribution that has a range of min ≤ X < max. * * @param img Image which is to be filled. Modified, * @param rand Random number generator * @param min Minimum value of the distribution, inclusive * @param max Maximum value of the distribution, inclusive */ public static void fillUniform(GrayF64 img, Random rand , double min , double max) { double range = max-min; double[] data = img.data; for (int y = 0; y < img.height; y++) { int index = img.getStartIndex() + y * img.getStride(); for (int x = 0; x < img.width; x++) { data[index++] = rand.nextDouble()*range+min; } } }
/** * Computes the variance of pixel intensity values inside the image. * * @param img Input image. Not modified. * @param mean Mean pixel intensity value. * @return Pixel variance */ public static double variance( GrayF64 img , double mean ) { double variance = 0; for (int y = 0; y < img.height; y++) { int index = img.getStartIndex() + y * img.getStride(); int indexEnd = index+img.width; // for(int x = 0; x < img.width; x++ ) { for (; index < indexEnd; index++ ) { double d = (img.data[index]) - mean; variance += d*d; } } return variance/(img.width*img.height); }
/** * Adds Gaussian/normal i.i.d noise to each pixel in the image. If a value exceeds the specified * it will be set to the closest bound. * @param input Input image. Modified. * @param rand Random number generator. * @param sigma Distributions standard deviation. * @param lowerBound Allowed lower bound * @param upperBound Allowed upper bound */ public static void addGaussian(GrayF64 input, Random rand , double sigma , double lowerBound , double upperBound ) { for (int y = 0; y < input.height; y++) { int index = input.getStartIndex() + y * input.getStride(); for (int x = 0; x < input.width; x++) { double value = (input.data[index] ) + (rand.nextGaussian()*sigma); if( value < lowerBound ) value = lowerBound; if( value > upperBound ) value = upperBound; input.data[index++] = value; } } }
/** * Sets each value in the image to a value drawn from a Gaussian distribution. A user * specified lower and upper bound is provided to ensure that the values are within a legal * range. A drawn value outside the allowed range will be set to the closest bound. * * @param input Input image. Modified. * @param rand Random number generator * @param mean Distribution's mean. * @param sigma Distribution's standard deviation. * @param lowerBound Lower bound of value clip * @param upperBound Upper bound of value clip */ public static void fillGaussian(GrayF64 input, Random rand , double mean , double sigma , double lowerBound , double upperBound ) { double[] data = input.data; for (int y = 0; y < input.height; y++) { int index = input.getStartIndex() + y * input.getStride(); for (int x = 0; x < input.width; x++) { double value = (rand.nextGaussian()*sigma+mean); if( value < lowerBound ) value = lowerBound; if( value > upperBound ) value = upperBound; data[index++] = value; } } }
/** * <p> * Computes the absolute value of the difference between each pixel in the two images.<br> * d(x,y) = |img1(x,y) - img2(x,y)| * </p> * @param imgA Input image. Not modified. * @param imgB Input image. Not modified. * @param diff Absolute value of difference image. Modified. */ public static void diffAbs(GrayF64 imgA , GrayF64 imgB , GrayF64 diff ) { InputSanityCheck.checkSameShape(imgA,imgB,diff); final int h = imgA.getHeight(); final int w = imgA.getWidth(); for (int y = 0; y < h; y++) { int indexA = imgA.getStartIndex() + y * imgA.getStride(); int indexB = imgB.getStartIndex() + y * imgB.getStride(); int indexDiff = diff.getStartIndex() + y * diff.getStride(); int indexEnd = indexA+w; // for(int x = 0; x < w; x++ ) { for (; indexA < indexEnd; indexA++, indexB++, indexDiff++ ) { diff.data[indexDiff] = Math.abs((imgA.data[indexA] ) - (imgB.data[indexB] )); } } }
/** * <p> * Performs pixel-wise addition<br> * output(x,y) = imgA(x,y) + imgB(x,y) * </p> * @param imgA Input image. Not modified. * @param imgB Input image. Not modified. * @param output Output image. Modified. */ public static void add(GrayF64 imgA , GrayF64 imgB , GrayF64 output ) { InputSanityCheck.checkSameShape(imgA,imgB,output); final int h = imgA.getHeight(); final int w = imgA.getWidth(); for (int y = 0; y < h; y++) { int indexA = imgA.getStartIndex() + y * imgA.getStride(); int indexB = imgB.getStartIndex() + y * imgB.getStride(); int indexOut = output.getStartIndex() + y * output.getStride(); int indexEnd = indexA+w; // for(int x = 0; x < w; x++ ) { for (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) { output.data[indexOut] = ((imgA.data[indexA] ) + (imgB.data[indexB] )); } } }
/** * <p> * Performs pixel-wise multiplication<br> * output(x,y) = imgA(x,y) * imgB(x,y) * </p> * @param imgA Input image. Not modified. * @param imgB Input image. Not modified. * @param output Output image. Modified. */ public static void multiply(GrayF64 imgA , GrayF64 imgB , GrayF64 output ) { InputSanityCheck.checkSameShape(imgA,imgB,output); final int h = imgA.getHeight(); final int w = imgA.getWidth(); for (int y = 0; y < h; y++) { int indexA = imgA.getStartIndex() + y * imgA.getStride(); int indexB = imgB.getStartIndex() + y * imgB.getStride(); int indexOut = output.getStartIndex() + y * output.getStride(); int indexEnd = indexA+w; // for(int x = 0; x < w; x++ ) { for (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) { output.data[indexOut] = ((imgA.data[indexA] ) * (imgB.data[indexB] )); } } }
/** * <p> * Performs pixel-wise subtraction.<br> * output(x,y) = imgA(x,y) - imgB(x,y) * </p> * @param imgA Input image. Not modified. * @param imgB Input image. Not modified. * @param output Output image. Modified. */ public static void subtract(GrayF64 imgA , GrayF64 imgB , GrayF64 output ) { InputSanityCheck.checkSameShape(imgA,imgB,output); final int h = imgA.getHeight(); final int w = imgA.getWidth(); for (int y = 0; y < h; y++) { int indexA = imgA.getStartIndex() + y * imgA.getStride(); int indexB = imgB.getStartIndex() + y * imgB.getStride(); int indexOut = output.getStartIndex() + y * output.getStride(); int indexEnd = indexA+w; // for(int x = 0; x < w; x++ ) { for (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) { output.data[indexOut] = ((imgA.data[indexA] ) - (imgB.data[indexB] )); } } }
/** * <p> * Performs pixel-wise division<br> * output(x,y) = imgA(x,y) / imgB(x,y) * </p> * @param imgA Input image. Not modified. * @param imgB Input image. Not modified. * @param output Output image. Modified. */ public static void divide(GrayF64 imgA , GrayF64 imgB , GrayF64 output ) { InputSanityCheck.checkSameShape(imgA,imgB,output); final int h = imgA.getHeight(); final int w = imgA.getWidth(); for (int y = 0; y < h; y++) { int indexA = imgA.getStartIndex() + y * imgA.getStride(); int indexB = imgB.getStartIndex() + y * imgB.getStride(); int indexOut = output.getStartIndex() + y * output.getStride(); int indexEnd = indexA+w; // for(int x = 0; x < w; x++ ) { for (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) { output.data[indexOut] = ((imgA.data[indexA] ) / (imgB.data[indexB] )); } } }
/** * Extracts a single band from a multi-band image * * @param input Multi-band image * @param band which bad is to be extracted * @param output The single band image */ public static void extractBand( InterleavedF64 input, int band , GrayF64 output) { final int numBands = input.numBands; for (int y = 0; y < input.height; y++) { int indexIn = input.getStartIndex() + y * input.getStride() + band; int indexOut = output.getStartIndex() + y * output.getStride(); int end = indexOut + output.width; for (; indexOut < end; indexIn += numBands , indexOut++ ) { output.data[indexOut] = input.data[indexIn]; } } }
/** * Inserts a single band into a multi-band image overwriting the original band * * @param input Single band image * @param band Which band the image is to be inserted into * @param output The multi-band image which the input image is to be inserted into */ public static void insertBand( GrayF64 input, int band , InterleavedF64 output) { final int numBands = output.numBands; for (int y = 0; y < input.height; y++) { int indexIn = input.getStartIndex() + y * input.getStride(); int indexOut = output.getStartIndex() + y * output.getStride() + band; int end = indexOut + output.width*numBands - band; for (; indexOut < end; indexOut += numBands , indexIn++ ) { output.data[indexOut] = input.data[indexIn]; } } }
/** * Bounds image pixels to be between these two values * * @param img Image * @param min minimum value. * @param max maximum value. */ public static void boundImage(GrayF64 img , double min , double max ) { final int h = img.getHeight(); final int w = img.getWidth(); double[] data = img.data; for (int y = 0; y < h; y++) { int index = img.getStartIndex() + y * img.getStride(); int indexEnd = index+w; // for(int x = 0; x < w; x++ ) { for (; index < indexEnd; index++) { double value = data[index]; if( value < min ) data[index] = min; else if( value > max ) data[index] = max; } } }
/** * Computes the average for each pixel across all bands in the {@link Planar} image. * * @param input Planar image * @param output Gray scale image containing average pixel values */ public static void averageBand(Planar<GrayF64> input , GrayF64 output ) { final int h = input.getHeight(); final int w = input.getWidth(); GrayF64[] bands = input.bands; for (int y = 0; y < h; y++) { int indexInput = input.getStartIndex() + y * input.getStride(); int indexOutput = output.getStartIndex() + y * output.getStride(); int indexEnd = indexInput+w; // for(int x = 0; x < w; x++ ) { for (; indexInput < indexEnd; indexInput++, indexOutput++ ) { double total = 0; for( int i = 0; i < bands.length; i++ ) { total += bands[i].data[ indexInput ]; } output.data[indexOutput] = (total / bands.length); } } }