/*
 * Copyright (c) 2011-2016, 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.filter.misc;

import boofcv.struct.image.*;

/**
 * 

* Operations related to down sampling image by computing the average within square regions. The first square region is * from (0,0) to * (w-1,w-1), inclusive. Each square region after that is found by skipping over 'w' pixels in x and y directions. * partial regions along the right and bottom borders are handled by computing the average with the rectangle defined * by the intersection of the image and the square region. *

* *

* NOTE: Errors are reduced in integer images by rounding instead of standard integer division. *

* * * @author Peter Abeles */ public class AverageDownSampleOps { /** * Computes the length of a down sampled image based on the original length and the square width * @param length Length of side in input image * @param squareWidth Width of region used to down sample images * @return Length of side in down sampled image */ public static int downSampleSize( int length , int squareWidth ) { int ret = length/squareWidth; if( length%squareWidth != 0 ) ret++; return ret; } /** * Reshapes an image so that it is the correct size to store the down sampled image */ public static void reshapeDown(ImageBase image, int inputWidth, int inputHeight, int squareWidth) { int w = downSampleSize(inputWidth,squareWidth); int h = downSampleSize(inputHeight,squareWidth); image.reshape(w,h); } /** * Down samples image. Type checking is done at runtime. * * @param input Input image. Not modified. * @param sampleWidth Width of square region. * @param output Output image. Modified. */ public static void down(ImageGray input , int sampleWidth , ImageGray output ) { if( sampleWidth == 2 ) { if( input instanceof GrayU8) { ImplAverageDownSample2.down((GrayU8) input, (GrayI8) output); } else if( input instanceof GrayS8) { ImplAverageDownSample2.down((GrayS8) input, (GrayI8) output); } else if( input instanceof GrayU16) { ImplAverageDownSample2.down((GrayU16) input, (GrayI16) output); } else if( input instanceof GrayS16) { ImplAverageDownSample2.down((GrayS16) input, (GrayI16) output); } else if( input instanceof GrayS32) { ImplAverageDownSample2.down((GrayS32) input, (GrayS32) output); } else if( input instanceof GrayF32) { ImplAverageDownSample2.down((GrayF32) input, (GrayF32) output); } else if( input instanceof GrayF64) { ImplAverageDownSample2.down((GrayF64) input, (GrayF64) output); } else { throw new IllegalArgumentException("Unknown image type"); } } else { if( input instanceof GrayU8) { ImplAverageDownSampleN.down((GrayU8) input, sampleWidth , (GrayI8) output); } else if( input instanceof GrayS8) { ImplAverageDownSampleN.down((GrayS8) input, sampleWidth , (GrayI8) output); } else if( input instanceof GrayU16) { ImplAverageDownSampleN.down((GrayU16) input, sampleWidth , (GrayI16) output); } else if( input instanceof GrayS16) { ImplAverageDownSampleN.down((GrayS16) input, sampleWidth , (GrayI16) output); } else if( input instanceof GrayS32) { ImplAverageDownSampleN.down((GrayS32) input, sampleWidth , (GrayS32) output); } else if( input instanceof GrayF32) { ImplAverageDownSampleN.down((GrayF32) input, sampleWidth , (GrayF32) output); } else if( input instanceof GrayF64) { ImplAverageDownSampleN.down((GrayF64) input, sampleWidth , (GrayF64) output); } else { throw new IllegalArgumentException("Unknown image type"); } } } /** * Down samples image. Type checking is done at runtime. * * @param input Input image. Not modified. * @param output Output image. Modified. */ public static void down( T input , T output ) { if( ImageGray.class.isAssignableFrom(input.getClass()) ) { if (input instanceof GrayU8) { GrayF32 middle = new GrayF32(output.width, input.height); ImplAverageDownSample.horizontal((GrayU8) input, middle); ImplAverageDownSample.vertical(middle, (GrayI8) output); } else if (input instanceof GrayU16) { GrayF32 middle = new GrayF32(output.width, input.height); ImplAverageDownSample.horizontal((GrayU16) input, middle); ImplAverageDownSample.vertical(middle, (GrayU16) output); } else if (input instanceof GrayF32) { GrayF32 middle = new GrayF32(output.width, input.height); ImplAverageDownSample.horizontal((GrayF32) input, middle); ImplAverageDownSample.vertical(middle, (GrayF32) output); } else if (input instanceof GrayF64) { GrayF64 middle = new GrayF64(output.width, input.height); ImplAverageDownSample.horizontal((GrayF64) input, middle); ImplAverageDownSample.vertical(middle, (GrayF64) output); } else { throw new IllegalArgumentException("Unknown image type"); } } else if( Planar.class.isAssignableFrom(input.getClass()) ) { Planar in = (Planar)input; Planar out = (Planar)output; int N = in.getNumBands(); for (int i = 0; i < N; i++) { down(in.getBand(i),out.getBand(i)); } } } /** * Down samples a planar image. Type checking is done at runtime. * * @param input Input image. Not modified. * @param sampleWidth Width of square region. * @param output Output image. Modified. */ public static void down(Planar input , int sampleWidth , Planar output ) { for( int band = 0; band < input.getNumBands(); band++ ) { down(input.getBand(band), sampleWidth, output.getBand(band)); } } /** * Down samples a planar image. Type checking is done at runtime. * * @param input Input image. Not modified. * @param output Output image. Modified. */ public static void down(Planar input , Planar output ) { for( int band = 0; band < input.getNumBands(); band++ ) { down(input.getBand(band), output.getBand(band)); } } /** * Down samples the image. * * @param input Input image. Not modified. * @param sampleWidth Width of square region. * @param output Output image. Modified. */ public static void down(GrayU8 input , int sampleWidth , GrayI8 output ) { if( sampleWidth == 2 ) { ImplAverageDownSample2.down( input, output); } else { ImplAverageDownSampleN.down (input, sampleWidth , output); } } /** * Down samples the image. * * @param input Input image. Not modified. * @param sampleWidth Width of square region. * @param output Output image. Modified. */ public static void down(GrayS8 input , int sampleWidth , GrayI8 output ) { if( sampleWidth == 2 ) { ImplAverageDownSample2.down( input, output); } else { ImplAverageDownSampleN.down( input, sampleWidth , output); } } /** * Down samples the image. * * @param input Input image. Not modified. * @param sampleWidth Width of square region. * @param output Output image. Modified. */ public static void down(GrayU16 input , int sampleWidth , GrayI16 output ) { if( sampleWidth == 2 ) { ImplAverageDownSample2.down( input, output); } else { ImplAverageDownSampleN.down( input, sampleWidth , output); } } /** * Down samples the image. * * @param input Input image. Not modified. * @param sampleWidth Width of square region. * @param output Output image. Modified. */ public static void down(GrayS16 input , int sampleWidth , GrayI16 output ) { if( sampleWidth == 2 ) { ImplAverageDownSample2.down( input, output); } else { ImplAverageDownSampleN.down( input, sampleWidth , output); } } /** * Down samples the image. * * @param input Input image. Not modified. * @param sampleWidth Width of square region. * @param output Output image. Modified. */ public static void down(GrayS32 input , int sampleWidth , GrayS32 output ) { if( sampleWidth == 2 ) { ImplAverageDownSample2.down( input, output); } else { ImplAverageDownSampleN.down( input, sampleWidth , output); } } /** * Down samples the image. * * @param input Input image. Not modified. * @param sampleWidth Width of square region. * @param output Output image. Modified. */ public static void down(GrayF32 input , int sampleWidth , GrayF32 output ) { if( sampleWidth == 2 ) { ImplAverageDownSample2.down( input, output); } else { ImplAverageDownSampleN.down( input, sampleWidth , output); } } /** * Down samples the image. * * @param input Input image. Not modified. * @param sampleWidth Width of square region. * @param output Output image. Modified. */ public static void down(GrayF64 input , int sampleWidth , GrayF64 output ) { if( sampleWidth == 2 ) { ImplAverageDownSample2.down( input, output); } else { ImplAverageDownSampleN.down( input, sampleWidth , output); } } }

Ads help maintain this website.