Apollo 11.0
自动驾驶开放平台
undistortion_handler.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
17
18#include <vector>
19
20#include "Eigen/Dense"
21
22#include "cyber/common/log.h"
25
26namespace apollo {
27namespace perception {
28namespace camera {
29
31 device_ = device;
32 auto code = cudaSetDevice(device_);
33 if (code != cudaSuccess) {
34 AERROR << "cudaSetDevice failed: " << cudaGetErrorString(code);
35 return false;
36 }
37 return true;
38}
39/* Initialization of the GPU routines for camera data preprocessing
40 *
41 * Return: 0 - success; other - failure
42 * Params: device - dev number of the GPU device
43 * Note: returns OK if already been inited.
44 */
45bool UndistortionHandler::Init(const std::string &sensor_name, int device) {
46 if (inited_) {
47 return true;
48 }
49
50 std::vector<double> D;
51 std::vector<double> K;
52
53 algorithm::SensorManager *sensor_manager =
54 algorithm::SensorManager::Instance();
55 if (!sensor_manager->IsSensorExist(sensor_name)) {
56 AERROR << "Sensor '" << sensor_name << "' not exists!";
57 return false;
58 }
59
60 if (!set_device(device)) {
61 return false;
62 }
63
65 std::dynamic_pointer_cast<base::BrownCameraDistortionModel>(
66 sensor_manager->GetDistortCameraModel(sensor_name));
67
68 height_ = static_cast<int>(distort_model->get_height());
69 width_ = static_cast<int>(distort_model->get_width());
70 d_mapx_.Reshape({height_, width_});
71 d_mapy_.Reshape({height_, width_});
72
73 Eigen::Matrix3f I;
74 I << 1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f;
75
76 InitUndistortRectifyMap(distort_model->get_intrinsic_params(),
77 distort_model->get_distort_params(), I,
78 distort_model->get_intrinsic_params(), width_,
79 height_, &d_mapx_, &d_mapy_);
80
81 inited_ = true;
82 return true;
83}
84
86 base::Image8U *dst_img) {
87 if (!inited_) {
88 return false;
89 }
90
91 if (!set_device(device_)) {
92 return false;
93 }
94
95 return imageRemap(src_img, dst_img, width_, height_, d_mapx_, d_mapy_);
96}
97
99 inited_ = false;
100 return true;
101}
102
104 const Eigen::Matrix3f &camera_model,
105 const Eigen::Matrix<float, 8, 1> &distortion, const Eigen::Matrix3f &R,
106 const Eigen::Matrix3f &new_camera_model, int width, int height,
107 base::Blob<float> *d_mapx, base::Blob<float> *d_mapy) {
108 float fx = camera_model(0, 0);
109 float fy = camera_model(1, 1);
110 float cx = camera_model(0, 2);
111 float cy = camera_model(1, 2);
112 float nfx = new_camera_model(0, 0);
113 float nfy = new_camera_model(1, 1);
114 float ncx = new_camera_model(0, 2);
115 float ncy = new_camera_model(1, 2);
116 float k1 = distortion(0, 0);
117 float k2 = distortion(1, 0);
118 float p1 = distortion(2, 0);
119 float p2 = distortion(3, 0);
120 float k3 = distortion(4, 0);
121 Eigen::Matrix3f Rinv = R.inverse();
122
123 for (int v = 0; v < height_; ++v) {
124 float *x_ptr = d_mapx->mutable_cpu_data() + d_mapx->offset(v);
125 float *y_ptr = d_mapy->mutable_cpu_data() + d_mapy->offset(v);
126 for (int u = 0; u < width_; ++u) {
127 Eigen::Matrix<float, 3, 1> xy1;
128 xy1 << (static_cast<float>(u) - ncx) / nfx,
129 (static_cast<float>(v) - ncy) / nfy, 1;
130 auto XYW = Rinv * xy1;
131 double nx = XYW(0, 0) / XYW(2, 0);
132 double ny = XYW(1, 0) / XYW(2, 0);
133 double r_square = nx * nx + ny * ny;
134 double scale = (1 + r_square * (k1 + r_square * (k2 + r_square * k3)));
135 double nnx =
136 nx * scale + 2 * p1 * nx * ny + p2 * (r_square + 2 * nx * nx);
137 double nny =
138 ny * scale + p1 * (r_square + 2 * ny * ny) + 2 * p2 * nx * ny;
139 x_ptr[u] = static_cast<float>(nnx * fx + cx);
140 y_ptr[u] = static_cast<float>(nny * fy + cy);
141 }
142 }
143}
144
145} // namespace camera
146} // namespace perception
147} // namespace apollo
bool IsSensorExist(const std::string &name) const
std::shared_ptr< BaseCameraDistortionModel > GetDistortCameraModel(const std::string &name) const
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
Definition blob.h:88
int offset(const int n, const int c=0, const int h=0, const int w=0) const
Definition blob.h:231
void Reshape(const int num, const int channels, const int height, const int width)
Deprecated; use Reshape(const std::vector<int>& shape).
Definition blob.cc:72
A wrapper around Blob holders serving as the basic computational unit for images.
Definition image_8u.h:44
void InitUndistortRectifyMap(const Eigen::Matrix3f &camera_model, const Eigen::Matrix< float, 8, 1 > &distortion, const Eigen::Matrix3f &R, const Eigen::Matrix3f &new_camera_model, int width, int height, base::Blob< float > *d_mapx, base::Blob< float > *d_mapy)
bool Init(const std::string &sensor_name, int device)
bool Handle(const base::Image8U &src_img, base::Image8U *dst_img)
: Processing each image @params: src_img - input image array dst_img - output image array
first check imutoantoffset saved in device
Definition readme.txt:2
#define AERROR
Definition log.h:44
std::shared_ptr< BrownCameraDistortionModel > BrownCameraDistortionModelPtr
bool imageRemap(const base::Image8U &src_img, base::Image8U *dst_img, const int src_width, const int src_height, const base::Blob< float > &map_x, const base::Blob< float > &map_y)
class register implement
Definition arena_queue.h:37