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

boofcv.struct.flow.ImageFlow Maven / Gradle / Ivy

/*
 * Copyright (c) 2011-2014, 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.struct.flow;

/**
 * The dense optical flow of an image.  Each pixel contains a data structure that indicates optical flow at the pixel
 * and if the optical flow could be found.
 *
 * @author Peter Abeles
 */
public class ImageFlow {
	// image dimension
	public int width,height;

	// storage for flow information
	public D data[] = new D[0];

	public ImageFlow(int width, int height) {
		reshape(width,height);
	}

	/**
	 * Changes the shape to match the specified dimension. Memory will only be created/destroyed if the requested
	 * size is larger than any previously requested size
	 * @param width New image width
	 * @param height new image height
	 */
	public void reshape( int width , int height ) {
		int N = width*height;

		if( data.length < N ) {
			D tmp[] = new D[N];
			System.arraycopy(data,0,tmp,0,data.length);
			for( int i = data.length; i < N; i++ )
				tmp[i] = new D();
			data = tmp;
		}
		this.width = width;
		this.height = height;
	}

	/**
	 * Marks all pixels as having an invalid flow
	 */
	public void invalidateAll() {
		int N = width*height;
		for( int i = 0; i < N; i++ )
			data[i].x = Float.NaN;
	}

	public void fillZero() {
		int N = width*height;
		for( int i = 0; i < N; i++ ) {
			D d = data[i];
			d.x = d.y = 0;
		}
	}

	public D get( int x , int y ) {
		if( !isInBounds(x,y))
			throw new IllegalArgumentException("Requested pixel is out of bounds: "+x+" "+y);

		return data[y*width+x];
	}

	public D unsafe_get( int x , int y ) {
		return data[y*width+x];
	}

	public final boolean isInBounds(int x, int y) {
		return x >= 0 && x < width && y >= 0 && y < height;
	}

	public int getWidth() {
		return width;
	}

	public int getHeight() {
		return height;
	}

	public void setTo( ImageFlow flow ) {
		int N = width*height;
		for( int i = 0; i < N; i++ ) {
			data[i].set( flow.data[i] );
		}
	}

	/**
	 * Specifies the optical flow for a single pixel.  Pixels for which no optical flow could be found are marked
	 * by setting x to Float.NaN.
	 */
	public static class D
	{
		/**
		 * Optical flow.  If no valid flow could be found then x = Float.NaN
		 */
		public float x,y;

		public void set( D d ) {
			this.x = d.x;
			this.y = d.y;
		}

		public void set( float x , float y ) {
			this.x = x;
			this.y = y;
		}

		public void markInvalid() {
			x = Float.NaN;
		}

		public float getX() {
			return x;
		}

		public float getY() {
			return y;
		}

		public boolean isValid() {
			return !Float.isNaN(x);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy