blob: 93f3892a54cbd1e2312d018655598234d61662da [file] [log] [blame]
Brian Silverman2ccf8c52016-03-15 00:22:26 -04001#ifndef Y2016_VISION_STEREO_GEOMETRY_H_
2#define Y2016_VISION_STEREO_GEOMETRY_H_
3
4#include <string>
5
6#include "aos/vision/math/vector.h"
7#include "aos/common/logging/logging.h"
8
9#include "y2016/vision/calibration.pb.h"
10
11namespace y2016 {
12namespace vision {
13
14// Returns the contents of the calibration file which are embedded into the
15// code.
16CalibrationFile EmbeddedCalibrationFile();
17
18// Returns the embedded Calibration for the given robot_name or LOG(FATAL)s.
19Calibration FindCalibrationForRobotOrDie(
20 const ::std::string &robot_name, const CalibrationFile &calibration_file);
21
22class StereoGeometry {
23 public:
24 StereoGeometry(const ::std::string &robot_name)
25 : calibration_(FindCalibrationForRobotOrDie(robot_name,
26 EmbeddedCalibrationFile())) {}
27
28 // Returns the forward world distance in meters corresponding to the given
29 // distance in pixels between the two cameras.
30 double PixelToWorldDistance(double pixel_distance) {
31 return (calibration_.center_center_dist() *
32 calibration_.camera_image_width() * calibration_.focal_length() /
33 (pixel_distance + calibration_.center_center_skew())) +
34 calibration_.measure_camera_offset();
35 }
36
37 // Converts locations on both cameras to the distance between the locations
38 // and both angles.
39 // Returns (via pointers) the distance to the target in meters, the horizontal
40 // angle to the target in radians, and the vertical angle to the target in
41 // radians.
42 // TODO(Brian): Figure out which way is positive on the angles.
43 void Process(const ::aos::vision::Vector<2> &center0,
44 const ::aos::vision::Vector<2> &center1, double *distance,
45 double *horizontal_angle, double *vertical_angle) {
46 *distance = PixelToWorldDistance(center1.x() - center0.x());
47 const double average_x = (center0.x() + center1.x()) / 2.0 -
48 calibration_.camera_image_width() / 2.0;
49 const double average_y = (center0.y() + center1.y()) / 2.0 -
50 calibration_.camera_image_height() / 2.0;
51
52 *horizontal_angle =
53 std::atan2(average_x, calibration_.camera_image_width() *
54 calibration_.focal_length());
55 *vertical_angle = std::atan2(average_y, calibration_.camera_image_width() *
56 calibration_.focal_length());
57 }
58
59 const Calibration &calibration() const { return calibration_; }
60
61 private:
62 Calibration calibration_;
63};
64
65} // namespace vision
66} // namespace y2016
67
68#endif // Y2016_VISION_STEREO_GEOMETRY_H_