Performs a vertical 1D convolution of a box kernel across the image

@param input	 The original image. Not modified.
@param output	 Where the resulting image is written to. Modified.
@param radius Kernel size.
490179
public static void vertical(GrayS16 input, GrayI16 output, int radius, @Nullable IWorkArrays work) {
		InputSanityCheck.checkSameShape(input , output);

		Kernel1D_S32 kernel = FactoryKernel.table1D_I32(radius);
		ConvolveJustBorder_General_SB.vertical(kernel,ImageBorderValue.wrap(input,0),output);
		if(BoofConcurrency.USE_CONCURRENT ) {
			ImplConvolveBox_MT.vertical(input, output, radius, work);
		} else {
			ImplConvolveBox.vertical(input, output, radius, work);
		}
	}
171060
public static <T extends ImageGray<T>>
	void scaleImageUp(T input , T output , int scale, InterpolatePixelS<T> interp ) {
		if( scale <= 1 )
			throw new IllegalArgumentException("Scale must be >= 2");
		if( input instanceof GrayF32) {
			ImplPyramidOps.scaleImageUp((GrayF32)input,(GrayF32)output,scale,(InterpolatePixelS)interp);
		} else if( input instanceof GrayU8) {
			ImplPyramidOps.scaleImageUp((GrayU8)input,(GrayU8)output,scale,(InterpolatePixelS)interp);
		} else {
			throw new IllegalArgumentException("Image type not yet supported");
		}
	}
576425
public void process(Planar<T> input, Planar<T> output) {

		int N = input.getNumBands();
		for( int i = 0; i < N; i++ ) {
			this.output[i] = FactoryGImageGray.wrap(output.getBand(i),this.output[i]);
			interp[i].setImage(input.getBand(i));
		}

		int indexMap = 0;
		for( int i = 0; i < output.height; i++ ) {
			int indexOut = output.startIndex + i*output.stride;
			for( int j = 0; j < output.width; j++ , indexOut++,indexMap++ ) {
				Point2D_F32 p = mapPixels[indexMap];
				if( p != null ) {
					for( int k = 0; k < N; k++ ) {
						this.output[k].set(indexOut, interp[k].get( p.x, p.y));
					}
				}
			}
		}
	}
1353997
public static <T extends ImageGray<T>> void average(Planar<T> input, T output) {
		average(input, output, 0, input.getNumBands() - 1);
	}
1158312
private static void compute(Kernel kernel, int[] in, int[] out, int width, int height, boolean alpha, int edge)
    {
        final float[] matrix = kernel.getMatrix();
        final int cols = kernel.getWidth();
        final int cols2 = cols / 2;

        for (int y = 0; y < height; y++)
        {
            int index = y;
            final int ioffset = y * width;
            for (int x = 0; x < width; x++)
            {
                compute(matrix, in, out, x, index, ioffset, cols2, width, alpha, edge);
                index += height;
            }
        }
    }
902896
public void polyScale(GrowQueue_I8 input , int scale , GrowQueue_I8 output) {

		output.resize(input.size);

		for (int i = 0; i < input.size; i++) {
			output.data[i] = (byte)multiply(input.data[i]&0xFF, scale);
		}
	}
311631
private void initializeDerivatives(T input) {
		// reshape derivatives if the input image has changed size
		if (detector.getRequiresGradient() || detector.getRequiresHessian()) {
			derivX.reshape(input.width, input.height);
			derivY.reshape(input.width, input.height);
		}
		if (detector.getRequiresHessian()) {
			derivXX.reshape(input.width, input.height);
			derivYY.reshape(input.width, input.height);
			derivXY.reshape(input.width, input.height);
		}
	}
777607
public static void equalizeLocalNaive( GrayU8 input , int radius , GrayU8 output ,
										   IWorkArrays workArrays )
	{
		int width = 2*radius+1;
		int maxValue = workArrays.length()-1;

		//CONCURRENT_BELOW BoofConcurrency.loopBlocks(0,input.height,(idx0,idx1)->{
		int idx0 = 0, idx1 = input.height;
		int[] histogram = workArrays.pop();
		for( int y = idx0; y < idx1; y++ ) {
			// make sure it's inside the image bounds
			int y0 = y-radius;
			int y1 = y+radius+1;
			if( y0 < 0 ) {
				y0 = 0; y1 = width;
				if( y1 > input.height )
					y1 = input.height;
			} else if( y1 > input.height ) {
				y1 = input.height;
				y0 = y1 - width;
				if( y0 < 0 )
					y0 = 0;
			}

			// pixel indexes
			int indexIn = input.startIndex + y*input.stride;
			int indexOut = output.startIndex + y*output.stride;

			for( int x = 0; x < input.width; x++ ) {
				// make sure it's inside the image bounds
				int x0 = x-radius;
				int x1 = x+radius+1;
				if( x0 < 0 ) {
					x0 = 0; x1 = width;
					if( x1 > input.width )
						x1 = input.width;
				} else if( x1 > input.width ) {
					x1 = input.width;
					x0 = x1 - width;
					if( x0 < 0 )
						x0 = 0;
				}

				// compute the local histogram
				localHistogram(input,x0,y0,x1,y1,histogram);

				// only need to compute up to the value of the input pixel
				int inputValue =  input.data[indexIn++] & 0xFF;
				int sum = 0;
				for( int i = 0; i <= inputValue; i++ ) {
					sum += histogram[i];
				}

				int area = (y1-y0)*(x1-x0);
				output.data[indexOut++] = (byte)((sum*maxValue)/area);
			}
		}
		workArrays.recycle(histogram);
		//CONCURRENT_ABOVE });
	}
23420
public static void RGB_to_PLU8(Picture input, Planar<GrayU8> output) {
		if( input.getColor() != ColorSpace.RGB )
			throw new RuntimeException("Unexpected input color space!");
		if( output.getNumBands() != 3 )
			throw new RuntimeException("Unexpected number of bands in output image!");

		output.reshape(input.getWidth(),input.getHeight());

		int dataIn[] = input.getData()[0];

		GrayU8 out0 = output.getBand(0);
		GrayU8 out1 = output.getBand(1);
		GrayU8 out2 = output.getBand(2);

		int indexIn = 0;
		int indexOut = 0;
		for (int i = 0; i < output.height; i++) {
			for (int j = 0; j < output.width; j++, indexOut++ ) {
				int r = dataIn[indexIn++];
				int g = dataIn[indexIn++];
				int b = dataIn[indexIn++];

				out2.data[indexOut] = (byte)r;
				out1.data[indexOut] = (byte)g;
				out0.data[indexOut] = (byte)b;
			}
		}
	}
401229
public FDistort input( ImageBase input ) {
		if( this.input == null || this.input.width != input.width || this.input.height != input.height ) {
			distorter = null;
		}
		this.input = input;
		inputType = input.getImageType();
		return this;
	}
435605
@Override
	public void setInput( Input input ) {
		super.setInput(input);
		orientation.reshape(input.width,input.height);
		magnitude.reshape(input.width,input.height);

		computePixelFeatures();
	}
68863
public void process( T image1 , T image2 , ImageFlow output) {

		InputSanityCheck.checkSameShape(image1,image2);

		derivX.reshape(image1.width,image1.height);
		derivY.reshape(image1.width,image1.height);
		derivT.reshape(image1.width,image1.height);

		averageFlow.reshape(output.width,output.height);

		if( resetOutput )
			output.fillZero();

		computeDerivX(image1,image2,derivX);
		computeDerivY(image1,image2,derivY);
		computeDerivT(image1,image2,derivT);

		findFlow(derivX,derivY,derivT,output);
	}
19748
public static void imageToTensor(Planar<GrayF32> input , Tensor_F32 output , int miniBatch) {
		if( input.isSubimage())
			throw new RuntimeException("Subimages not accepted");
		if( output.getDimension() != 4 )
			throw new IllegalArgumentException("Output should be 4-DOF.  batch + spatial (channel,height,width)");
		if( output.length(1) != input.getNumBands() )
			throw new IllegalArgumentException("Number of bands don't match");
		if( output.length(2) != input.getHeight() )
			throw new IllegalArgumentException("Spatial height doesn't match");
		if( output.length(3) != input.getWidth() )
			throw new IllegalArgumentException("Spatial width doesn't match");

		for (int i = 0; i < input.getNumBands(); i++) {
			GrayF32 band = input.getBand(i);
			int indexOut = output.idx(miniBatch,i,0,0);

			int length = input.width*input.height;
			System.arraycopy(band.data, 0,output.d,indexOut,length);
		}
	}
278960
public static void convolve(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) {
		if (kernel.getHeight() == 1)
			convolveH(kernel, inPixels, outPixels, width, height, alpha, edgeAction);
		else if (kernel.getWidth() == 1)
			convolveV(kernel, inPixels, outPixels, width, height, alpha, edgeAction);
		else
			convolveHV(kernel, inPixels, outPixels, width, height, alpha, edgeAction);
	}
521159
public static void applyBoxFilter( GrayF32 input ) {

		// declare storage
		GrayF32 boxImage = new GrayF32(input.width, input.height);
		InterleavedF32 boxTransform = new InterleavedF32(input.width,input.height,2);
		InterleavedF32 transform = new InterleavedF32(input.width,input.height,2);
		GrayF32 blurredImage = new GrayF32(input.width, input.height);
		GrayF32 spatialBlur = new GrayF32(input.width, input.height);

		DiscreteFourierTransform<GrayF32,InterleavedF32> dft =
				DiscreteFourierTransformOps.createTransformF32();


		// Make the image scaled from 0 to 1 to reduce overflow issues
		PixelMath.divide(input,255.0f,input);

		// compute the Fourier Transform
		dft.forward(input,transform);

		// create the box filter which is centered around the pixel.  Note that the filter gets wrapped around
		// the image edges
		for( int y = 0; y < 15; y++ ) {
			int yy = y-7 < 0 ? boxImage.height+(y-7) : y - 7;
			for( int x = 0; x < 15; x++ ) {
				int xx = x-7 < 0 ? boxImage.width+(x-7) : x - 7;
				// Set the value such that it doesn't change the image intensity
				boxImage.set(xx,yy,1.0f/(15*15));
			}
		}

		// compute the DFT for the box filter
		dft.forward(boxImage,boxTransform);

		// Visualize the Fourier Transform for the input image and the box filter
		displayTransform(transform,"Input Image");
		displayTransform(boxTransform,"Box Filter");

		// apply the filter. convolution in spacial domain is the same as multiplication in the frequency domain
		DiscreteFourierTransformOps.multiplyComplex(transform,boxTransform,transform);

		// convert the image back and display the results
		dft.inverse(transform,blurredImage);
		// undo change of scale
		PixelMath.multiply(blurredImage,255.0f,blurredImage);
		PixelMath.multiply(input,255.0f,input);

		// For sake of comparison, let's compute the box blur filter in the spatial domain
		// NOTE: The image border will be different since the frequency domain wraps around and this implementation
		// of the spacial domain adapts the kernel size
		BlurImageOps.mean(input,spatialBlur,7,null,null);

		// Convert to BufferedImage for output
		BufferedImage originOut = ConvertBufferedImage.convertTo(input, null);
		BufferedImage spacialOut = ConvertBufferedImage.convertTo(spatialBlur, null);
		BufferedImage blurredOut = ConvertBufferedImage.convertTo(blurredImage, null);

		ListDisplayPanel listPanel = new ListDisplayPanel();
		listPanel.addImage(originOut,"Original Image");
		listPanel.addImage(spacialOut,"Spacial Domain Box");
		listPanel.addImage(blurredOut,"Frequency Domain Box");

		ShowImages.showWindow(listPanel,"Box Blur in Spacial and Frequency Domain of Input Image");
	}
5560
public static void vertical(Kernel1D_S32 kernel, InterleavedU16 src, InterleavedI16 dst ) {
		InputSanityCheck.checkSameShapeB(src, dst);

		boolean processed = BOverrideConvolveImageNormalized.invokeNativeVertical(kernel,src,dst);
		
		if( !processed ) {
			if( kernel.width >= src.height ) {
				ConvolveNormalizedNaive_IL.vertical(kernel, src, dst);
			} else {
				ConvolveImageNoBorder.vertical(kernel, src, dst, kernel.computeSum());
				ConvolveNormalized_JustBorder_IL.vertical(kernel, src, dst);
			}
		}
	}
900709
public static void grayToBitmap( GrayU8 input , Bitmap output , byte[] storage) {
		if( output.getWidth() != input.getWidth() || output.getHeight() != input.getHeight() ) {
			throw new IllegalArgumentException("Image shapes are not the same");
		}
		
		if( storage == null )
			storage = declareStorage(output,null);
		
		ImplConvertBitmap.grayToArray(input, storage,output.getConfig());
		output.copyPixelsFromBuffer(ByteBuffer.wrap(storage));
	}