All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.alg.flow.UtilDenseOpticalFlow Maven / Gradle / Ivy

/*
 * 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.flow;

import boofcv.alg.interpolate.InterpolatePixelS;
import boofcv.alg.transform.pyramid.PyramidFloatGaussianScale;
import boofcv.alg.transform.pyramid.PyramidFloatScale;
import boofcv.core.image.border.BorderType;
import boofcv.factory.interpolate.FactoryInterpolation;
import boofcv.struct.image.ImageGray;
import boofcv.struct.pyramid.PyramidFloat;

/**
 * Useful functions when computing dense optical flow
 *
 * @author Peter Abeles
 */
public class UtilDenseOpticalFlow {

	/**
	 * 

* Create a standard image pyramid used by dense optical flow parameters. The first layer is the size * of the input image and the last layer is ≥ the minSize. The sigma for each layer is computed * using the following formula:
*
* sigmaLayer = sigma*sqrt( scale^-2 - 1 ) *

* *

* If the scale is 1 then a single layer pyramid will be created. If the scale is 0 then the scale will * be determined by the maxLayers parameter. *

* * @param width Width of input image. * @param height Height of input image. * @param scale Scale between layers. 0 ≤ scale ≤ 1. Try 0.7 * @param sigma Adjusts the amount of blur applied to each layer. If sigma ≤ 0 then no blur is applied. * @param minSize The minimum desired image size in the pyramid * @param maxLayers The maximum number of layers in the pyramid. * @param imageType Type of image for each layer * @param Image type * @return The image pyramid. */ public static PyramidFloat standardPyramid( int width , int height , double scale, double sigma , int minSize, int maxLayers , Class imageType ) { if( scale > 1.0 || scale < 0 ) throw new IllegalArgumentException("Scale must be 0 <= scale <= 1"); int numScales; if( scale == 1 || maxLayers == 1 ) { numScales = 1; } else if ( scale == 0 ) { numScales = maxLayers; double desiredReduction = minSize/(double)Math.min(width,height); scale = Math.pow(desiredReduction,1.0/(numScales-1)); } else { // this is how much the input image needs to be shrunk double desiredReduction = minSize/(double)Math.min(width,height); // number the number of frames needed and round to the nearest integer numScales = (int)(Math.log(desiredReduction)/Math.log(scale) + 0.5); if( numScales > maxLayers ) numScales = maxLayers; // compute a new scale factor using this number of scales scale = Math.pow(desiredReduction,1.0/numScales); // add one since the first scale is going to be the original image numScales++; } InterpolatePixelS interp = FactoryInterpolation.bilinearPixelS(imageType, BorderType.EXTENDED); if( sigma > 0 ) { double layerSigma = sigma*Math.sqrt(Math.pow(scale,-2)-1); double scaleFactors[] = new double[ numScales ]; double scaleSigmas[] = new double[ numScales ]; scaleFactors[0] = 1; scaleSigmas[0] = layerSigma; for( int i = 1; i < numScales; i++ ) { scaleFactors[i] = scaleFactors[i-1]/scale; scaleSigmas[i] = layerSigma; } return new PyramidFloatGaussianScale<>(interp, scaleFactors, scaleSigmas, imageType); } else { double scaleFactors[] = new double[ numScales ]; scaleFactors[0] = 1; for( int i = 1; i < numScales; i++ ) { scaleFactors[i] = scaleFactors[i-1]/scale; } return new PyramidFloatScale<>(interp, scaleFactors, imageType); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy