boofcv.alg.flow.UtilDenseOpticalFlow Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boofcv-feature Show documentation
Show all versions of boofcv-feature Show documentation
BoofCV is an open source Java library for real-time computer vision and robotics applications.
/*
* Copyright (c) 2011-2019, 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.factory.interpolate.FactoryInterpolation;
import boofcv.struct.border.BorderType;
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 - 2025 Weber Informatics LLC | Privacy Policy