boofcv.alg.misc.ImageMiscOps Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ip Show documentation
Show all versions of ip Show documentation
BoofCV is an open source Java library for real-time computer vision and robotics applications.
/*
* Copyright (c) 2011-2015, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.alg.misc;
import boofcv.struct.image.*;
import java.util.Random;
/**
* Basic image operations which have no place better to go.
*
* DO NOT MODIFY: Generated by GenerateImageMiscOps.
*
* @author Peter Abeles
*/
public class ImageMiscOps {
/**
* Copies a rectangular region from one image into another.
* output[dstX:(dstX+width) , dstY:(dstY+height-1)] = input[srcX:(srcX+width) , srcY:(srcY+height-1)]
*
* @param srcX x-coordinate of corner in input image
* @param srcY y-coordinate of corner in input image
* @param dstX x-coordinate of corner in output image
* @param dstY y-coordinate of corner in output image
* @param width Width of region to be copied
* @param height Height of region to be copied
* @param input Input image
* @param output output image
*/
public static void copy( int srcX , int srcY , int dstX , int dstY , int width , int height ,
ImageInt8 input , ImageInt8 output ) {
if( input.width < srcX+width || input.height < srcY+height )
throw new IllegalArgumentException("Copy region must be contained input image");
if( output.width < dstX+width || output.height < dstY+height )
throw new IllegalArgumentException("Copy region must be contained output image");
for (int y = 0; y < height; y++) {
int indexSrc = input.startIndex + (srcY + y) * input.stride + srcX;
int indexDst = output.startIndex + (dstY + y) * output.stride + dstX;
for (int x = 0; x < width; x++) {
output.data[indexDst++] = input.data[indexSrc++];
}
}
}
/**
* 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(ImageInt8 input, int value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
input.data[index++] = (byte)value;
}
}
}
/**
* 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(InterleavedI8 input, int value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int end = index + input.width*input.numBands;
for (; index < end; index++ ) {
input.data[index] = (byte)value;
}
}
}
/**
* Fills each band in the image with the specified values
*
* @param input An image.
* @param values Array which contains the values each band is to be filled with.
*/
public static void fill(InterleavedI8 input, int[] values) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
for( int band = 0; band < numBands; band++ ) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
int value = values[band];
for (; index < end; index += numBands ) {
input.data[index] = (byte)value;
}
}
}
}
/**
* Fills one band in the image with the specified value
*
* @param input An image.
* @param band Which band is to be filled with the specified value
* @param value The value that the image is being filled with.
*/
public static void fillBand(InterleavedI8 input, int band , int value) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
for (; index < end; index += numBands ) {
input.data[index] = (byte)value;
}
}
}
/**
* Inserts a single band into into one of the bands in a multi-band image
*
* @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( ImageInt8 input, int band , InterleavedI8 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];
}
}
}
/**
* Fills the outside border with the specified value
*
* @param input An image.
* @param value The value that the image is being filled with.
* @param radius Border width.
*/
public static void fillBorder(ImageInt8 input, int value, int radius ) {
// top and bottom
for (int y = 0; y < radius; y++) {
int indexTop = input.startIndex + y * input.stride;
int indexBottom = input.startIndex + (input.height-y-1) * input.stride;
for (int x = 0; x < input.width; x++) {
input.data[indexTop++] = (byte)value;
input.data[indexBottom++] = (byte)value;
}
}
// left and right
int h = input.height-radius;
int indexStart = input.startIndex + radius*input.stride;
for (int x = 0; x < radius; x++) {
int indexLeft = indexStart + x;
int indexRight = indexStart + input.width-1-x;
for (int y = radius; y < h; y++) {
input.data[indexLeft] = (byte)value;
input.data[indexRight] = (byte)value;
indexLeft += input.stride;
indexRight += input.stride;
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(ImageInt8 img, int value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
img.set(x, y, value);
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image. All bands
* are filled with the same value.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(InterleavedI8 img, byte value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
int length = (x1-x0)*img.numBands;
for (int y = y0; y < y1; y++) {
int index = img.startIndex + y*img.stride + x0*img.numBands;
int indexEnd = index + length;
while( index < indexEnd ) {
img.data[index++] = value;
}
}
} /**
* 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, exclusive
*/
public static void fillUniform(ImageInt8 img, Random rand , int min , int max) {
int range = max-min;
byte[] 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++] = (byte)(rand.nextInt(range)+min);
}
}
}
/**
* 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, exclusive
*/
public static void fillUniform(InterleavedI8 img, Random rand , int min , int max) {
int range = max-min;
byte[] data = img.data;
for (int y = 0; y < img.height; y++) {
int index = img.getStartIndex() + y * img.getStride();
int end = index + img.width*img.numBands;
for (; index < end; index++) {
data[index] = (byte)(rand.nextInt(range)+min);
}
}
}
/**
* 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(ImageInt8 input, Random rand , double mean , double sigma , int lowerBound , int upperBound ) {
byte[] 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++) {
int value = (int)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
data[index++] = (byte)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(InterleavedI8 input, Random rand , double mean , double sigma , int lowerBound , int upperBound ) {
byte[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (int)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
data[index++] = (byte)value;
}
}
}
/**
* Flips the image from top to bottom
*/
public static void flipVertical( ImageInt8 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 ) {
int tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2++] = (byte)tmp;
}
}
}
/**
* Flips the image from left to right
*/
public static void flipHorizontal( ImageInt8 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 ) {
int tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2--] = (byte)tmp;
}
}
}
/**
* In-place 90 degree image rotation in the clockwise direction. Only works on
* square images.
*/
public static void rotateCW( ImageInt8 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
int tmp3 = image.data[index3];
image.data[index3] = image.data[index2];
image.data[index2] = image.data[index1];
image.data[index1] = image.data[index0];
image.data[index0] = (byte)tmp3;
}
}
}
/**
* Rotates the image 90 degrees in the clockwise direction.
*/
public static void rotateCW( ImageInt8 input , ImageInt8 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int h = input.height-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(h-y,x,input.data[indexIn++]);
}
}
}
/**
* In-place 90 degree image rotation in the counter-clockwise direction. Only works on
* square images.
*/
public static void rotateCCW( ImageInt8 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
int tmp0 = image.data[index0];
image.data[index0] = image.data[index1];
image.data[index1] = image.data[index2];
image.data[index2] = image.data[index3];
image.data[index3] = (byte)tmp0;
}
}
}
/**
* Rotates the image 90 degrees in the counter-clockwise direction.
*/
public static void rotateCCW( ImageInt8 input , ImageInt8 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int w = input.width-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(y,w-x,input.data[indexIn++]);
}
}
}
/**
* Copies a rectangular region from one image into another.
* output[dstX:(dstX+width) , dstY:(dstY+height-1)] = input[srcX:(srcX+width) , srcY:(srcY+height-1)]
*
* @param srcX x-coordinate of corner in input image
* @param srcY y-coordinate of corner in input image
* @param dstX x-coordinate of corner in output image
* @param dstY y-coordinate of corner in output image
* @param width Width of region to be copied
* @param height Height of region to be copied
* @param input Input image
* @param output output image
*/
public static void copy( int srcX , int srcY , int dstX , int dstY , int width , int height ,
ImageInt16 input , ImageInt16 output ) {
if( input.width < srcX+width || input.height < srcY+height )
throw new IllegalArgumentException("Copy region must be contained input image");
if( output.width < dstX+width || output.height < dstY+height )
throw new IllegalArgumentException("Copy region must be contained output image");
for (int y = 0; y < height; y++) {
int indexSrc = input.startIndex + (srcY + y) * input.stride + srcX;
int indexDst = output.startIndex + (dstY + y) * output.stride + dstX;
for (int x = 0; x < width; x++) {
output.data[indexDst++] = input.data[indexSrc++];
}
}
}
/**
* 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(ImageInt16 input, int value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
input.data[index++] = (short)value;
}
}
}
/**
* 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(InterleavedI16 input, int value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int end = index + input.width*input.numBands;
for (; index < end; index++ ) {
input.data[index] = (short)value;
}
}
}
/**
* Fills each band in the image with the specified values
*
* @param input An image.
* @param values Array which contains the values each band is to be filled with.
*/
public static void fill(InterleavedI16 input, int[] values) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
for( int band = 0; band < numBands; band++ ) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
int value = values[band];
for (; index < end; index += numBands ) {
input.data[index] = (short)value;
}
}
}
}
/**
* Fills one band in the image with the specified value
*
* @param input An image.
* @param band Which band is to be filled with the specified value
* @param value The value that the image is being filled with.
*/
public static void fillBand(InterleavedI16 input, int band , int value) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
for (; index < end; index += numBands ) {
input.data[index] = (short)value;
}
}
}
/**
* Inserts a single band into into one of the bands in a multi-band image
*
* @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( ImageInt16 input, int band , InterleavedI16 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];
}
}
}
/**
* Fills the outside border with the specified value
*
* @param input An image.
* @param value The value that the image is being filled with.
* @param radius Border width.
*/
public static void fillBorder(ImageInt16 input, int value, int radius ) {
// top and bottom
for (int y = 0; y < radius; y++) {
int indexTop = input.startIndex + y * input.stride;
int indexBottom = input.startIndex + (input.height-y-1) * input.stride;
for (int x = 0; x < input.width; x++) {
input.data[indexTop++] = (short)value;
input.data[indexBottom++] = (short)value;
}
}
// left and right
int h = input.height-radius;
int indexStart = input.startIndex + radius*input.stride;
for (int x = 0; x < radius; x++) {
int indexLeft = indexStart + x;
int indexRight = indexStart + input.width-1-x;
for (int y = radius; y < h; y++) {
input.data[indexLeft] = (short)value;
input.data[indexRight] = (short)value;
indexLeft += input.stride;
indexRight += input.stride;
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(ImageInt16 img, int value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
img.set(x, y, value);
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image. All bands
* are filled with the same value.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(InterleavedI16 img, short value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
int length = (x1-x0)*img.numBands;
for (int y = y0; y < y1; y++) {
int index = img.startIndex + y*img.stride + x0*img.numBands;
int indexEnd = index + length;
while( index < indexEnd ) {
img.data[index++] = value;
}
}
} /**
* 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, exclusive
*/
public static void fillUniform(ImageInt16 img, Random rand , int min , int max) {
int range = max-min;
short[] 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++] = (short)(rand.nextInt(range)+min);
}
}
}
/**
* 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, exclusive
*/
public static void fillUniform(InterleavedI16 img, Random rand , int min , int max) {
int range = max-min;
short[] data = img.data;
for (int y = 0; y < img.height; y++) {
int index = img.getStartIndex() + y * img.getStride();
int end = index + img.width*img.numBands;
for (; index < end; index++) {
data[index] = (short)(rand.nextInt(range)+min);
}
}
}
/**
* 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(ImageInt16 input, Random rand , double mean , double sigma , int lowerBound , int upperBound ) {
short[] 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++) {
int value = (int)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
data[index++] = (short)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(InterleavedI16 input, Random rand , double mean , double sigma , int lowerBound , int upperBound ) {
short[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (int)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
data[index++] = (short)value;
}
}
}
/**
* Flips the image from top to bottom
*/
public static void flipVertical( ImageInt16 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 ) {
int tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2++] = (short)tmp;
}
}
}
/**
* Flips the image from left to right
*/
public static void flipHorizontal( ImageInt16 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 ) {
int tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2--] = (short)tmp;
}
}
}
/**
* In-place 90 degree image rotation in the clockwise direction. Only works on
* square images.
*/
public static void rotateCW( ImageInt16 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
int tmp3 = image.data[index3];
image.data[index3] = image.data[index2];
image.data[index2] = image.data[index1];
image.data[index1] = image.data[index0];
image.data[index0] = (short)tmp3;
}
}
}
/**
* Rotates the image 90 degrees in the clockwise direction.
*/
public static void rotateCW( ImageInt16 input , ImageInt16 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int h = input.height-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(h-y,x,input.data[indexIn++]);
}
}
}
/**
* In-place 90 degree image rotation in the counter-clockwise direction. Only works on
* square images.
*/
public static void rotateCCW( ImageInt16 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
int tmp0 = image.data[index0];
image.data[index0] = image.data[index1];
image.data[index1] = image.data[index2];
image.data[index2] = image.data[index3];
image.data[index3] = (short)tmp0;
}
}
}
/**
* Rotates the image 90 degrees in the counter-clockwise direction.
*/
public static void rotateCCW( ImageInt16 input , ImageInt16 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int w = input.width-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(y,w-x,input.data[indexIn++]);
}
}
}
/**
* Copies a rectangular region from one image into another.
* output[dstX:(dstX+width) , dstY:(dstY+height-1)] = input[srcX:(srcX+width) , srcY:(srcY+height-1)]
*
* @param srcX x-coordinate of corner in input image
* @param srcY y-coordinate of corner in input image
* @param dstX x-coordinate of corner in output image
* @param dstY y-coordinate of corner in output image
* @param width Width of region to be copied
* @param height Height of region to be copied
* @param input Input image
* @param output output image
*/
public static void copy( int srcX , int srcY , int dstX , int dstY , int width , int height ,
ImageSInt32 input , ImageSInt32 output ) {
if( input.width < srcX+width || input.height < srcY+height )
throw new IllegalArgumentException("Copy region must be contained input image");
if( output.width < dstX+width || output.height < dstY+height )
throw new IllegalArgumentException("Copy region must be contained output image");
for (int y = 0; y < height; y++) {
int indexSrc = input.startIndex + (srcY + y) * input.stride + srcX;
int indexDst = output.startIndex + (dstY + y) * output.stride + dstX;
for (int x = 0; x < width; x++) {
output.data[indexDst++] = input.data[indexSrc++];
}
}
}
/**
* 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(ImageSInt32 input, int value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
input.data[index++] = value;
}
}
}
/**
* 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(InterleavedS32 input, int value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int end = index + input.width*input.numBands;
for (; index < end; index++ ) {
input.data[index] = value;
}
}
}
/**
* Fills each band in the image with the specified values
*
* @param input An image.
* @param values Array which contains the values each band is to be filled with.
*/
public static void fill(InterleavedS32 input, int[] values) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
for( int band = 0; band < numBands; band++ ) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
int value = values[band];
for (; index < end; index += numBands ) {
input.data[index] = value;
}
}
}
}
/**
* Fills one band in the image with the specified value
*
* @param input An image.
* @param band Which band is to be filled with the specified value
* @param value The value that the image is being filled with.
*/
public static void fillBand(InterleavedS32 input, int band , int value) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
for (; index < end; index += numBands ) {
input.data[index] = value;
}
}
}
/**
* Inserts a single band into into one of the bands in a multi-band image
*
* @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( ImageSInt32 input, int band , InterleavedS32 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];
}
}
}
/**
* Fills the outside border with the specified value
*
* @param input An image.
* @param value The value that the image is being filled with.
* @param radius Border width.
*/
public static void fillBorder(ImageSInt32 input, int value, int radius ) {
// top and bottom
for (int y = 0; y < radius; y++) {
int indexTop = input.startIndex + y * input.stride;
int indexBottom = input.startIndex + (input.height-y-1) * input.stride;
for (int x = 0; x < input.width; x++) {
input.data[indexTop++] = value;
input.data[indexBottom++] = value;
}
}
// left and right
int h = input.height-radius;
int indexStart = input.startIndex + radius*input.stride;
for (int x = 0; x < radius; x++) {
int indexLeft = indexStart + x;
int indexRight = indexStart + input.width-1-x;
for (int y = radius; y < h; y++) {
input.data[indexLeft] = value;
input.data[indexRight] = value;
indexLeft += input.stride;
indexRight += input.stride;
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(ImageSInt32 img, int value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
img.set(x, y, value);
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image. All bands
* are filled with the same value.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(InterleavedS32 img, int value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
int length = (x1-x0)*img.numBands;
for (int y = y0; y < y1; y++) {
int index = img.startIndex + y*img.stride + x0*img.numBands;
int indexEnd = index + length;
while( index < indexEnd ) {
img.data[index++] = value;
}
}
} /**
* 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, exclusive
*/
public static void fillUniform(ImageSInt32 img, Random rand , int min , int max) {
int range = max-min;
int[] 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.nextInt(range)+min);
}
}
}
/**
* 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, exclusive
*/
public static void fillUniform(InterleavedS32 img, Random rand , int min , int max) {
int range = max-min;
int[] data = img.data;
for (int y = 0; y < img.height; y++) {
int index = img.getStartIndex() + y * img.getStride();
int end = index + img.width*img.numBands;
for (; index < end; index++) {
data[index] = (rand.nextInt(range)+min);
}
}
}
/**
* 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(ImageSInt32 input, Random rand , double mean , double sigma , int lowerBound , int upperBound ) {
int[] 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++) {
int value = (int)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
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(InterleavedS32 input, Random rand , double mean , double sigma , int lowerBound , int upperBound ) {
int[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (int)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
data[index++] = value;
}
}
}
/**
* Flips the image from top to bottom
*/
public static void flipVertical( ImageSInt32 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 ) {
int tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2++] = (int)tmp;
}
}
}
/**
* Flips the image from left to right
*/
public static void flipHorizontal( ImageSInt32 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 ) {
int tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2--] = (int)tmp;
}
}
}
/**
* In-place 90 degree image rotation in the clockwise direction. Only works on
* square images.
*/
public static void rotateCW( ImageSInt32 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
int tmp3 = image.data[index3];
image.data[index3] = image.data[index2];
image.data[index2] = image.data[index1];
image.data[index1] = image.data[index0];
image.data[index0] = (int)tmp3;
}
}
}
/**
* Rotates the image 90 degrees in the clockwise direction.
*/
public static void rotateCW( ImageSInt32 input , ImageSInt32 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int h = input.height-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(h-y,x,input.data[indexIn++]);
}
}
}
/**
* In-place 90 degree image rotation in the counter-clockwise direction. Only works on
* square images.
*/
public static void rotateCCW( ImageSInt32 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
int tmp0 = image.data[index0];
image.data[index0] = image.data[index1];
image.data[index1] = image.data[index2];
image.data[index2] = image.data[index3];
image.data[index3] = (int)tmp0;
}
}
}
/**
* Rotates the image 90 degrees in the counter-clockwise direction.
*/
public static void rotateCCW( ImageSInt32 input , ImageSInt32 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int w = input.width-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(y,w-x,input.data[indexIn++]);
}
}
}
/**
* Copies a rectangular region from one image into another.
* output[dstX:(dstX+width) , dstY:(dstY+height-1)] = input[srcX:(srcX+width) , srcY:(srcY+height-1)]
*
* @param srcX x-coordinate of corner in input image
* @param srcY y-coordinate of corner in input image
* @param dstX x-coordinate of corner in output image
* @param dstY y-coordinate of corner in output image
* @param width Width of region to be copied
* @param height Height of region to be copied
* @param input Input image
* @param output output image
*/
public static void copy( int srcX , int srcY , int dstX , int dstY , int width , int height ,
ImageSInt64 input , ImageSInt64 output ) {
if( input.width < srcX+width || input.height < srcY+height )
throw new IllegalArgumentException("Copy region must be contained input image");
if( output.width < dstX+width || output.height < dstY+height )
throw new IllegalArgumentException("Copy region must be contained output image");
for (int y = 0; y < height; y++) {
int indexSrc = input.startIndex + (srcY + y) * input.stride + srcX;
int indexDst = output.startIndex + (dstY + y) * output.stride + dstX;
for (int x = 0; x < width; x++) {
output.data[indexDst++] = input.data[indexSrc++];
}
}
}
/**
* 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(ImageSInt64 input, long value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
input.data[index++] = value;
}
}
}
/**
* 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(InterleavedS64 input, long value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int end = index + input.width*input.numBands;
for (; index < end; index++ ) {
input.data[index] = value;
}
}
}
/**
* Fills each band in the image with the specified values
*
* @param input An image.
* @param values Array which contains the values each band is to be filled with.
*/
public static void fill(InterleavedS64 input, long[] values) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
for( int band = 0; band < numBands; band++ ) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
long value = values[band];
for (; index < end; index += numBands ) {
input.data[index] = value;
}
}
}
}
/**
* Fills one band in the image with the specified value
*
* @param input An image.
* @param band Which band is to be filled with the specified value
* @param value The value that the image is being filled with.
*/
public static void fillBand(InterleavedS64 input, int band , long value) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
for (; index < end; index += numBands ) {
input.data[index] = value;
}
}
}
/**
* Inserts a single band into into one of the bands in a multi-band image
*
* @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( ImageSInt64 input, int band , InterleavedS64 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];
}
}
}
/**
* Fills the outside border with the specified value
*
* @param input An image.
* @param value The value that the image is being filled with.
* @param radius Border width.
*/
public static void fillBorder(ImageSInt64 input, long value, int radius ) {
// top and bottom
for (int y = 0; y < radius; y++) {
int indexTop = input.startIndex + y * input.stride;
int indexBottom = input.startIndex + (input.height-y-1) * input.stride;
for (int x = 0; x < input.width; x++) {
input.data[indexTop++] = value;
input.data[indexBottom++] = value;
}
}
// left and right
int h = input.height-radius;
int indexStart = input.startIndex + radius*input.stride;
for (int x = 0; x < radius; x++) {
int indexLeft = indexStart + x;
int indexRight = indexStart + input.width-1-x;
for (int y = radius; y < h; y++) {
input.data[indexLeft] = value;
input.data[indexRight] = value;
indexLeft += input.stride;
indexRight += input.stride;
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(ImageSInt64 img, long value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
img.set(x, y, value);
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image. All bands
* are filled with the same value.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(InterleavedS64 img, long value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
int length = (x1-x0)*img.numBands;
for (int y = y0; y < y1; y++) {
int index = img.startIndex + y*img.stride + x0*img.numBands;
int indexEnd = index + length;
while( index < indexEnd ) {
img.data[index++] = value;
}
}
} /**
* 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, exclusive
*/
public static void fillUniform(ImageSInt64 img, Random rand , long min , long max) {
long range = max-min;
long[] 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.nextInt((int)range)+min;
}
}
}
/**
* 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, exclusive
*/
public static void fillUniform(InterleavedS64 img, Random rand , long min , long max) {
long range = max-min;
long[] data = img.data;
for (int y = 0; y < img.height; y++) {
int index = img.getStartIndex() + y * img.getStride();
int end = index + img.width*img.numBands;
for (; index < end; index++) {
data[index] = rand.nextInt((int)range)+min;
}
}
}
/**
* 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(ImageSInt64 input, Random rand , double mean , double sigma , long lowerBound , long upperBound ) {
long[] 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++) {
long value = (long)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
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(InterleavedS64 input, Random rand , double mean , double sigma , long lowerBound , long upperBound ) {
long[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
long value = (long)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
data[index++] = value;
}
}
}
/**
* Flips the image from top to bottom
*/
public static void flipVertical( ImageSInt64 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 ) {
long tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2++] = (long)tmp;
}
}
}
/**
* Flips the image from left to right
*/
public static void flipHorizontal( ImageSInt64 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 ) {
long tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2--] = (long)tmp;
}
}
}
/**
* In-place 90 degree image rotation in the clockwise direction. Only works on
* square images.
*/
public static void rotateCW( ImageSInt64 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
long tmp3 = image.data[index3];
image.data[index3] = image.data[index2];
image.data[index2] = image.data[index1];
image.data[index1] = image.data[index0];
image.data[index0] = (long)tmp3;
}
}
}
/**
* Rotates the image 90 degrees in the clockwise direction.
*/
public static void rotateCW( ImageSInt64 input , ImageSInt64 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int h = input.height-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(h-y,x,input.data[indexIn++]);
}
}
}
/**
* In-place 90 degree image rotation in the counter-clockwise direction. Only works on
* square images.
*/
public static void rotateCCW( ImageSInt64 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
long tmp0 = image.data[index0];
image.data[index0] = image.data[index1];
image.data[index1] = image.data[index2];
image.data[index2] = image.data[index3];
image.data[index3] = (long)tmp0;
}
}
}
/**
* Rotates the image 90 degrees in the counter-clockwise direction.
*/
public static void rotateCCW( ImageSInt64 input , ImageSInt64 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int w = input.width-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(y,w-x,input.data[indexIn++]);
}
}
}
/**
* Copies a rectangular region from one image into another.
* output[dstX:(dstX+width) , dstY:(dstY+height-1)] = input[srcX:(srcX+width) , srcY:(srcY+height-1)]
*
* @param srcX x-coordinate of corner in input image
* @param srcY y-coordinate of corner in input image
* @param dstX x-coordinate of corner in output image
* @param dstY y-coordinate of corner in output image
* @param width Width of region to be copied
* @param height Height of region to be copied
* @param input Input image
* @param output output image
*/
public static void copy( int srcX , int srcY , int dstX , int dstY , int width , int height ,
ImageFloat32 input , ImageFloat32 output ) {
if( input.width < srcX+width || input.height < srcY+height )
throw new IllegalArgumentException("Copy region must be contained input image");
if( output.width < dstX+width || output.height < dstY+height )
throw new IllegalArgumentException("Copy region must be contained output image");
for (int y = 0; y < height; y++) {
int indexSrc = input.startIndex + (srcY + y) * input.stride + srcX;
int indexDst = output.startIndex + (dstY + y) * output.stride + dstX;
for (int x = 0; x < width; x++) {
output.data[indexDst++] = input.data[indexSrc++];
}
}
}
/**
* 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(ImageFloat32 input, float value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
input.data[index++] = value;
}
}
}
/**
* 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(InterleavedF32 input, float value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int end = index + input.width*input.numBands;
for (; index < end; index++ ) {
input.data[index] = value;
}
}
}
/**
* Fills each band in the image with the specified values
*
* @param input An image.
* @param values Array which contains the values each band is to be filled with.
*/
public static void fill(InterleavedF32 input, float[] values) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
for( int band = 0; band < numBands; band++ ) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
float value = values[band];
for (; index < end; index += numBands ) {
input.data[index] = value;
}
}
}
}
/**
* Fills one band in the image with the specified value
*
* @param input An image.
* @param band Which band is to be filled with the specified value
* @param value The value that the image is being filled with.
*/
public static void fillBand(InterleavedF32 input, int band , float value) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
for (; index < end; index += numBands ) {
input.data[index] = value;
}
}
}
/**
* Inserts a single band into into one of the bands in a multi-band image
*
* @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( ImageFloat32 input, int band , InterleavedF32 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];
}
}
}
/**
* Fills the outside border with the specified value
*
* @param input An image.
* @param value The value that the image is being filled with.
* @param radius Border width.
*/
public static void fillBorder(ImageFloat32 input, float value, int radius ) {
// top and bottom
for (int y = 0; y < radius; y++) {
int indexTop = input.startIndex + y * input.stride;
int indexBottom = input.startIndex + (input.height-y-1) * input.stride;
for (int x = 0; x < input.width; x++) {
input.data[indexTop++] = value;
input.data[indexBottom++] = value;
}
}
// left and right
int h = input.height-radius;
int indexStart = input.startIndex + radius*input.stride;
for (int x = 0; x < radius; x++) {
int indexLeft = indexStart + x;
int indexRight = indexStart + input.width-1-x;
for (int y = radius; y < h; y++) {
input.data[indexLeft] = value;
input.data[indexRight] = value;
indexLeft += input.stride;
indexRight += input.stride;
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(ImageFloat32 img, float value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
img.set(x, y, value);
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image. All bands
* are filled with the same value.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(InterleavedF32 img, float value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
int length = (x1-x0)*img.numBands;
for (int y = y0; y < y1; y++) {
int index = img.startIndex + y*img.stride + x0*img.numBands;
int indexEnd = index + length;
while( index < indexEnd ) {
img.data[index++] = value;
}
}
} /**
* 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(ImageFloat32 img, Random rand , float min , float max) {
float range = max-min;
float[] 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.nextFloat()*range+min;
}
}
}
/**
* 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(InterleavedF32 img, Random rand , float min , float max) {
float range = max-min;
float[] data = img.data;
for (int y = 0; y < img.height; y++) {
int index = img.getStartIndex() + y * img.getStride();
int end = index + img.width*img.numBands;
for (; index < end; index++) {
data[index] = rand.nextFloat()*range+min;
}
}
}
/**
* 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(ImageFloat32 input, Random rand , double mean , double sigma , float lowerBound , float upperBound ) {
float[] 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++) {
float value = (float)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
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(InterleavedF32 input, Random rand , double mean , double sigma , float lowerBound , float upperBound ) {
float[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
float value = (float)(rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
data[index++] = value;
}
}
}
/**
* Flips the image from top to bottom
*/
public static void flipVertical( ImageFloat32 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 ) {
float tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2++] = (float)tmp;
}
}
}
/**
* Flips the image from left to right
*/
public static void flipHorizontal( ImageFloat32 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 ) {
float tmp = input.data[index1];
input.data[index1++] = input.data[index2];
input.data[index2--] = (float)tmp;
}
}
}
/**
* In-place 90 degree image rotation in the clockwise direction. Only works on
* square images.
*/
public static void rotateCW( ImageFloat32 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
float tmp3 = image.data[index3];
image.data[index3] = image.data[index2];
image.data[index2] = image.data[index1];
image.data[index1] = image.data[index0];
image.data[index0] = (float)tmp3;
}
}
}
/**
* Rotates the image 90 degrees in the clockwise direction.
*/
public static void rotateCW( ImageFloat32 input , ImageFloat32 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int h = input.height-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(h-y,x,input.data[indexIn++]);
}
}
}
/**
* In-place 90 degree image rotation in the counter-clockwise direction. Only works on
* square images.
*/
public static void rotateCCW( ImageFloat32 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
float tmp0 = image.data[index0];
image.data[index0] = image.data[index1];
image.data[index1] = image.data[index2];
image.data[index2] = image.data[index3];
image.data[index3] = (float)tmp0;
}
}
}
/**
* Rotates the image 90 degrees in the counter-clockwise direction.
*/
public static void rotateCCW( ImageFloat32 input , ImageFloat32 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int w = input.width-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(y,w-x,input.data[indexIn++]);
}
}
}
/**
* Copies a rectangular region from one image into another.
* output[dstX:(dstX+width) , dstY:(dstY+height-1)] = input[srcX:(srcX+width) , srcY:(srcY+height-1)]
*
* @param srcX x-coordinate of corner in input image
* @param srcY y-coordinate of corner in input image
* @param dstX x-coordinate of corner in output image
* @param dstY y-coordinate of corner in output image
* @param width Width of region to be copied
* @param height Height of region to be copied
* @param input Input image
* @param output output image
*/
public static void copy( int srcX , int srcY , int dstX , int dstY , int width , int height ,
ImageFloat64 input , ImageFloat64 output ) {
if( input.width < srcX+width || input.height < srcY+height )
throw new IllegalArgumentException("Copy region must be contained input image");
if( output.width < dstX+width || output.height < dstY+height )
throw new IllegalArgumentException("Copy region must be contained output image");
for (int y = 0; y < height; y++) {
int indexSrc = input.startIndex + (srcY + y) * input.stride + srcX;
int indexDst = output.startIndex + (dstY + y) * output.stride + dstX;
for (int x = 0; x < width; x++) {
output.data[indexDst++] = input.data[indexSrc++];
}
}
}
/**
* 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(ImageFloat64 input, double value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
input.data[index++] = value;
}
}
}
/**
* 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(InterleavedF64 input, double value) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int end = index + input.width*input.numBands;
for (; index < end; index++ ) {
input.data[index] = value;
}
}
}
/**
* Fills each band in the image with the specified values
*
* @param input An image.
* @param values Array which contains the values each band is to be filled with.
*/
public static void fill(InterleavedF64 input, double[] values) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
for( int band = 0; band < numBands; band++ ) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
double value = values[band];
for (; index < end; index += numBands ) {
input.data[index] = value;
}
}
}
}
/**
* Fills one band in the image with the specified value
*
* @param input An image.
* @param band Which band is to be filled with the specified value
* @param value The value that the image is being filled with.
*/
public static void fillBand(InterleavedF64 input, int band , double value) {
final int numBands = input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride() + band;
int end = index + input.width*numBands - band;
for (; index < end; index += numBands ) {
input.data[index] = value;
}
}
}
/**
* Inserts a single band into into one of the bands in a multi-band image
*
* @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( ImageFloat64 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];
}
}
}
/**
* Fills the outside border with the specified value
*
* @param input An image.
* @param value The value that the image is being filled with.
* @param radius Border width.
*/
public static void fillBorder(ImageFloat64 input, double value, int radius ) {
// top and bottom
for (int y = 0; y < radius; y++) {
int indexTop = input.startIndex + y * input.stride;
int indexBottom = input.startIndex + (input.height-y-1) * input.stride;
for (int x = 0; x < input.width; x++) {
input.data[indexTop++] = value;
input.data[indexBottom++] = value;
}
}
// left and right
int h = input.height-radius;
int indexStart = input.startIndex + radius*input.stride;
for (int x = 0; x < radius; x++) {
int indexLeft = indexStart + x;
int indexRight = indexStart + input.width-1-x;
for (int y = radius; y < h; y++) {
input.data[indexLeft] = value;
input.data[indexRight] = value;
indexLeft += input.stride;
indexRight += input.stride;
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(ImageFloat64 img, double value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
img.set(x, y, value);
}
}
}
/**
* Draws a filled rectangle that is aligned along the image axis inside the image. All bands
* are filled with the same value.
*
* @param img Image the rectangle is drawn in. Modified
* @param value Value of the rectangle
* @param x0 Top left x-coordinate
* @param y0 Top left y-coordinate
* @param width Rectangle width
* @param height Rectangle height
*/
public static void fillRectangle(InterleavedF64 img, double value, int x0, int y0, int width, int height) {
int x1 = x0 + width;
int y1 = y0 + height;
if( x0 < 0 ) x0 = 0; if( x1 > img.width ) x1 = img.width;
if( y0 < 0 ) y0 = 0; if( y1 > img.height ) y1 = img.height;
int length = (x1-x0)*img.numBands;
for (int y = y0; y < y1; y++) {
int index = img.startIndex + y*img.stride + x0*img.numBands;
int indexEnd = index + length;
while( index < indexEnd ) {
img.data[index++] = value;
}
}
} /**
* 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(ImageFloat64 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;
}
}
}
/**
* 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(InterleavedF64 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();
int end = index + img.width*img.numBands;
for (; index < end; index++) {
data[index] = rand.nextDouble()*range+min;
}
}
}
/**
* 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(ImageFloat64 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;
}
}
}
/**
* 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(InterleavedF64 input, Random rand , double mean , double sigma , double lowerBound , double upperBound ) {
double[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
double value = (rand.nextGaussian()*sigma+mean);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
data[index++] = value;
}
}
}
/**
* Flips the image from top to bottom
*/
public static void flipVertical( ImageFloat64 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;
}
}
}
/**
* Flips the image from left to right
*/
public static void flipHorizontal( ImageFloat64 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;
}
}
}
/**
* In-place 90 degree image rotation in the clockwise direction. Only works on
* square images.
*/
public static void rotateCW( ImageFloat64 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
double tmp3 = image.data[index3];
image.data[index3] = image.data[index2];
image.data[index2] = image.data[index1];
image.data[index1] = image.data[index0];
image.data[index0] = (double)tmp3;
}
}
}
/**
* Rotates the image 90 degrees in the clockwise direction.
*/
public static void rotateCW( ImageFloat64 input , ImageFloat64 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int h = input.height-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(h-y,x,input.data[indexIn++]);
}
}
}
/**
* In-place 90 degree image rotation in the counter-clockwise direction. Only works on
* square images.
*/
public static void rotateCCW( ImageFloat64 image ) {
if( image.width != image.height )
throw new IllegalArgumentException("Image must be square");
int w = image.height/2 + image.height%2;
int h = image.height/2;
for( int y0 = 0; y0 < h; y0++ ) {
int y1 = image.height-y0-1;
for( int x0 = 0; x0 < w; x0++ ) {
int x1 = image.width-x0-1;
int index0 = image.startIndex + y0*image.stride + x0;
int index1 = image.startIndex + x0*image.stride + y1;
int index2 = image.startIndex + y1*image.stride + x1;
int index3 = image.startIndex + x1*image.stride + y0;
double tmp0 = image.data[index0];
image.data[index0] = image.data[index1];
image.data[index1] = image.data[index2];
image.data[index2] = image.data[index3];
image.data[index3] = (double)tmp0;
}
}
}
/**
* Rotates the image 90 degrees in the counter-clockwise direction.
*/
public static void rotateCCW( ImageFloat64 input , ImageFloat64 output ) {
if( input.width != output.height || input.height != output.width )
throw new IllegalArgumentException("Incompatible shapes");
int w = input.width-1;
for( int y = 0; y < input.height; y++ ) {
int indexIn = input.startIndex + y*input.stride;
for (int x = 0; x < input.width; x++) {
output.unsafe_set(y,w-x,input.data[indexIn++]);
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(ImageUInt8 input, Random rand , int min , int max) {
int range = max-min;
byte[] 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++) {
int value = (data[index] & 0xFF) + rand.nextInt(range)+min;
if( value < 0 ) value = 0;
if( value > 255 ) value = 255;
data[index++] = (byte) value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(InterleavedU8 input, Random rand , int min , int max) {
int range = max-min;
byte[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (data[index] & 0xFF) + rand.nextInt(range)+min;
if( value < 0 ) value = 0;
if( value > 255 ) value = 255;
data[index++] = (byte) value;
}
}
}
/**
* 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(ImageUInt8 input, Random rand , double sigma , int lowerBound , int upperBound ) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
int value = (input.data[index] & 0xFF) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = (byte) value;
}
}
}
/**
* 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(InterleavedU8 input, Random rand , double sigma , int lowerBound , int upperBound ) {
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (input.data[index]& 0xFF) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = (byte)value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(ImageSInt8 input, Random rand , int min , int max) {
int range = max-min;
byte[] 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++) {
int value = (data[index] ) + rand.nextInt(range)+min;
if( value < -128 ) value = -128;
if( value > 127 ) value = 127;
data[index++] = (byte) value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(InterleavedS8 input, Random rand , int min , int max) {
int range = max-min;
byte[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (data[index] ) + rand.nextInt(range)+min;
if( value < -128 ) value = -128;
if( value > 127 ) value = 127;
data[index++] = (byte) value;
}
}
}
/**
* 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(ImageSInt8 input, Random rand , double sigma , int lowerBound , int upperBound ) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
int value = (input.data[index] ) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = (byte) value;
}
}
}
/**
* 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(InterleavedS8 input, Random rand , double sigma , int lowerBound , int upperBound ) {
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (input.data[index]) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = (byte)value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(ImageUInt16 input, Random rand , int min , int max) {
int range = max-min;
short[] 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++) {
int value = (data[index] & 0xFFFF) + rand.nextInt(range)+min;
if( value < 0 ) value = 0;
if( value > 65535 ) value = 65535;
data[index++] = (short) value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(InterleavedU16 input, Random rand , int min , int max) {
int range = max-min;
short[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (data[index] & 0xFFFF) + rand.nextInt(range)+min;
if( value < 0 ) value = 0;
if( value > 65535 ) value = 65535;
data[index++] = (short) value;
}
}
}
/**
* 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(ImageUInt16 input, Random rand , double sigma , int lowerBound , int upperBound ) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
int value = (input.data[index] & 0xFFFF) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = (short) value;
}
}
}
/**
* 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(InterleavedU16 input, Random rand , double sigma , int lowerBound , int upperBound ) {
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (input.data[index]& 0xFFFF) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = (short)value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(ImageSInt16 input, Random rand , int min , int max) {
int range = max-min;
short[] 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++) {
int value = (data[index] ) + rand.nextInt(range)+min;
if( value < -32768 ) value = -32768;
if( value > 32767 ) value = 32767;
data[index++] = (short) value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(InterleavedS16 input, Random rand , int min , int max) {
int range = max-min;
short[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (data[index] ) + rand.nextInt(range)+min;
if( value < -32768 ) value = -32768;
if( value > 32767 ) value = 32767;
data[index++] = (short) value;
}
}
}
/**
* 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(ImageSInt16 input, Random rand , double sigma , int lowerBound , int upperBound ) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
int value = (input.data[index] ) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = (short) value;
}
}
}
/**
* 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(InterleavedS16 input, Random rand , double sigma , int lowerBound , int upperBound ) {
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (input.data[index]) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = (short)value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(ImageSInt32 input, Random rand , int min , int max) {
int range = max-min;
int[] 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++) {
int value = (data[index] ) + rand.nextInt(range)+min;
data[index++] = value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(InterleavedS32 input, Random rand , int min , int max) {
int range = max-min;
int[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (data[index] ) + rand.nextInt(range)+min;
data[index++] = value;
}
}
}
/**
* 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(ImageSInt32 input, Random rand , double sigma , int lowerBound , int upperBound ) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
int value = (input.data[index] ) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = value;
}
}
}
/**
* 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(InterleavedS32 input, Random rand , double sigma , int lowerBound , int upperBound ) {
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
int value = (input.data[index]) + (int)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(ImageSInt64 input, Random rand , long min , long max) {
long range = max-min;
long[] 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++) {
long value = data[index] + rand.nextInt((int)range)+min;
data[index++] = value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(InterleavedS64 input, Random rand , long min , long max) {
long range = max-min;
long[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
long value = data[index] + rand.nextInt((int)range)+min;
data[index++] = value;
}
}
}
/**
* 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(ImageSInt64 input, Random rand , double sigma , long lowerBound , long upperBound ) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
long value = (input.data[index] ) + (long)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = value;
}
}
}
/**
* 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(InterleavedS64 input, Random rand , double sigma , long lowerBound , long upperBound ) {
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
long value = (input.data[index]) + (long)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(ImageFloat32 input, Random rand , float min , float max) {
float range = max-min;
float[] 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++) {
float value = data[index] + rand.nextFloat()*range+min;
data[index++] = value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(InterleavedF32 input, Random rand , float min , float max) {
float range = max-min;
float[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
float value = data[index] + rand.nextFloat()*range+min;
data[index++] = value;
}
}
}
/**
* 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(ImageFloat32 input, Random rand , double sigma , float lowerBound , float upperBound ) {
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
for (int x = 0; x < input.width; x++) {
float value = (input.data[index] ) + (float)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = value;
}
}
}
/**
* 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(InterleavedF32 input, Random rand , double sigma , float lowerBound , float upperBound ) {
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
float value = (input.data[index]) + (float)(rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = value;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(ImageFloat64 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;
}
}
}
/**
* Adds uniform i.i.d noise to each pixel in the image. Noise range is min ≤ X < max.
*/
public static void addUniform(InterleavedF64 input, Random rand , double min , double max) {
double range = max-min;
double[] data = input.data;
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
double value = data[index] + rand.nextDouble()*range+min;
data[index++] = value;
}
}
}
/**
* 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(ImageFloat64 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;
}
}
}
/**
* 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(InterleavedF64 input, Random rand , double sigma , double lowerBound , double upperBound ) {
int length = input.width*input.numBands;
for (int y = 0; y < input.height; y++) {
int index = input.getStartIndex() + y * input.getStride();
int indexEnd = index+length;
while( index < indexEnd ) {
double value = (input.data[index]) + (rand.nextGaussian()*sigma);
if( value < lowerBound ) value = lowerBound;
if( value > upperBound ) value = upperBound;
input.data[index++] = value;
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy