<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://boofcv.org/index.php?action=history&amp;feed=atom&amp;title=ExampleTrifocalTensorUses</id>
	<title>ExampleTrifocalTensorUses - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://boofcv.org/index.php?action=history&amp;feed=atom&amp;title=ExampleTrifocalTensorUses"/>
	<link rel="alternate" type="text/html" href="https://boofcv.org/index.php?title=ExampleTrifocalTensorUses&amp;action=history"/>
	<updated>2026-05-08T05:43:05Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.36.2</generator>
	<entry>
		<id>https://boofcv.org/index.php?title=ExampleTrifocalTensorUses&amp;diff=2960&amp;oldid=prev</id>
		<title>Peter: Created page with &quot;Shows how to compute a trifocal tensor after it has been computed. Trifocal tensors compactly represent 3-view geometry and just computing them will remove many outliers which...&quot;</title>
		<link rel="alternate" type="text/html" href="https://boofcv.org/index.php?title=ExampleTrifocalTensorUses&amp;diff=2960&amp;oldid=prev"/>
		<updated>2021-07-12T20:03:18Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;Shows how to compute a trifocal tensor after it has been computed. Trifocal tensors compactly represent 3-view geometry and just computing them will remove many outliers which...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Shows how to compute a trifocal tensor after it has been computed. Trifocal tensors compactly represent 3-view geometry and just computing them will remove many outliers which made their way through robust 2-view tests. Once known they can be used to predict the locations of points in different views and when decomposed can be used to easily create consistent projective reconstructions.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example Code:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.38/examples/src/main/java/boofcv/examples/sfm/ExampleTrifocalTensorUses.java ExampleTrifocalTensorUses.java]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Concepts:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Three view geometry&lt;br /&gt;
* Reconstruction&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Related Examples:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* [[ExampleComputeTrifocalTensor| Computing Trifocal Tensor]]&lt;br /&gt;
* [[Example_Multiview_Uncalibrated_Reconstruction_Sparse| Scene Reconstruction]]&lt;br /&gt;
&lt;br /&gt;
= Example Code =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Shows a few example uses of the trifocal tensor.&lt;br /&gt;
 */&lt;br /&gt;
public class ExampleTrifocalTensorUses {&lt;br /&gt;
	public static void main( String[] args ) {&lt;br /&gt;
		// Load three images/views&lt;br /&gt;
		String name = &amp;quot;rock_leaves_&amp;quot;;&lt;br /&gt;
		GrayU8 gray01 = UtilImageIO.loadImage(UtilIO.pathExample(&amp;quot;triple/&amp;quot; + name + &amp;quot;01.jpg&amp;quot;), GrayU8.class);&lt;br /&gt;
		GrayU8 gray02 = UtilImageIO.loadImage(UtilIO.pathExample(&amp;quot;triple/&amp;quot; + name + &amp;quot;02.jpg&amp;quot;), GrayU8.class);&lt;br /&gt;
		GrayU8 gray03 = UtilImageIO.loadImage(UtilIO.pathExample(&amp;quot;triple/&amp;quot; + name + &amp;quot;03.jpg&amp;quot;), GrayU8.class);&lt;br /&gt;
&lt;br /&gt;
		// Get the trifocal tensor for these three images&lt;br /&gt;
		var tensor = new TrifocalTensor();&lt;br /&gt;
		List&amp;lt;AssociatedTriple&amp;gt; inliers = ExampleComputeTrifocalTensor.imagesToTrifocal(gray01, gray02, gray03, tensor);&lt;br /&gt;
		// The inlier set from robustly fitting a trifocal tensor is one of its more helpful uses.&lt;br /&gt;
		// It has fewer degenerate situations than a straight forward application of fundamental/essential matrices.&lt;br /&gt;
		// Unlike with two views where you find the distance from the epipolar line, if you use three views there is&lt;br /&gt;
		// a unique pixel in each view and that will improve the efficiency of many SFM applications. Yes, if you&lt;br /&gt;
		// know what you are doing it&amp;#039;s possible to use multiple stereo pairs. However, most people do that incorrectly&lt;br /&gt;
		// which will yield worse results.&lt;br /&gt;
&lt;br /&gt;
		// Trifocal tensor to 3 compatible camera matrices&lt;br /&gt;
		// Camera matrix for view-1, P1, is going to be identity&lt;br /&gt;
		DMatrixRMaj P2 = new DMatrixRMaj(3, 4);&lt;br /&gt;
		DMatrixRMaj P3 = new DMatrixRMaj(3, 4);&lt;br /&gt;
		MultiViewOps.trifocalToCameraMatrices(tensor, P2, P3);&lt;br /&gt;
		// These camera matrices are useful if doing a projective reconstruction.&lt;br /&gt;
&lt;br /&gt;
		// One thing that you can do with a trifocal tensor is transfer points from one view onto another&lt;br /&gt;
		// Similar to what you would do with a homography.&lt;br /&gt;
		AssociatedTriple match = inliers.get(4);&lt;br /&gt;
		Point3D_F64 predicted3 = new Point3D_F64(); // pixel, but in homogenous coordinates&lt;br /&gt;
		MultiViewOps.transfer_1_to_3(tensor, match.p1, match.p2, predicted3);&lt;br /&gt;
&lt;br /&gt;
		System.out.printf(&amp;quot;Predicted x3=(%.1f, %.1f)  actual=(%.1f, %.1f)\n&amp;quot;,&lt;br /&gt;
				predicted3.x/predicted3.z, predicted3.y/predicted3.z, match.p3.x, match.p3.y);&lt;br /&gt;
&lt;br /&gt;
		// You can get two fundamental matrices from the trifocal tensor&lt;br /&gt;
		DMatrixRMaj F21 = new DMatrixRMaj(3, 3);&lt;br /&gt;
		DMatrixRMaj F31 = new DMatrixRMaj(3, 3);&lt;br /&gt;
		MultiViewOps.trifocalToFundamental(tensor, F21, F31);&lt;br /&gt;
&lt;br /&gt;
		// Scale is arbitrary so let&amp;#039;s make it norm of 1&lt;br /&gt;
		CommonOps_DDRM.divide(F21, NormOps_DDRM.normF(F21));&lt;br /&gt;
		CommonOps_DDRM.divide(F31, NormOps_DDRM.normF(F31));&lt;br /&gt;
&lt;br /&gt;
		// Demonstration the epipolar constraint works here. This should be close to zero&lt;br /&gt;
		System.out.println(&amp;quot;x2&amp;#039;*F21*X1 = &amp;quot; + MultiViewOps.constraint(F21, match.p1, match.p2));&lt;br /&gt;
		System.out.println(&amp;quot;x3&amp;#039;*F31*X1 = &amp;quot; + MultiViewOps.constraint(F31, match.p1, match.p3));&lt;br /&gt;
&lt;br /&gt;
		// For examples of how a trifocal tensor can be used in self calibration see&lt;br /&gt;
		// ExampleTrifocalStereoUncalibrated&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Peter</name></author>
	</entry>
</feed>