MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkUndistortCameraImage.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
13
19
20
22#include <opencv2/imgproc/imgproc_c.h>
23#include <opencv2/calib3d.hpp>
24
31{
32 if(m_tempImage != nullptr)
33 cvReleaseImage(&m_tempImage);
34}
35
36
38mitk::Point2D mitk::UndistortCameraImage::UndistortPixel(const mitk::Point2D& src)
39{
40 float r_2 = 0; // radial distance squared
41 const mitk::Point2D old_src = src; // copy of the original distorted point
42
43 // distortion coefficients
44 float k1 = m_distortionMatrixData[0];
45 float k2 = m_distortionMatrixData[1];
46 float p1 = m_distortionMatrixData[2];
47 float p2 = m_distortionMatrixData[3];
48
49 // Shift points to principal point and use focal length
50 mitk::Point2D dstd;
51 dstd[0] = (src[0] - m_ccX) / m_fcX;
52 dstd[1] = (src[1] - m_ccY) / m_fcY;
53 mitk::Point2D desPnt = dstd;
54
55 // Compensate lens distortion
56 float x = dstd[0];
57 float y = dstd[1];
58
59 for (int iter = 0; iter < 5; iter++)
60 {
61 r_2 = x*x + y*y;
62 const float k_radial = 1 + k1 * r_2 + k2 * r_2 * r_2;
63 const float delta_x = 2 * p1*x*y + p2 * (r_2 + 2*x*x);
64 const float delta_y = 2 * p2*x*y + p1 * (r_2 + 2*y*y);
65 x = (desPnt[0] - delta_x) / k_radial;
66 y = (desPnt[1] - delta_y) / k_radial;
67 }
68 dstd[0] = x;
69 dstd[1] = y;
70 dstd[0] *= m_fcX;
71 dstd[1] *= m_fcY;
72 dstd[0] += m_ccX;
73 dstd[1] += m_ccY;
74
75 // ready
76 // const mitk::Point2D dst = dstd;
77
78 // do a sanity check to make sure this ideal point translates properly to the distorted point
79 // this does the reverse of the above. It maps ideal undistorted to distorted image coordinates
80 x = dstd[0] - m_ccX;
81 y = dstd[1] - m_ccY;
82 x /= m_fcX;
83 y /= m_fcY;
84 r_2 = x*x + y*y;
85 float distx = x + x*(k1*r_2 + k2*r_2*r_2) + (2*p1*x*y + p2*(r_2 + 2*x*x));
86 float disty = y + y*(k1*r_2 + k2*r_2*r_2) + (2*p2*x*y + p1*(r_2 + 2*y*y));
87 distx *= m_fcX;
88 disty *= m_fcY;
89 distx += m_ccX;
90 disty += m_ccY;
91
92 // this should never be more than .2 pixels...
93 const float diffx = old_src[0] - distx;
94 const float diffy = old_src[1] - disty;
95 if (fabs(diffx) > .1 || fabs(diffy) > .1)
96 {
97 std::cout << "undistort sanity check error: diffx =" << diffx << " , diffy = " << diffy;
98 }
99 return dstd;
100}
101
102void mitk::UndistortCameraImage::UndistortImage(IplImage *src, IplImage *dst)
103{
104 // init intrinsic camera matrix [fx 0 cx; 0 fy cy; 0 0 1].
105 m_intrinsicMatrixData[0] = (double)m_fcX;
106 m_intrinsicMatrixData[1] = 0.0;
107 m_intrinsicMatrixData[2] = (double)m_ccX;
108 m_intrinsicMatrixData[3] = 0.0;
109 m_intrinsicMatrixData[4] = (double)m_fcY;
110 m_intrinsicMatrixData[5] = (double)m_ccY;
111 m_intrinsicMatrixData[6] = 0.0;
112 m_intrinsicMatrixData[7] = 0.0;
113 m_intrinsicMatrixData[8] = 1.0;
114 m_intrinsicMatrix = cvMat(3, 3, CV_32FC1, m_intrinsicMatrixData);
115
116 // init distortion matrix
117 m_distortionMatrix = cvMat(1, 4, CV_32F, m_distortionMatrixData);
118
119 // undistort
120 auto srcMat = cv::cvarrToMat(src);
121 auto dstMat = cv::cvarrToMat(dst);
122 auto intrinsicMat = cv::cvarrToMat(&m_intrinsicMatrix);
123 auto distortionMat = cv::cvarrToMat(&m_distortionMatrix);
124 cv::undistort(srcMat, dstMat, intrinsicMat, distortionMat);
125}
126
127
128// FAST METHODS FOR UNDISTORTION IN REALTIME //
129
130void mitk::UndistortCameraImage::UndistortImageFast(IplImage * src, IplImage* dst)
131{
132 if(!src)
133 return;
134
135 /*if(dst == nullptr)
136 dst = src;
137
138 if(src->nChannels == 3)
139 {
140 IplImage *r = cvCreateImage(cvGetSize(src),src->depth,1);//subpixel
141 IplImage *g = cvCreateImage(cvGetSize(src),src->depth,1);//subpixel
142 IplImage *b = cvCreateImage(cvGetSize(src),src->depth,1);//subpixel
143
144 cvSplit(src, r,g,b, nullptr);
145
146 cvRemap( r, r, m_mapX, m_mapY ); // Undistort image
147 cvRemap( g, g, m_mapX, m_mapY ); // Undistort image
148 cvRemap( b, b, m_mapX, m_mapY ); // Undistort image
149
150 cvMerge(r,g,b, nullptr, dst);
151 }
152 else
153 {
154 cvRemap(src, dst, m_mapX, m_mapY);
155 }*/
156
157
158 /*if(m_tempImage == nullptr)
159 m_tempImage = cvCreateImage(cvSize(src->width,src->height),src->depth,src->nChannels);*/
160
161 /*if(dst == nullptr)
162 dst = cvCreateImage(cvSize(src->width,src->height),src->depth,src->nChannels);*/
163
164 if(!dst)
165 {
166 m_tempImage = cvCloneImage( src );
167 cvRemap(m_tempImage, src, m_mapX, m_mapY, CV_INTER_CUBIC);
168 cvReleaseImage( &m_tempImage );
169 m_tempImage = nullptr;
170 /*memcpy( src->imageData, m_tempImage->imageData, m_tempImage->imageSize );
171 cvReleaseImage( &m_tempImage );*/
172 }
173 else
174 {
175 cvRemap(src, dst, m_mapX, m_mapY, CV_INTER_CUBIC);
176 }
177
178 /*m_tempImage->origin = src->origin;
179
180 if(dst == nullptr)
181 memcpy( src->imageData, m_tempImage->imageData, m_tempImage->imageSize );
182 else
183 memcpy( dst->imageData, m_tempImage->imageData, m_tempImage->imageSize );
184
185 //cvUnDistort(m_srcImg, m_dstImg, m_undistMap,m_interpolationMode);
186 //cvUndistort2(m_srcImg, m_dstImg, &m_intrinsicMatrix,&m_distortionMatrixDataCoefficients);*/
187}
188
189
190
192 float in_dPrincipalX, float in_dPrincipalY,
193 float in_Dist[4], float ImageSizeX, float ImageSizeY)
194{
195 //create new matrix
196 m_DistortionCoeffs = cvCreateMat(4, 1, CV_64FC1);
197 m_CameraMatrix = cvCreateMat(3, 3, CV_64FC1);
198
199
200 //set the camera matrix [fx 0 cx; 0 fy cy; 0 0 1].
201 cvSetReal2D(m_CameraMatrix, 0, 0, in_dF1);
202 cvSetReal2D(m_CameraMatrix, 0, 1, 0.0);
203 cvSetReal2D(m_CameraMatrix, 0, 2, in_dPrincipalX);
204
205 cvSetReal2D(m_CameraMatrix, 1, 0, 0.0);
206 cvSetReal2D(m_CameraMatrix, 1, 1, in_dF2);
207 cvSetReal2D(m_CameraMatrix, 1, 2, in_dPrincipalY);
208
209 cvSetReal2D(m_CameraMatrix, 2, 0, 0.0);
210 cvSetReal2D(m_CameraMatrix, 2, 1, 0.0);
211 cvSetReal2D(m_CameraMatrix, 2, 2, 1.0);
212
213 //set distortions coefficients
214 cvSetReal1D(m_DistortionCoeffs, 0, in_Dist[0]);
215 cvSetReal1D(m_DistortionCoeffs, 1, in_Dist[1]);
216 cvSetReal1D(m_DistortionCoeffs, 2, in_Dist[2]);
217 cvSetReal1D(m_DistortionCoeffs, 3, in_Dist[3]);
218
219 m_mapX = cvCreateMat(ImageSizeY, ImageSizeX, CV_32FC1);
220 m_mapY = cvCreateMat(ImageSizeY, ImageSizeX, CV_32FC1);
221
222 auto cameraMat = cv::cvarrToMat(m_CameraMatrix);
223 auto distortionCoeffs = cv::cvarrToMat(m_DistortionCoeffs);
224 auto mapX = cv::cvarrToMat(m_mapX);
225 auto mapY = cv::cvarrToMat(m_mapY);
226 cv::initUndistortRectifyMap(cameraMat, distortionCoeffs, cv::Mat(), cameraMat, mapX.size(), mapX.type(), mapX, mapY);
227}
228
229
230
231
void UndistortImageFast(IplImage *src, IplImage *dst=nullptr)
void UndistortImage(IplImage *src, IplImage *dst)
void SetUndistortImageFastInfo(float in_dF1, float in_dF2, float in_dPrincipalX, float in_dPrincipalY, float in_Dist[4], float ImageSizeX, float ImageSizeY)
mitk::Point2D UndistortPixel(const mitk::Point2D &src)
USAGE ///.