Use an explicit ceres::Context

This lets us reuse it which makes the solves way faster.

Change-Id: I3f8745970f1e3bf0c3299632efb019002c8eb36f
diff --git a/y2019/vision/target_finder.cc b/y2019/vision/target_finder.cc
index 3a4c9b0..77806d5 100644
--- a/y2019/vision/target_finder.cc
+++ b/y2019/vision/target_finder.cc
@@ -1,13 +1,18 @@
 #include "y2019/vision/target_finder.h"
 
 #include "aos/vision/blob/hierarchical_contour_merge.h"
+#include "ceres/ceres.h"
 
 using namespace aos::vision;
 
 namespace y2019 {
 namespace vision {
 
-TargetFinder::TargetFinder() : target_template_(Target::MakeTemplate()) {}
+TargetFinder::TargetFinder()
+    : target_template_(Target::MakeTemplate()),
+      ceres_context_(ceres::Context::Create()) {}
+
+TargetFinder::~TargetFinder() {}
 
 aos::vision::RangeImage TargetFinder::Threshold(aos::vision::ImagePtr image) {
   const uint8_t threshold_value = GetThresholdValue();
@@ -550,8 +555,9 @@
     valid_result_count_++;
   }
   if (print_rate > 0 && frame_count_ > print_rate) {
-    LOG(INFO, "Found (%zu / %zu)(%.2f) targets.\n", valid_result_count_,
-        frame_count_, (double)valid_result_count_ / (double)frame_count_);
+    LOG(INFO) << "Found (" << valid_result_count_ << " / " << frame_count_
+              << ")(" << ((double)valid_result_count_ / (double)frame_count_)
+              << " targets.";
     frame_count_ = 0;
     valid_result_count_ = 0;
   }
diff --git a/y2019/vision/target_finder.h b/y2019/vision/target_finder.h
index c7de67a..3da5373 100644
--- a/y2019/vision/target_finder.h
+++ b/y2019/vision/target_finder.h
@@ -1,14 +1,21 @@
 #ifndef _Y2019_VISION_TARGET_FINDER_H_
 #define _Y2019_VISION_TARGET_FINDER_H_
 
+#include <memory>
+
+#include "aos/vision/blob/contour.h"
 #include "aos/vision/blob/region_alloc.h"
 #include "aos/vision/blob/threshold.h"
 #include "aos/vision/blob/transpose.h"
-#include "aos/vision/blob/contour.h"
 #include "aos/vision/debug/overlay.h"
 #include "aos/vision/math/vector.h"
 #include "y2019/vision/target_types.h"
 
+namespace ceres {
+
+class Context;
+
+}  // namespace ceres
 namespace y2019 {
 namespace vision {
 
@@ -26,6 +33,8 @@
 class TargetFinder {
  public:
   TargetFinder();
+  ~TargetFinder();
+
   // Turn a raw image into blob range image.
   aos::vision::RangeImage Threshold(aos::vision::ImagePtr image);
 
@@ -88,6 +97,8 @@
 
   ExtrinsicParams default_extrinsics_;
 
+  const std::unique_ptr<ceres::Context> ceres_context_;
+
   // Counts for logging.
   size_t frame_count_;
   size_t valid_result_count_;
diff --git a/y2019/vision/target_geometry.cc b/y2019/vision/target_geometry.cc
index 91c8848..e647f1f 100644
--- a/y2019/vision/target_geometry.cc
+++ b/y2019/vision/target_geometry.cc
@@ -236,8 +236,10 @@
   double params_4point[ExtrinsicParams::kNumParams];
   default_extrinsics_.set(&params_4point[0]);
 
-  Problem problem_8point;
-  Problem problem_4point;
+  Problem::Options problem_options;
+  problem_options.context = ceres_context_.get();
+  Problem problem_8point(problem_options);
+  Problem problem_4point(problem_options);
 
   ::std::array<aos::vision::Vector<2>, 8> target_value = target.ToPointList();
   ::std::array<aos::vision::Vector<2>, 8> template_value =