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

boofcv.alg.fiducial.calib.chess.ChessboardCornerGraph Maven / Gradle / Ivy

/*
 * Copyright (c) 2021, 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.fiducial.calib.chess;

import boofcv.alg.feature.detect.chess.ChessboardCorner;
import boofcv.core.graph.FeatureGraph2D;
import org.ddogleg.struct.DogArray;
import org.jetbrains.annotations.Nullable;

import java.util.List;

/**
 * A graph describing the inner corners in a chessboard patterns. Each node is a corner. A node can have 4 edges that
 * represent the 4 cardinal directions. Edges are directed. orientation refers to the corner's orientation
 * which has a range of 180 degrees or -pi/2 to pi/2
 *
 * @author Peter Abeles
 */
public class ChessboardCornerGraph {

	public DogArray corners = new DogArray<>(Node::new);

	/**
	 * Convert into a generic graph.
	 */
	public void convert( FeatureGraph2D graph ) {
		graph.nodes.resize(corners.size);
		graph.reset();
		for (int i = 0; i < corners.size; i++) {
			Node c = corners.get(i);
			FeatureGraph2D.Node n = graph.nodes.grow();
			n.reset();
			n.setTo(c.corner.x, c.corner.y);
			n.index = c.index;
		}

		for (int i = 0; i < corners.size; i++) {
			Node c = corners.get(i);
			for (int j = 0; j < 4; j++) {
				if (c.edges[j] == null)
					continue;
				graph.connect(c.index, c.edges[j].index);
			}
		}
	}

	public Node growCorner() {
		Node n = corners.grow();
		n.reset();
		n.index = corners.size - 1;
		return n;
	}

	public @Nullable Node findClosest( double x, double y ) {
		double distance = Double.MAX_VALUE;
		Node closest = null;
		for (int i = 0; i < corners.size; i++) {
			Node n = corners.get(i);
			double d = n.corner.distance2(x, y);
			if (d < distance) {
				distance = d;
				closest = n;
			}
		}

		return closest;
	}

	public void print() {
		for (int cornerIdx = 0; cornerIdx < corners.size; cornerIdx++) {
			Node n = corners.get(cornerIdx);
			System.out.printf("[%3d] {%3.0f, %3.0f} -> ", n.index, n.corner.x, n.corner.y);
			for (int i = 0; i < 4; i++) {
				if (n.edges[i] == null) {
					System.out.print("[    ] ");
				} else {
					System.out.printf("[ %2d ] ", n.edges[i].index);
				}
			}
			System.out.println();
		}
	}

	public void reset() {
		corners.reset();
	}

	@SuppressWarnings({"NullAway.Init"})
	public static class Node {
		/**
		 * Index in the node list
		 */
		public int index;
		/**
		 * Reference to the corner this node came from.
		 */
		public ChessboardCorner corner;
		/**
		 * References to other corners. Can only be connected to 4 corners in directions approximated 90 degrees apart.
		 */
		public final Node[] edges = new Node[4];

		public double getX() {return corner.x;}

		public double getY() {return corner.y;}

		public double getOrientation() {return corner.orientation;}

		/**
		 * Iterates through edges until it encounters edge 'count'
		 */
		public void putEdgesIntoList( List found ) {
			found.clear();
			for (int i = 0; i < 4; i++) {
				if (edges[i] != null) {
					found.add(edges[i]);
				}
			}
		}

		/**
		 * Rotate edges down in the array.
		 */
		public void rotateEdgesDown() {
			Node tmp = edges[0];
			for (int i = 1; i < 4; i++) {
				edges[i - 1] = edges[i];
			}
			edges[3] = tmp;
		}

		@SuppressWarnings("NullAway")
		public void reset() {
			index = -1;
			corner = null;
			for (int i = 0; i < 4; i++) {
				edges[i] = null;
			}
		}

		public int countEdges() {
			int total = 0;

			for (int i = 0; i < 4; i++) {
				if (edges[i] != null)
					total++;
			}

			return total;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy