37 #include <jsk_topic_tools/log_utils.h>
39 #include <sensor_msgs/Image.h>
43 #include <boost/assign.hpp>
51 DiagnosticNodelet::onInit();
59 srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
60 dynamic_reconfigure::Server<Config>::CallbackType
f =
62 srv_->setCallback (
f);
94 jsk_topic_tools::warnNoRemap(names);
106 int l = distorted.rows / 2;
109 float min_degree = 30;
110 float min_radian = min_degree * 3.14159265 /180.0;
111 float tan_min_radian = tan(min_radian);
112 const float K = 341.656050955;
114 cv::Mat undistorted(
l,
l*4, CV_8UC3);
115 cv::Mat undistorted_bilinear(
l,
l*4, CV_8UC3);
116 for(
int i = 0;
i < undistorted.rows; ++
i){
117 for(
int j = 0; j < undistorted.cols; ++j){
120 double theta = 2.0 *
PI * (double)(-j) / (double)(4.0 *
l);
124 int x = (
int)round(fTrueX) +
l;
125 int y =
l - (
int)round(fTrueY);
126 if (
x >= 0 &&
x < (2 *
l) && y >= 0 && y < (2 *
l))
128 for(
int c = 0; c < undistorted.channels(); ++c)
129 undistorted.data[
i * undistorted.step + j * undistorted.elemSize() + c ]
130 = distorted.data[
x * distorted.step + y * distorted.elemSize() + c];
133 fTrueX = fTrueX + (double)
l;
134 fTrueY = (double)
l - fTrueY;
136 int iFloorX = (
int)floor(fTrueX);
137 int iFloorY = (
int)floor(fTrueY);
138 int iCeilingX = (
int)ceil(fTrueX);
139 int iCeilingY = (
int)ceil(fTrueY);
141 if (iFloorX < 0 || iCeilingX < 0 ||
142 iFloorX >= (2 *
l) || iCeilingX >= (2 *
l) ||
143 iFloorY < 0 || iCeilingY < 0 ||
144 iFloorY >= (2 *
l) || iCeilingY >= (2 *
l))
continue;
146 double fDeltaX = fTrueX - (double)iFloorX;
147 double fDeltaY = fTrueY - (double)iFloorY;
149 cv::Mat clrTopLeft(1,1, CV_8UC3), clrTopRight(1,1, CV_8UC3), clrBottomLeft(1,1, CV_8UC3), clrBottomRight(1,1, CV_8UC3);
150 for(
int c = 0; c < undistorted.channels(); ++c){
151 clrTopLeft.data[ c ] = distorted.data[iFloorX * distorted.step + iFloorY * distorted.elemSize() + c];
152 clrTopRight.data[ c ] = distorted.data[iCeilingX * distorted.step + iFloorY * distorted.elemSize() + c];
153 clrBottomLeft.data[ c ] = distorted.data[iFloorX * distorted.step + iCeilingY * distorted.elemSize() + c];
154 clrBottomRight.data[ c ] = distorted.data[iCeilingX * distorted.step + iCeilingY * distorted.elemSize() + c];
157 double fTop0 =
interpolate(fDeltaX, clrTopLeft.data[0], clrTopRight.data[0]);
158 double fTop1 =
interpolate(fDeltaX, clrTopLeft.data[1], clrTopRight.data[1]);
159 double fTop2 =
interpolate(fDeltaX, clrTopLeft.data[2], clrTopRight.data[2]);
160 double fBottom0 =
interpolate(fDeltaX, clrBottomLeft.data[0], clrBottomRight.data[0]);
161 double fBottom1 =
interpolate(fDeltaX, clrBottomLeft.data[1], clrBottomRight.data[1]);
162 double fBottom2 =
interpolate(fDeltaX, clrBottomLeft.data[2], clrBottomRight.data[2]);
168 i0 = std::min(255, std::max(i0, 0));
169 i1 = std::min(255, std::max(i1, 0));
170 i2 = std::min(255, std::max(i2, 0));
172 undistorted_bilinear.data[
i * undistorted_bilinear.step + j * undistorted_bilinear.elemSize() + 0] = i0;
173 undistorted_bilinear.data[
i * undistorted_bilinear.step + j * undistorted_bilinear.elemSize() + 1] = i1;
174 undistorted_bilinear.data[
i * undistorted_bilinear.step + j * undistorted_bilinear.elemSize() + 2] = i2;
188 cv::Mat undistorted(
int(
l * 1.0 / tan_min_radian*
scale_),
int(
l * 2.0 *
PI *
scale_), CV_8UC3);
189 int center_x = distorted.rows/2, center_y = distorted.cols/2;
192 for(
int i = 0;
i < undistorted.rows; ++
i){
193 for(
int j = 0; j < undistorted.cols; ++j){
196 phi = atan(
l * 1.0 /
i*
scale_) + 0.5;
197 float theta = (j-
int(undistorted.cols/2))/
scale_ * 1.0/
l;
198 int x = K * phi *
cos(theta) + center_x;
199 int y = K * phi *
sin(theta) + center_y;
200 for(
int c = 0; c < undistorted.channels(); ++c){
201 int index = undistorted.rows - 1 -
i;
204 int jndex = j + offset_jndex;
205 if(jndex > undistorted.cols - 1)
206 jndex -= undistorted.cols - 1;
207 undistorted.data[
index * undistorted.step + jndex * undistorted.elemSize() + c ]
208 = distorted.data[
x * distorted.step + y * distorted.elemSize() + c];
220 float max_radian = max_degree * 3.14159265 /180.0;
221 float tan_max_radian = tan(max_radian);
222 const float K = 341.656050955;
223 const float absolute_max_degree = 85;
224 const float absolute_max_radian = absolute_max_degree * 3.14159265 /180.0;
225 float max_radius = max_radian * K;
226 cv::Mat undistorted(
int(
l * tan_max_radian * 2 *
scale_),
int(
l * tan_max_radian * 2 *
scale_), CV_8UC3);
227 int center_x = distorted.rows/2, center_y = distorted.cols/2;
228 int un_center_x = undistorted.rows/(2 *
scale_), un_center_y = undistorted.cols/(2*
scale_);
230 for(
int i = 0;
i < undistorted.rows; ++
i){
231 for(
int j = 0; j < undistorted.cols; ++j){
232 int diff_x =
i/
scale_-un_center_x, diff_y = j/
scale_-un_center_y;
233 float radius =
sqrt(pow(diff_x, 2) + pow(diff_y, 2));
235 if( radian < absolute_max_radian ){
236 float multi = 0, new_x = center_x, new_y = center_y;
239 multi = radian * K /
radius;
240 new_x += diff_x * multi;
241 new_y += diff_y * multi;
244 for(
int c = 0; c < undistorted.channels(); ++c){
245 undistorted.data[
i * undistorted.step + j * undistorted.elemSize() + c ]
246 = distorted.data[
int(new_x) * distorted.step +
int(new_y) * distorted.elemSize() + c];