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