calibfilter.cpp
Go to the documentation of this file.
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41 
42 #include "calibfilter.h"
43 #include <stdio.h>
44 
45 #include <opencv2/calib3d/calib3d_c.h>
46 #include <opencv2/core/core_c.h>
47 
48 #undef quad
49 
51 {
52  /* etalon data */
54  etalonParamCount = 0;
55  etalonParams = 0;
56  etalonPointCount = 0;
57  etalonPoints = 0;
58 
59  /* camera data */
60  cameraCount = 1;
61 
62  memset(points, 0, sizeof(points));
63  memset(undistMap, 0, sizeof(undistMap));
64  undistImg = 0;
65  memset(latestCounts, 0, sizeof(latestCounts));
66  memset(latestPoints, 0, sizeof(latestPoints));
67 #pragma GCC diagnostic push
68 #pragma GCC diagnostic ignored "-Wclass-memaccess"
69  memset(&stereo, 0, sizeof(stereo));
70 #pragma GCC diagnostic pop
71  maxPoints = 0;
72  framesTotal = 15;
73  framesAccepted = 0;
74  isCalibrated = false;
75 
76  imgSize = cvSize(0, 0);
77  grayImg = 0;
78  tempImg = 0;
79  storage = 0;
80 
81  memset(rectMap, 0, sizeof(rectMap));
82 }
83 
84 
86 {
87  SetCameraCount(0);
88  cvFree(&etalonParams);
89  cvFree(&etalonPoints);
90  cvReleaseMat(&grayImg);
91  cvReleaseMat(&tempImg);
92  cvReleaseMat(&undistImg);
93  cvReleaseMemStorage(&storage);
94 }
95 
96 
97 bool CvCalibFilter::SetEtalon(CvCalibEtalonType type, double* params,
98  int pointCount, CvPoint2D32f* _points)
99 {
100  int i, arrSize;
101 
102  Stop();
103 
104  for (i = 0; i < MAX_CAMERAS; i++)
105  {
106  cvFree(latestPoints + i);
107  }
108 
109  if (type == CV_CALIB_ETALON_USER || type != etalonType)
110  {
111  if (etalonParams != NULL)
112  {
113  cvFree(&etalonParams);
114  }
115  }
116 
117  etalonType = type;
118 
119  switch (etalonType)
120  {
122  etalonParamCount = 3;
123  if (!params || cvRound(params[0]) != params[0] || params[0] < 3 ||
124  cvRound(params[1]) != params[1] || params[1] < 3 || params[2] <= 0)
125  {
126  assert(0);
127  return false;
128  }
129 
130  pointCount = cvRound((params[0] - 1) * (params[1] - 1));
131  break;
132 
134  etalonParamCount = 0;
135 
136  if (!_points || pointCount < 4)
137  {
138  assert(0);
139  return false;
140  }
141  break;
142 
143  default:
144  assert(0);
145  return false;
146  }
147 
148  if (etalonParamCount > 0)
149  {
150  arrSize = etalonParamCount * sizeof(etalonParams[0]);
151  etalonParams = (double*)cvAlloc(arrSize);
152  }
153 
154  arrSize = pointCount * sizeof(etalonPoints[0]);
155 
156  if (etalonPointCount != pointCount)
157  {
158  if (etalonPoints != NULL)
159  {
160  cvFree(&etalonPoints);
161  }
162  etalonPointCount = pointCount;
163  etalonPoints = (CvPoint2D32f*)cvAlloc(arrSize);
164  }
165 
166  switch (etalonType)
167  {
169  {
170  int etalonWidth = cvRound(params[0]) - 1;
171  int etalonHeight = cvRound(params[1]) - 1;
172  int x, y, k = 0;
173 
174  etalonParams[0] = etalonWidth;
175  etalonParams[1] = etalonHeight;
176  etalonParams[2] = params[2];
177 
178  for (y = 0; y < etalonHeight; y++)
179  for (x = 0; x < etalonWidth; x++)
180  {
181  etalonPoints[k++] = cvPoint2D32f((etalonWidth - 1 - x) * params[2],
182  y * params[2]);
183  }
184  }
185  break;
186 
188  if (params != NULL)
189  {
190  memcpy(etalonParams, params, arrSize);
191  }
192  if (_points != NULL)
193  {
194  memcpy(etalonPoints, _points, arrSize);
195  }
196  break;
197 
198  default:
199  assert(0);
200  return false;
201  }
202 
203  return true;
204 }
205 
206 
208 CvCalibFilter::GetEtalon(int* paramCount, const double** params,
209  int* pointCount, const CvPoint2D32f** _points) const
210 {
211  if (paramCount)
212  {
213  *paramCount = etalonParamCount;
214  }
215 
216  if (params)
217  {
218  *params = etalonParams;
219  }
220 
221  if (pointCount)
222  {
223  *pointCount = etalonPointCount;
224  }
225 
226  if (_points)
227  {
228  *_points = etalonPoints;
229  }
230 
231  return etalonType;
232 }
233 
234 
236 {
237  Stop();
238 
239  if (count != cameraCount)
240  {
241  for (int i = 0; i < cameraCount; i++)
242  {
243  cvFree(points + i);
244  cvFree(latestPoints + i);
245  cvReleaseMat(&undistMap[i][0]);
246  cvReleaseMat(&undistMap[i][1]);
247  cvReleaseMat(&rectMap[i][0]);
248  cvReleaseMat(&rectMap[i][1]);
249  }
250 
251  memset(latestCounts, 0, sizeof(latestCounts));
252  maxPoints = 0;
253  cameraCount = count;
254  }
255 }
256 
257 
258 bool CvCalibFilter::SetFrames(int frames)
259 {
260  if (frames < 5)
261  {
262  assert(0);
263  return false;
264  }
265 
266  framesTotal = frames;
267  return true;
268 }
269 
270 /* Calibrates camera using multiple views of calibration pattern */
271 static void cvCalibrateCamera(int image_count, int* _point_counts,
272  cv::Size image_size, cv::Point2f* _image_points, cv::Point2f* _object_points,
273  float* _distortion_coeffs, float* _camera_matrix, float* _translation_vectors,
274  float* _rotation_matrices, int flags)
275 {
276  int i, total = 0;
277  cv::Mat point_counts = cv::Mat(image_count, 1, CV_32SC1, _point_counts);
278  std::vector<std::vector<cv::Point2f> > image_points, object_points;
279  cv::Mat dist_coeffs = cv::Mat(4, 1, CV_32FC1, _distortion_coeffs);
280  cv::Mat camera_matrix = cv::Mat(3, 3, CV_32FC1, _camera_matrix);
281  std::vector<cv::Mat> rotation_matrices;
282  std::vector<cv::Mat> translation_vectors;
283 
284  for (i = 0; i < image_count; i++)
285  {
286  total += _point_counts[i];
287  for (int j = 0; j < _point_counts[i]; j++)
288  {
289  std::vector<cv::Point2f> img, obj;
290  img.insert(img.begin(), _image_points, _image_points + _point_counts[i]);
291  obj.insert(obj.begin(), _object_points, _object_points + _point_counts[i]);
292  image_points.push_back(img);
293  object_points.push_back(obj);
294  _image_points += _point_counts[i];
295  _object_points += _point_counts[i];
296  }
297 
298  rotation_matrices.emplace_back(1, 9, CV_32FC1, _rotation_matrices);
299  translation_vectors.emplace_back(1, 3, CV_32FC1, _translation_vectors);
300  _rotation_matrices += 9;
301  _translation_vectors += 3;
302  }
303 
304 
305  cv::calibrateCamera(object_points, image_points, std::move(image_size),
306  camera_matrix, dist_coeffs, rotation_matrices, translation_vectors,
307  flags);
308 }
309 
310 #define icvCheckVector_32f( ptr, len )
311 #define icvCheckVector_64f( ptr, len )
312 
313 CV_INLINE void icvMulMatrix_32f(const float* src1, int w1, int h1,
314  const float* src2, int w2, int h2,
315  float* dst)
316 {
317  int i, j, k;
318 
319  if (w1 != h2)
320  {
321  assert(0);
322  return;
323  }
324 
325  for (i = 0; i < h1; i++, src1 += w1, dst += w2)
326  for (j = 0; j < w2; j++)
327  {
328  double s = 0;
329  for (k = 0; k < w1; k++)
330  {
331  s += src1[k] * src2[j + k * w2];
332  }
333  dst[j] = (float)s;
334  }
335 
336  icvCheckVector_32f(dst, h1 * w2);
337 }
338 
339 CV_INLINE void icvSubVector_64d(const double* src1, const double* src2,
340  double* dst, int len)
341 {
342  int i;
343  for (i = 0; i < len; i++)
344  {
345  dst[i] = src1[i] - src2[i];
346  }
347 
348  icvCheckVector_64f(dst, len);
349 }
350 
351 CV_INLINE void icvMulMatrix_64d(const double* src1, int w1, int h1,
352  const double* src2, int w2, int h2,
353  double* dst)
354 {
355  int i, j, k;
356 
357  if (w1 != h2)
358  {
359  assert(0);
360  return;
361  }
362 
363  for (i = 0; i < h1; i++, src1 += w1, dst += w2)
364  for (j = 0; j < w2; j++)
365  {
366  double s = 0;
367  for (k = 0; k < w1; k++)
368  {
369  s += src1[k] * src2[j + k * w2];
370  }
371  dst[j] = s;
372  }
373 
374  icvCheckVector_64f(dst, h1 * w2);
375 }
376 
377 CV_INLINE void icvInvertMatrix_64d(double* A, int n, double* invA)
378 {
379  CvMat Am = cvMat(n, n, CV_64F, A);
380  CvMat invAm = cvMat(n, n, CV_64F, invA);
381 
382  cvInvert(&Am, &invAm, CV_SVD);
383 }
384 
385 CV_INLINE void icvAddVector_64d(const double* src1, const double* src2,
386  double* dst, int len)
387 {
388  int i;
389  for (i = 0; i < len; i++)
390  {
391  dst[i] = src1[i] + src2[i];
392  }
393 
394  icvCheckVector_64f(dst, len);
395 }
396 
397 CV_INLINE void icvTransposeMatrix_64d(const double* src, int w, int h, double* dst)
398 {
399  int i, j;
400 
401  for (i = 0; i < w; i++)
402  for (j = 0; j < h; j++)
403  {
404  *dst++ = src[j * w + i];
405  }
406 
407  icvCheckVector_64f(dst, w * h);
408 }
409 
410 double cvPseudoInverse(const CvArr* src, CvArr* dst)
411 {
412  return cvInvert(src, dst, CV_SVD);
413 }
414 
415 // BEGIN
416 /*M///////////////////////////////////////////////////////////////////////////////////////
417 //
418 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
419 //
420 // By downloading, copying, installing or using the software you agree to this license.
421 // If you do not agree to this license, do not download, install,
422 // copy or use the software.
423 //
424 //
425 // Intel License Agreement
426 // For Open Source Computer Vision Library
427 //
428 // Copyright (C) 2000, Intel Corporation, all rights reserved.
429 // Third party copyrights are property of their respective owners.
430 //
431 // Redistribution and use in source and binary forms, with or without modification,
432 // are permitted provided that the following conditions are met:
433 //
434 // * Redistribution's of source code must retain the above copyright notice,
435 // this list of conditions and the following disclaimer.
436 //
437 // * Redistribution's in binary form must reproduce the above copyright notice,
438 // this list of conditions and the following disclaimer in the documentation
439 // and/or other materials provided with the distribution.
440 //
441 // * The name of Intel Corporation may not be used to endorse or promote products
442 // derived from this software without specific prior written permission.
443 //
444 // This software is provided by the copyright holders and contributors "as is" and
445 // any express or implied warranties, including, but not limited to, the implied
446 // warranties of merchantability and fitness for a particular purpose are disclaimed.
447 // In no event shall the Intel Corporation or contributors be liable for any direct,
448 // indirect, incidental, special, exemplary, or consequential damages
449 // (including, but not limited to, procurement of substitute goods or services;
450 // loss of use, data, or profits; or business interruption) however caused
451 // and on any theory of liability, whether in contract, strict liability,
452 // or tort (including negligence or otherwise) arising in any way out of
453 // the use of this software, even if advised of the possibility of such damage.
454 //
455 //M*/
456 
457 
458 #include <float.h>
459 #include <limits.h>
460 
461 #include <utility>
462 
463 
464 /* IPP-compatible return codes */
465 typedef enum CvStatus
466 {
472 
481 
482  CV_BADARG_ERR = -49, //ipp comp
483  CV_NOTDEFINED_ERR = -48, //ipp comp
484 
485  CV_BADCHANNELS_ERR = -47, //ipp comp
486  CV_BADRANGE_ERR = -44, //ipp comp
487  CV_BADSTEP_ERR = -29, //ipp comp
488 
490  CV_DIV_BY_ZERO_ERR = -11, //ipp comp
492 
501 }
502 CvStatus;
503 
504 /* Valery Mosyagin */
505 
506 #undef quad
507 
508 #define EPS64D 1e-9
509 
510 using CvMatr32f = float* ;
511 using CvPoint2D64d = CvPoint2D64f;
512 using CvPoint3D64d = CvPoint3D64f;
513 using CvVect64d = double* ;
514 using CvMatr64d = double* ;
515 using CvVect32f = float* ;
516 
517 #define cvmMul( src1, src2, dst ) cvMatMulAdd( src1, src2, 0, dst )
518 
519 enum
520 {
521  CV_MAT32F = CV_32FC1,
522  CV_MAT3x1_32F = CV_32FC1,
523  CV_MAT4x1_32F = CV_32FC1,
524  CV_MAT3x3_32F = CV_32FC1,
525  CV_MAT4x4_32F = CV_32FC1,
526 
527  CV_MAT64D = CV_64FC1,
528  CV_MAT3x1_64D = CV_64FC1,
529  CV_MAT4x1_64D = CV_64FC1,
530  CV_MAT3x3_64D = CV_64FC1,
531  CV_MAT4x4_64D = CV_64FC1
532 };
533 
535  CvMatr32f transVect,
536  CvMatr32f essMatr);
537 
539  CvMatr32f fundMatr,
540  CvMatr32f cameraMatr1,
541  CvMatr32f cameraMatr2);
542 
544  CvPoint3D32f* epipole1,
545  CvPoint3D32f* epipole2);
546 
547 void icvTestPoint(CvPoint2D64d testPoint,
548  CvVect64d line1, CvVect64d line2,
549  CvPoint2D64d basePoint,
550  int* result);
551 
552 
553 void icvGetPieceLength3D(CvPoint3D64d point1, CvPoint3D64d point2, double* dist);
554 
556  CvPoint3D64d point1,
557  CvPoint3D64d point2,
558  CvPoint3D64d* pointSym2)
559 {
560  double len1, len2;
561  double alpha;
562  icvGetPieceLength3D(pointCorner, point1, &len1);
563  if (len1 < EPS64D)
564  {
565  return CV_BADARG_ERR;
566  }
567  icvGetPieceLength3D(pointCorner, point2, &len2);
568  alpha = len2 / len1;
569 
570  pointSym2->x = pointCorner.x + alpha * (point1.x - pointCorner.x);
571  pointSym2->y = pointCorner.y + alpha * (point1.y - pointCorner.y);
572  pointSym2->z = pointCorner.z + alpha * (point1.z - pointCorner.z);
573  return CV_NO_ERR;
574 }
575 
576 /* author Valery Mosyagin */
577 
578 /* Compute 3D point for scanline and alpha betta */
579 int icvCompute3DPoint(double alpha, double betta,
580  CvStereoLineCoeff* coeffs,
581  CvPoint3D64d* point)
582 {
583 
584  double partX;
585  double partY;
586  double partZ;
587  double partAll;
588  double invPartAll;
589 
590  double alphabetta = alpha * betta;
591 
592  partAll = alpha - betta;
593  if (fabs(partAll) > 0.00001) /* alpha must be > betta */
594  {
595 
596  partX = coeffs->Xcoef + coeffs->XcoefA * alpha +
597  coeffs->XcoefB * betta + coeffs->XcoefAB * alphabetta;
598 
599  partY = coeffs->Ycoef + coeffs->YcoefA * alpha +
600  coeffs->YcoefB * betta + coeffs->YcoefAB * alphabetta;
601 
602  partZ = coeffs->Zcoef + coeffs->ZcoefA * alpha +
603  coeffs->ZcoefB * betta + coeffs->ZcoefAB * alphabetta;
604 
605  invPartAll = 1.0 / partAll;
606 
607  point->x = partX * invPartAll;
608  point->y = partY * invPartAll;
609  point->z = partZ * invPartAll;
610  return CV_NO_ERR;
611  }
612  else
613  {
614  return CV_BADFACTOR_ERR;
615  }
616 }
617 
618 /*--------------------------------------------------------------------------------------*/
619 
620 /* Compute rotate matrix and trans vector for change system */
622  CvMatr64d transVect1,
623  CvMatr64d rotMatr2,
624  CvMatr64d transVect2,
625  CvMatr64d convRotMatr,
626  CvMatr64d convTransVect)
627 {
628  double invRotMatr2[9];
629  double tmpVect[3];
630 
631 
632  icvInvertMatrix_64d(rotMatr2, 3, invRotMatr2);
633  /* Test for error */
634 
635  icvMulMatrix_64d(rotMatr1,
636  3, 3,
637  invRotMatr2,
638  3, 3,
639  convRotMatr);
640 
641  icvMulMatrix_64d(convRotMatr,
642  3, 3,
643  transVect2,
644  1, 3,
645  tmpVect);
646 
647  icvSubVector_64d(transVect1, tmpVect, convTransVect, 3);
648 
649 
650  return CV_NO_ERR;
651 }
652 
653 /*--------------------------------------------------------------------------------------*/
654 
655 /* Compute point coordinates in other system */
657  CvPoint3D64d* M1,
658  CvMatr64d rotMatr,
659  CvMatr64d transVect
660  )
661 {
662  double tmpVect[3];
663 
664  icvMulMatrix_64d(rotMatr,
665  3, 3,
666  (double*)&M2,
667  1, 3,
668  tmpVect);
669 
670  icvAddVector_64d(tmpVect, transVect, (double*)M1, 3);
671 
672  return CV_NO_ERR;
673 }
674 /*--------------------------------------------------------------------------------------*/
675 
677  CvPoint2D64d point2,
678  CvPoint2D64d point3,
679  CvPoint2D64d point4,
680  CvMatr64d camMatr1,
681  CvMatr64d rotMatr1,
682  CvMatr64d transVect1,
683  CvMatr64d camMatr2,
684  CvMatr64d rotMatr2,
685  CvMatr64d transVect2,
686  CvStereoLineCoeff* coeffs,
687  int* needSwapCamera);
688 
689 static int icvComputeCoeffForStereoV3(double quad1[4][2],
690  double quad2[4][2],
691  int numScanlines,
692  CvMatr64d camMatr1,
693  CvMatr64d rotMatr1,
694  CvMatr64d transVect1,
695  CvMatr64d camMatr2,
696  CvMatr64d rotMatr2,
697  CvMatr64d transVect2,
698  CvStereoLineCoeff* startCoeffs,
699  int* needSwapCamera)
700 {
701  /* For each pair */
702  /* In this function we must define position of cameras */
703 
704  CvPoint2D64d point1;
705  CvPoint2D64d point2;
706  CvPoint2D64d point3;
707  CvPoint2D64d point4;
708 
709  int currLine;
710  *needSwapCamera = 0;
711  for (currLine = 0; currLine < numScanlines; currLine++)
712  {
713  /* Compute points */
714  double alpha = ((double)currLine) / ((double)(numScanlines)); /* maybe - 1 */
715 
716  point1.x = (1.0 - alpha) * quad1[0][0] + alpha * quad1[3][0];
717  point1.y = (1.0 - alpha) * quad1[0][1] + alpha * quad1[3][1];
718 
719  point2.x = (1.0 - alpha) * quad1[1][0] + alpha * quad1[2][0];
720  point2.y = (1.0 - alpha) * quad1[1][1] + alpha * quad1[2][1];
721 
722  point3.x = (1.0 - alpha) * quad2[0][0] + alpha * quad2[3][0];
723  point3.y = (1.0 - alpha) * quad2[0][1] + alpha * quad2[3][1];
724 
725  point4.x = (1.0 - alpha) * quad2[1][0] + alpha * quad2[2][0];
726  point4.y = (1.0 - alpha) * quad2[1][1] + alpha * quad2[2][1];
727 
728  /* We can compute coeffs for this line */
729  icvComCoeffForLine(point1,
730  point2,
731  point3,
732  point4,
733  camMatr1,
734  rotMatr1,
735  transVect1,
736  camMatr2,
737  rotMatr2,
738  transVect2,
739  &startCoeffs[currLine],
740  needSwapCamera);
741  }
742  return CV_NO_ERR;
743 }
744 /*--------------------------------------------------------------------------------------*/
745 
746 static int icvCvt_32f_64d(float* src, double* dst, int size);
747 
748 static int icvComputeCoeffForStereoNew(double quad1[4][2],
749  double quad2[4][2],
750  int numScanlines,
751  CvMatr32f camMatr1,
752  CvMatr32f rotMatr1,
753  CvMatr32f transVect1,
754  CvMatr32f camMatr2,
755  CvStereoLineCoeff* startCoeffs,
756  int* needSwapCamera)
757 {
758  /* Convert data */
759 
760  double camMatr1_64d[9];
761  double camMatr2_64d[9];
762 
763  double rotMatr1_64d[9];
764  double transVect1_64d[3];
765 
766  double rotMatr2_64d[9];
767  double transVect2_64d[3];
768 
769  icvCvt_32f_64d(camMatr1, camMatr1_64d, 9);
770  icvCvt_32f_64d(camMatr2, camMatr2_64d, 9);
771 
772  icvCvt_32f_64d(rotMatr1, rotMatr1_64d, 9);
773  icvCvt_32f_64d(transVect1, transVect1_64d, 3);
774 
775  rotMatr2_64d[0] = 1;
776  rotMatr2_64d[1] = 0;
777  rotMatr2_64d[2] = 0;
778  rotMatr2_64d[3] = 0;
779  rotMatr2_64d[4] = 1;
780  rotMatr2_64d[5] = 0;
781  rotMatr2_64d[6] = 0;
782  rotMatr2_64d[7] = 0;
783  rotMatr2_64d[8] = 1;
784 
785  transVect2_64d[0] = 0;
786  transVect2_64d[1] = 0;
787  transVect2_64d[2] = 0;
788 
789  int status = icvComputeCoeffForStereoV3(quad1,
790  quad2,
791  numScanlines,
792  camMatr1_64d,
793  rotMatr1_64d,
794  transVect1_64d,
795  camMatr2_64d,
796  rotMatr2_64d,
797  transVect2_64d,
798  startCoeffs,
799  needSwapCamera);
800 
801 
802  return status;
803 
804 }
805 /*--------------------------------------------------------------------------------------*/
806 int icvComputeCoeffForStereo(CvStereoCamera* stereoCamera)
807 {
808  double quad1[4][2];
809  double quad2[4][2];
810 
811  int i;
812  for (i = 0; i < 4; i++)
813  {
814  quad1[i][0] = stereoCamera->quad[0][i].x;
815  quad1[i][1] = stereoCamera->quad[0][i].y;
816 
817  quad2[i][0] = stereoCamera->quad[1][i].x;
818  quad2[i][1] = stereoCamera->quad[1][i].y;
819  }
820 
821  icvComputeCoeffForStereoNew(quad1,
822  quad2,
823  stereoCamera->warpSize.height,
824  stereoCamera->camera[0]->matrix,
825  stereoCamera->rotMatrix,
826  stereoCamera->transVector,
827  stereoCamera->camera[1]->matrix,
828  stereoCamera->lineCoeffs,
829  &(stereoCamera->needSwapCameras));
830  return CV_OK;
831 }
832 
834  CvPoint3D64d pointB,
835  CvPoint3D64d pointCam1,
836  double gamma,
837  CvStereoLineCoeff* coeffs);
838 
840  CvMatr64d camMatr,
841  CvPoint3D64d* direct);
842 
843 int icvGetCrossLines(CvPoint3D64d point11, CvPoint3D64d point12,
844  CvPoint3D64d point21, CvPoint3D64d point22,
845  CvPoint3D64d* midPoint);
846 
847 
848 /*--------------------------------------------------------------------------------------*/
850  CvPoint2D64d point2,
851  CvPoint2D64d point3,
852  CvPoint2D64d point4,
853  CvMatr64d camMatr1,
854  CvMatr64d rotMatr1,
855  CvMatr64d transVect1,
856  CvMatr64d camMatr2,
857  CvMatr64d rotMatr2,
858  CvMatr64d transVect2,
859  CvStereoLineCoeff* coeffs,
860  int* needSwapCamera)
861 {
862  /* Get direction for all points */
863  /* Direction for camera 1 */
864 
865  CvPoint3D64f direct1;
866  CvPoint3D64f direct2;
867  CvPoint3D64f camPoint1;
868 
869  CvPoint3D64f directS3;
870  CvPoint3D64f directS4;
871  CvPoint3D64f direct3;
872  CvPoint3D64f direct4;
873  CvPoint3D64f camPoint2;
874 
876  camMatr1,
877  &direct1);
878 
880  camMatr1,
881  &direct2);
882 
883  /* Direction for camera 2 */
884 
886  camMatr2,
887  &directS3);
888 
890  camMatr2,
891  &directS4);
892 
893  /* Create conversion for camera 2: two direction and camera point */
894 
895  double convRotMatr[9];
896  double convTransVect[3];
897 
898  icvCreateConvertMatrVect(rotMatr1,
899  transVect1,
900  rotMatr2,
901  transVect2,
902  convRotMatr,
903  convTransVect);
904 
905  CvPoint3D64f zeroVect;
906  zeroVect.x = zeroVect.y = zeroVect.z = 0.0;
907  camPoint1.x = camPoint1.y = camPoint1.z = 0.0;
908 
909  icvConvertPointSystem(directS3, &direct3, convRotMatr, convTransVect);
910  icvConvertPointSystem(directS4, &direct4, convRotMatr, convTransVect);
911  icvConvertPointSystem(zeroVect, &camPoint2, convRotMatr, convTransVect);
912 
913  CvPoint3D64f pointB;
914 
915  int postype = 0;
916 
917  /* Changed order */
918  /* Compute point B: xB,yB,zB */
919  icvGetCrossLines(camPoint1, direct2,
920  camPoint2, direct3,
921  &pointB);
922 
923  if (pointB.z < 0) /* If negative use other lines for cross */
924  {
925  postype = 1;
926  icvGetCrossLines(camPoint1, direct1,
927  camPoint2, direct4,
928  &pointB);
929  }
930 
931  CvPoint3D64d pointNewA;
932  CvPoint3D64d pointNewC;
933 
934  pointNewA.x = pointNewA.y = pointNewA.z = 0;
935  pointNewC.x = pointNewC.y = pointNewC.z = 0;
936 
937  if (postype == 0)
938  {
939  icvGetSymPoint3D(camPoint1,
940  direct1,
941  pointB,
942  &pointNewA);
943 
944  icvGetSymPoint3D(camPoint2,
945  direct4,
946  pointB,
947  &pointNewC);
948  }
949  else
950  {
951  /* In this case we must change cameras */
952  *needSwapCamera = 1;
953  icvGetSymPoint3D(camPoint2,
954  direct3,
955  pointB,
956  &pointNewA);
957 
958  icvGetSymPoint3D(camPoint1,
959  direct2,
960  pointB,
961  &pointNewC);
962  }
963 
964 
965  double gamma;
966 
967  double xA, yA, zA;
968  double xB, yB, zB;
969  double xC, yC, zC;
970 
971  xA = pointNewA.x;
972  yA = pointNewA.y;
973  zA = pointNewA.z;
974 
975  xB = pointB.x;
976  yB = pointB.y;
977  zB = pointB.z;
978 
979  xC = pointNewC.x;
980  yC = pointNewC.y;
981  zC = pointNewC.z;
982 
983  double len1, len2;
984  len1 = sqrt((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB) + (zA - zB) * (zA - zB));
985  len2 = sqrt((xB - xC) * (xB - xC) + (yB - yC) * (yB - yC) + (zB - zC) * (zB - zC));
986  gamma = len2 / len1;
987 
988  icvComputeStereoLineCoeffs(pointNewA,
989  pointB,
990  camPoint1,
991  gamma,
992  coeffs);
993 
994  return CV_NO_ERR;
995 }
996 
997 
998 /*--------------------------------------------------------------------------------------*/
999 
1001  CvMatr64d camMatr,
1002  CvPoint3D64d* direct)
1003 {
1004  /* */
1005  double invMatr[9];
1006 
1007  /* Invert matrix */
1008 
1009  icvInvertMatrix_64d(camMatr, 3, invMatr);
1010  /* TEST FOR ERRORS */
1011 
1012  double vect[3];
1013  vect[0] = point.x;
1014  vect[1] = point.y;
1015  vect[2] = 1;
1016 
1017  /* Mul matr */
1018  icvMulMatrix_64d(invMatr,
1019  3, 3,
1020  vect,
1021  1, 3,
1022  (double*)direct);
1023 
1024  return CV_NO_ERR;
1025 }
1026 
1027 /*--------------------------------------------------------------------------------------*/
1028 
1030  CvPoint3D64d point21, CvPoint3D64d point22,
1031  CvPoint3D64d* midPoint)
1032 {
1033  double xM, yM, zM;
1034  double xN, yN, zN;
1035 
1036  double xA, yA, zA;
1037  double xB, yB, zB;
1038 
1039  double xC, yC, zC;
1040  double xD, yD, zD;
1041 
1042  xA = point11.x;
1043  yA = point11.y;
1044  zA = point11.z;
1045 
1046  xB = point12.x;
1047  yB = point12.y;
1048  zB = point12.z;
1049 
1050  xC = point21.x;
1051  yC = point21.y;
1052  zC = point21.z;
1053 
1054  xD = point22.x;
1055  yD = point22.y;
1056  zD = point22.z;
1057 
1058  double a11, a12, a21, a22;
1059  double b1, b2;
1060 
1061  a11 = (xB - xA) * (xB - xA) + (yB - yA) * (yB - yA) + (zB - zA) * (zB - zA);
1062  a12 = -(xD - xC) * (xB - xA) - (yD - yC) * (yB - yA) - (zD - zC) * (zB - zA);
1063  a21 = (xB - xA) * (xD - xC) + (yB - yA) * (yD - yC) + (zB - zA) * (zD - zC);
1064  a22 = -(xD - xC) * (xD - xC) - (yD - yC) * (yD - yC) - (zD - zC) * (zD - zC);
1065  b1 = -((xA - xC) * (xB - xA) + (yA - yC) * (yB - yA) + (zA - zC) * (zB - zA));
1066  b2 = -((xA - xC) * (xD - xC) + (yA - yC) * (yD - yC) + (zA - zC) * (zD - zC));
1067 
1068  double delta;
1069  double deltaA, deltaB;
1070  double alpha, betta;
1071 
1072  delta = a11 * a22 - a12 * a21;
1073 
1074  if (fabs(delta) < EPS64D)
1075  {
1076  /*return ERROR;*/
1077  }
1078 
1079  deltaA = b1 * a22 - b2 * a12;
1080  deltaB = a11 * b2 - b1 * a21;
1081 
1082  alpha = deltaA / delta;
1083  betta = deltaB / delta;
1084 
1085  xM = xA + alpha * (xB - xA);
1086  yM = yA + alpha * (yB - yA);
1087  zM = zA + alpha * (zB - zA);
1088 
1089  xN = xC + betta * (xD - xC);
1090  yN = yC + betta * (yD - yC);
1091  zN = zC + betta * (zD - zC);
1092 
1093  /* Compute middle point */
1094  midPoint->x = (xM + xN) * 0.5;
1095  midPoint->y = (yM + yN) * 0.5;
1096  midPoint->z = (zM + zN) * 0.5;
1097 
1098  return CV_NO_ERR;
1099 }
1100 
1101 /*--------------------------------------------------------------------------------------*/
1102 
1104  CvPoint3D64d pointB,
1105  CvPoint3D64d pointCam1,
1106  double gamma,
1107  CvStereoLineCoeff* coeffs)
1108 {
1109  double x1, y1, z1;
1110 
1111  x1 = pointCam1.x;
1112  y1 = pointCam1.y;
1113  z1 = pointCam1.z;
1114 
1115  double xA, yA, zA;
1116  double xB, yB, zB;
1117 
1118  xA = pointA.x;
1119  yA = pointA.y;
1120  zA = pointA.z;
1121 
1122  xB = pointB.x;
1123  yB = pointB.y;
1124  zB = pointB.z;
1125 
1126  if (gamma > 0)
1127  {
1128  coeffs->Xcoef = -x1 + xA;
1129  coeffs->XcoefA = xB + x1 - xA;
1130  coeffs->XcoefB = -xA - gamma * x1 + gamma * xA;
1131  coeffs->XcoefAB = -xB + xA + gamma * xB - gamma * xA;
1132 
1133  coeffs->Ycoef = -y1 + yA;
1134  coeffs->YcoefA = yB + y1 - yA;
1135  coeffs->YcoefB = -yA - gamma * y1 + gamma * yA;
1136  coeffs->YcoefAB = -yB + yA + gamma * yB - gamma * yA;
1137 
1138  coeffs->Zcoef = -z1 + zA;
1139  coeffs->ZcoefA = zB + z1 - zA;
1140  coeffs->ZcoefB = -zA - gamma * z1 + gamma * zA;
1141  coeffs->ZcoefAB = -zB + zA + gamma * zB - gamma * zA;
1142  }
1143  else
1144  {
1145  gamma = - gamma;
1146  coeffs->Xcoef = -(-x1 + xA);
1147  coeffs->XcoefB = -(xB + x1 - xA);
1148  coeffs->XcoefA = -(-xA - gamma * x1 + gamma * xA);
1149  coeffs->XcoefAB = -(-xB + xA + gamma * xB - gamma * xA);
1150 
1151  coeffs->Ycoef = -(-y1 + yA);
1152  coeffs->YcoefB = -(yB + y1 - yA);
1153  coeffs->YcoefA = -(-yA - gamma * y1 + gamma * yA);
1154  coeffs->YcoefAB = -(-yB + yA + gamma * yB - gamma * yA);
1155 
1156  coeffs->Zcoef = -(-z1 + zA);
1157  coeffs->ZcoefB = -(zB + z1 - zA);
1158  coeffs->ZcoefA = -(-zA - gamma * z1 + gamma * zA);
1159  coeffs->ZcoefAB = -(-zB + zA + gamma * zB - gamma * zA);
1160  }
1161 
1162 
1163 
1164  return CV_NO_ERR;
1165 }
1166 /*--------------------------------------------------------------------------------------*/
1167 
1168 
1169 /*---------------------------------------------------------------------------------------*/
1170 
1171 /* This function get minimum angle started at point which contains rect */
1172 int icvGetAngleLine(CvPoint2D64d startPoint, CvSize imageSize, CvPoint2D64d* point1, CvPoint2D64d* point2)
1173 {
1174  /* Get crosslines with image corners */
1175 
1176  /* Find four lines */
1177 
1178  CvPoint2D64d pa, pb, pc, pd;
1179 
1180  pa.x = 0;
1181  pa.y = 0;
1182 
1183  pb.x = imageSize.width - 1;
1184  pb.y = 0;
1185 
1186  pd.x = imageSize.width - 1;
1187  pd.y = imageSize.height - 1;
1188 
1189  pc.x = 0;
1190  pc.y = imageSize.height - 1;
1191 
1192  /* We can compute points for angle */
1193  /* Test for place section */
1194 
1195  if (startPoint.x < 0)
1196  {
1197  /* 1,4,7 */
1198  if (startPoint.y < 0)
1199  {
1200  /* 1 */
1201  *point1 = pb;
1202  *point2 = pc;
1203  }
1204  else if (startPoint.y > imageSize.height - 1)
1205  {
1206  /* 7 */
1207  *point1 = pa;
1208  *point2 = pd;
1209  }
1210  else
1211  {
1212  /* 4 */
1213  *point1 = pa;
1214  *point2 = pc;
1215  }
1216  }
1217  else if (startPoint.x > imageSize.width - 1)
1218  {
1219  /* 3,6,9 */
1220  if (startPoint.y < 0)
1221  {
1222  /* 3 */
1223  *point1 = pa;
1224  *point2 = pd;
1225  }
1226  else if (startPoint.y > imageSize.height - 1)
1227  {
1228  /* 9 */
1229  *point1 = pb;
1230  *point2 = pc;
1231  }
1232  else
1233  {
1234  /* 6 */
1235  *point1 = pb;
1236  *point2 = pd;
1237  }
1238  }
1239  else
1240  {
1241  /* 2,5,8 */
1242  if (startPoint.y < 0)
1243  {
1244  /* 2 */
1245  if (startPoint.x < imageSize.width / 2)
1246  {
1247  *point1 = pb;
1248  *point2 = pa;
1249  }
1250  else
1251  {
1252  *point1 = pa;
1253  *point2 = pb;
1254  }
1255  }
1256  else if (startPoint.y > imageSize.height - 1)
1257  {
1258  /* 8 */
1259  if (startPoint.x < imageSize.width / 2)
1260  {
1261  *point1 = pc;
1262  *point2 = pd;
1263  }
1264  else
1265  {
1266  *point1 = pd;
1267  *point2 = pc;
1268  }
1269  }
1270  else
1271  {
1272  /* 5 - point in the image */
1273  return 2;
1274  }
1275  }
1276  return 0;
1277 }/* GetAngleLine */
1278 
1279 /*---------------------------------------------------------------------------------------*/
1280 
1282  double* a, double* b, double* c,
1283  int* result)
1284 {
1285  double det;
1286  double detA, detB, detC;
1287 
1288  det = p_start.x * p_end.y + p_end.x + p_start.y - p_end.y - p_start.y * p_end.x - p_start.x;
1289  if (fabs(det) < EPS64D)/* Error */
1290  {
1291  *result = 0;
1292  return;
1293  }
1294 
1295  detA = p_start.y - p_end.y;
1296  detB = p_end.x - p_start.x;
1297  detC = p_start.x * p_end.y - p_end.x * p_start.y;
1298 
1299  double invDet = 1.0 / det;
1300  *a = detA * invDet;
1301  *b = detB * invDet;
1302  *c = detC * invDet;
1303 
1304  *result = 1;
1305  return;
1306 }
1307 
1308 /*---------------------------------------------------------------------------------------*/
1309 
1310 #define icvTransformVector_64d( matr, src, dst, w, h ) \
1311  icvMulMatrix_64d( matr, w, h, src, 1, w, dst )
1312 
1313 void icvGetCrossRectDirect(CvSize imageSize,
1314  double a, double b, double c,
1315  CvPoint2D64d* start, CvPoint2D64d* end,
1316  int* result);
1317 
1318 /* Get common area of rectifying */
1319 static void icvGetCommonArea(CvSize imageSize,
1320  CvPoint3D64d epipole1, CvPoint3D64d epipole2,
1321  CvMatr64d fundMatr,
1322  CvVect64d coeff11, CvVect64d coeff12,
1323  CvVect64d coeff21, CvVect64d coeff22,
1324  int* result)
1325 {
1326  int res = 0;
1327  CvPoint2D64d point11;
1328  CvPoint2D64d point12;
1329  CvPoint2D64d point21;
1330  CvPoint2D64d point22;
1331 
1332  double corr11[3];
1333  double corr12[3];
1334  double corr21[3];
1335  double corr22[3];
1336 
1337  double pointW11[3];
1338  double pointW12[3];
1339  double pointW21[3];
1340  double pointW22[3];
1341 
1342  double transFundMatr[3 * 3];
1343  /* Compute transpose of fundamental matrix */
1344  icvTransposeMatrix_64d(fundMatr, 3, 3, transFundMatr);
1345 
1346  CvPoint2D64d epipole1_2d;
1347  CvPoint2D64d epipole2_2d;
1348 
1349  if (fabs(epipole1.z) < 1e-8)
1350  {
1351  /* epipole1 in infinity */
1352  *result = 0;
1353  return;
1354  }
1355  epipole1_2d.x = epipole1.x / epipole1.z;
1356  epipole1_2d.y = epipole1.y / epipole1.z;
1357 
1358  if (fabs(epipole2.z) < 1e-8)
1359  {
1360  /* epipole2 in infinity */
1361  *result = 0;
1362  return;
1363  }
1364  epipole2_2d.x = epipole2.x / epipole2.z;
1365  epipole2_2d.y = epipole2.y / epipole2.z;
1366 
1367  int stat = icvGetAngleLine(epipole1_2d, imageSize, &point11, &point12);
1368  if (stat == 2)
1369  {
1370  /* No angle */
1371  *result = 0;
1372  return;
1373  }
1374 
1375  stat = icvGetAngleLine(epipole2_2d, imageSize, &point21, &point22);
1376  if (stat == 2)
1377  {
1378  /* No angle */
1379  *result = 0;
1380  return;
1381  }
1382 
1383  /* ============= Computation for line 1 ================ */
1384  /* Find correspondence line for angle points11 */
1385  /* corr21 = Fund'*p1 */
1386 
1387  pointW11[0] = point11.x;
1388  pointW11[1] = point11.y;
1389  pointW11[2] = 1.0;
1390 
1391  icvTransformVector_64d(transFundMatr, /* !!! Modified from not transposed */
1392  pointW11,
1393  corr21,
1394  3, 3);
1395 
1396  /* Find crossing of line with image 2 */
1397  CvPoint2D64d start;
1398  CvPoint2D64d end;
1399  icvGetCrossRectDirect(imageSize,
1400  corr21[0], corr21[1], corr21[2],
1401  &start, &end,
1402  &res);
1403 
1404  if (res == 0)
1405  {
1406  /* We have not cross */
1407  /* We must define new angle */
1408 
1409  pointW21[0] = point21.x;
1410  pointW21[1] = point21.y;
1411  pointW21[2] = 1.0;
1412 
1413  /* Find correspondence line for this angle points */
1414  /* We know point and try to get corr line */
1415  /* For point21 */
1416  /* corr11 = Fund * p21 */
1417 
1418  icvTransformVector_64d(fundMatr, /* !!! Modified */
1419  pointW21,
1420  corr11,
1421  3, 3);
1422 
1423  /* We have cross. And it's result cross for up line. Set result coefs */
1424 
1425  /* Set coefs for line 1 image 1 */
1426  coeff11[0] = corr11[0];
1427  coeff11[1] = corr11[1];
1428  coeff11[2] = corr11[2];
1429 
1430  /* Set coefs for line 1 image 2 */
1431  icvGetCoefForPiece(epipole2_2d, point21,
1432  &coeff21[0], &coeff21[1], &coeff21[2],
1433  &res);
1434  if (res == 0)
1435  {
1436  *result = 0;
1437  return;/* Error */
1438  }
1439  }
1440  else
1441  {
1442  /* Line 1 cross image 2 */
1443  /* Set coefs for line 1 image 1 */
1444  icvGetCoefForPiece(epipole1_2d, point11,
1445  &coeff11[0], &coeff11[1], &coeff11[2],
1446  &res);
1447  if (res == 0)
1448  {
1449  *result = 0;
1450  return;/* Error */
1451  }
1452 
1453  /* Set coefs for line 1 image 2 */
1454  coeff21[0] = corr21[0];
1455  coeff21[1] = corr21[1];
1456  coeff21[2] = corr21[2];
1457 
1458  }
1459 
1460  /* ============= Computation for line 2 ================ */
1461  /* Find correspondence line for angle points11 */
1462  /* corr22 = Fund*p2 */
1463 
1464  pointW12[0] = point12.x;
1465  pointW12[1] = point12.y;
1466  pointW12[2] = 1.0;
1467 
1468  icvTransformVector_64d(transFundMatr,
1469  pointW12,
1470  corr22,
1471  3, 3);
1472 
1473  /* Find crossing of line with image 2 */
1474  icvGetCrossRectDirect(imageSize,
1475  corr22[0], corr22[1], corr22[2],
1476  &start, &end,
1477  &res);
1478 
1479  if (res == 0)
1480  {
1481  /* We have not cross */
1482  /* We must define new angle */
1483 
1484  pointW22[0] = point22.x;
1485  pointW22[1] = point22.y;
1486  pointW22[2] = 1.0;
1487 
1488  /* Find correspondence line for this angle points */
1489  /* We know point and try to get corr line */
1490  /* For point21 */
1491  /* corr2 = Fund' * p1 */
1492 
1493  icvTransformVector_64d(fundMatr,
1494  pointW22,
1495  corr12,
1496  3, 3);
1497 
1498 
1499  /* We have cross. And it's result cross for down line. Set result coefs */
1500 
1501  /* Set coefs for line 2 image 1 */
1502  coeff12[0] = corr12[0];
1503  coeff12[1] = corr12[1];
1504  coeff12[2] = corr12[2];
1505 
1506  /* Set coefs for line 1 image 2 */
1507  icvGetCoefForPiece(epipole2_2d, point22,
1508  &coeff22[0], &coeff22[1], &coeff22[2],
1509  &res);
1510  if (res == 0)
1511  {
1512  *result = 0;
1513  return;/* Error */
1514  }
1515  }
1516  else
1517  {
1518  /* Line 2 cross image 2 */
1519  /* Set coefs for line 2 image 1 */
1520  icvGetCoefForPiece(epipole1_2d, point12,
1521  &coeff12[0], &coeff12[1], &coeff12[2],
1522  &res);
1523  if (res == 0)
1524  {
1525  *result = 0;
1526  return;/* Error */
1527  }
1528 
1529  /* Set coefs for line 1 image 2 */
1530  coeff22[0] = corr22[0];
1531  coeff22[1] = corr22[1];
1532  coeff22[2] = corr22[2];
1533 
1534  }
1535 
1536  /* Now we know common area */
1537 
1538  return;
1539 
1540 }/* GetCommonArea */
1541 
1542 /*---------------------------------------------------------------------------------------*/
1543 
1544 /* Get cross for direction1 and direction2 */
1545 /* Result = 1 - cross */
1546 /* Result = 2 - parallel and not equal */
1547 /* Result = 3 - parallel and equal */
1548 
1550  CvPoint2D64d* cross, int* result)
1551 {
1552  double det = direct1[0] * direct2[1] - direct2[0] * direct1[1];
1553  double detx = -direct1[2] * direct2[1] + direct1[1] * direct2[2];
1554 
1555  if (fabs(det) > EPS64D)
1556  {
1557  /* Have cross */
1558  cross->x = detx / det;
1559  cross->y = (-direct1[0] * direct2[2] + direct2[0] * direct1[2]) / det;
1560  *result = 1;
1561  }
1562  else
1563  {
1564  /* may be parallel */
1565  if (fabs(detx) > EPS64D)
1566  {
1567  /* parallel and not equal */
1568  *result = 2;
1569  }
1570  else
1571  {
1572  /* equals */
1573  *result = 3;
1574  }
1575  }
1576 
1577  return;
1578 }
1579 
1580 /*---------------------------------------------------------------------------------------*/
1581 
1582 /* Get cross for piece p1,p2 and direction a,b,c */
1583 /* Result = 0 - no cross */
1584 /* Result = 1 - cross */
1585 /* Result = 2 - parallel and not equal */
1586 /* Result = 3 - parallel and equal */
1587 
1589  double a, double b, double c,
1590  CvPoint2D64d* cross, int* result)
1591 {
1592 
1593  if ((a * p_start.x + b * p_start.y + c) * (a * p_end.x + b * p_end.y + c) <= 0)
1594  {
1595  /* Have cross */
1596  double det;
1597  double detxc, detyc;
1598 
1599  det = a * (p_end.x - p_start.x) + b * (p_end.y - p_start.y);
1600 
1601  if (fabs(det) < EPS64D)
1602  {
1603  /* lines are parallel and may be equal or line is point */
1604  if (fabs(a * p_start.x + b * p_start.y + c) < EPS64D)
1605  {
1606  /* line is point or not diff */
1607  *result = 3;
1608  return;
1609  }
1610  else
1611  {
1612  *result = 2;
1613  }
1614  return;
1615  }
1616 
1617  detxc = b * (p_end.y * p_start.x - p_start.y * p_end.x) + c * (p_start.x - p_end.x);
1618  detyc = a * (p_end.x * p_start.y - p_start.x * p_end.y) + c * (p_start.y - p_end.y);
1619 
1620  cross->x = detxc / det;
1621  cross->y = detyc / det;
1622  *result = 1;
1623 
1624  }
1625  else
1626  {
1627  *result = 0;
1628  }
1629  return;
1630 }
1631 /*--------------------------------------------------------------------------------------*/
1632 
1634  CvPoint2D64d p2_start, CvPoint2D64d p2_end,
1636  int* result)
1637 {
1638  double ex1, ey1, ex2, ey2;
1639  double px1, py1, px2, py2;
1640  double del;
1641  double delA, delB, delX, delY;
1642  double alpha, betta;
1643 
1644  ex1 = p1_start.x;
1645  ey1 = p1_start.y;
1646  ex2 = p1_end.x;
1647  ey2 = p1_end.y;
1648 
1649  px1 = p2_start.x;
1650  py1 = p2_start.y;
1651  px2 = p2_end.x;
1652  py2 = p2_end.y;
1653 
1654  del = (py1 - py2) * (ex1 - ex2) - (px1 - px2) * (ey1 - ey2);
1655  if (fabs(del) <= EPS64D)
1656  {
1657  /* May be they are parallel !!! */
1658  *result = 0;
1659  return;
1660  }
1661 
1662  delA = (ey1 - ey2) * (ex1 - px1) + (ex1 - ex2) * (py1 - ey1);
1663  delB = (py1 - py2) * (ex1 - px1) + (px1 - px2) * (py1 - ey1);
1664 
1665  alpha = delA / del;
1666  betta = delB / del;
1667 
1668  if (alpha < 0 || alpha > 1.0 || betta < 0 || betta > 1.0)
1669  {
1670  *result = 0;
1671  return;
1672  }
1673 
1674  delX = (px1 - px2) * (ey1 * (ex1 - ex2) - ex1 * (ey1 - ey2)) +
1675  (ex1 - ex2) * (px1 * (py1 - py2) - py1 * (px1 - px2));
1676 
1677  delY = (py1 - py2) * (ey1 * (ex1 - ex2) - ex1 * (ey1 - ey2)) +
1678  (ey1 - ey2) * (px1 * (py1 - py2) - py1 * (px1 - px2));
1679 
1680  cross->x = delX / del;
1681  cross->y = delY / del;
1682 
1683  *result = 1;
1684  return;
1685 }
1686 
1687 
1688 /*---------------------------------------------------------------------------------------*/
1689 
1690 void icvGetPieceLength(CvPoint2D64d point1, CvPoint2D64d point2, double* dist)
1691 {
1692  double dx = point2.x - point1.x;
1693  double dy = point2.y - point1.y;
1694  *dist = sqrt(dx * dx + dy * dy);
1695  return;
1696 }
1697 
1698 /*---------------------------------------------------------------------------------------*/
1699 
1700 void icvGetPieceLength3D(CvPoint3D64d point1, CvPoint3D64d point2, double* dist)
1701 {
1702  double dx = point2.x - point1.x;
1703  double dy = point2.y - point1.y;
1704  double dz = point2.z - point1.z;
1705  *dist = sqrt(dx * dx + dy * dy + dz * dz);
1706  return;
1707 }
1708 
1709 /*---------------------------------------------------------------------------------------*/
1710 
1711 /* Find line from epipole which cross image rect */
1712 /* Find points of cross 0 or 1 or 2. Return number of points in cross */
1713 void icvGetCrossRectDirect(CvSize imageSize,
1714  double a, double b, double c,
1715  CvPoint2D64d* start, CvPoint2D64d* end,
1716  int* result)
1717 {
1718  CvPoint2D64d frameBeg;
1719  CvPoint2D64d frameEnd;
1720  CvPoint2D64d cross[4];
1721  int haveCross[4];
1722 
1723  haveCross[0] = 0;
1724  haveCross[1] = 0;
1725  haveCross[2] = 0;
1726  haveCross[3] = 0;
1727 
1728  frameBeg.x = 0;
1729  frameBeg.y = 0;
1730  frameEnd.x = imageSize.width;
1731  frameEnd.y = 0;
1732 
1733  icvGetCrossPieceDirect(frameBeg, frameEnd, a, b, c, &cross[0], &haveCross[0]);
1734 
1735  frameBeg.x = imageSize.width;
1736  frameBeg.y = 0;
1737  frameEnd.x = imageSize.width;
1738  frameEnd.y = imageSize.height;
1739  icvGetCrossPieceDirect(frameBeg, frameEnd, a, b, c, &cross[1], &haveCross[1]);
1740 
1741  frameBeg.x = imageSize.width;
1742  frameBeg.y = imageSize.height;
1743  frameEnd.x = 0;
1744  frameEnd.y = imageSize.height;
1745  icvGetCrossPieceDirect(frameBeg, frameEnd, a, b, c, &cross[2], &haveCross[2]);
1746 
1747  frameBeg.x = 0;
1748  frameBeg.y = imageSize.height;
1749  frameEnd.x = 0;
1750  frameEnd.y = 0;
1751  icvGetCrossPieceDirect(frameBeg, frameEnd, a, b, c, &cross[3], &haveCross[3]);
1752 
1753  double maxDist;
1754 
1755  int maxI = 0, maxJ = 0;
1756 
1757 
1758  int i, j;
1759 
1760  maxDist = -1.0;
1761 
1762  double distance;
1763 
1764  for (i = 0; i < 3; i++)
1765  {
1766  if (haveCross[i] == 1)
1767  {
1768  for (j = i + 1; j < 4; j++)
1769  {
1770  if (haveCross[j] == 1)
1771  {
1772  /* Compute dist */
1774  if (distance > maxDist)
1775  {
1776  maxI = i;
1777  maxJ = j;
1778  maxDist = distance;
1779  }
1780  }
1781  }
1782  }
1783  }
1784 
1785  if (maxDist >= 0)
1786  {
1787  /* We have cross */
1788  *start = cross[maxI];
1789  *result = 1;
1790  if (maxDist > 0)
1791  {
1792  *end = cross[maxJ];
1793  *result = 2;
1794  }
1795  }
1796  else
1797  {
1798  *result = 0;
1799  }
1800 
1801  return;
1802 }/* GetCrossRectDirect */
1803 
1804 /*---------------------------------------------------------------------------------------*/
1806  CvMatr64d camMatr, CvMatr64d rotMatr, CvVect64d transVect,
1807  CvPoint2D64d* projPoint)
1808 {
1809 
1810  double tmpVect1[3];
1811  double tmpVect2[3];
1812 
1813  icvMulMatrix_64d(rotMatr,
1814  3, 3,
1815  (double*)&point,
1816  1, 3,
1817  tmpVect1);
1818 
1819  icvAddVector_64d(tmpVect1, transVect, tmpVect2, 3);
1820 
1821  icvMulMatrix_64d(camMatr,
1822  3, 3,
1823  tmpVect2,
1824  1, 3,
1825  tmpVect1);
1826 
1827  projPoint->x = tmpVect1[0] / tmpVect1[2];
1828  projPoint->y = tmpVect1[1] / tmpVect1[2];
1829 
1830  return;
1831 }
1832 
1833 static int icvCvt_64d_32f(double* src, float* dst, int size);
1834 
1835 void icvGetCutPiece(CvVect64d areaLineCoef1, CvVect64d areaLineCoef2,
1836  CvPoint2D64d epipole,
1837  CvSize imageSize,
1838  CvPoint2D64d* point11, CvPoint2D64d* point12,
1839  CvPoint2D64d* point21, CvPoint2D64d* point22,
1840  int* result);
1841 
1843  CvMatr64d camMatr1,
1844  CvMatr64d camMatr2,
1845  CvPoint2D32f point1,
1846  CvPoint2D32f* point2);
1847 
1849  CvMatr64d camMatr1,
1850  CvMatr64d camMatr2,
1851  CvPoint2D32f* point1,
1852  CvPoint2D32f point2);
1853 
1854 /*---------------------------------------------------------------------------------------*/
1855 /* Get quads for transform images */
1857  CvSize imageSize,
1858  CvMatr64d camMatr1,
1859  CvMatr64d rotMatr1,
1860  CvVect64d transVect1,
1861  CvMatr64d camMatr2,
1862  CvMatr64d rotMatr2,
1863  CvVect64d transVect2,
1864  CvSize* warpSize,
1865  double quad1[4][2],
1866  double quad2[4][2],
1867  CvMatr64d fundMatr,
1868  CvPoint3D64d* epipole1,
1869  CvPoint3D64d* epipole2
1870 )
1871 {
1872  /* First compute fundamental matrix and epipoles */
1873  int res;
1874 
1875 
1876  /* Compute epipoles and fundamental matrix using new functions */
1877  {
1878  double convRotMatr[9];
1879  double convTransVect[3];
1880 
1881  icvCreateConvertMatrVect(rotMatr1,
1882  transVect1,
1883  rotMatr2,
1884  transVect2,
1885  convRotMatr,
1886  convTransVect);
1887  float convRotMatr_32f[9];
1888  float convTransVect_32f[3];
1889 
1890  icvCvt_64d_32f(convRotMatr, convRotMatr_32f, 9);
1891  icvCvt_64d_32f(convTransVect, convTransVect_32f, 3);
1892 
1893  /* We know R and t */
1894  /* Compute essential matrix */
1895  float essMatr[9];
1896  float fundMatr_32f[9];
1897 
1898  float camMatr1_32f[9];
1899  float camMatr2_32f[9];
1900 
1901  icvCvt_64d_32f(camMatr1, camMatr1_32f, 9);
1902  icvCvt_64d_32f(camMatr2, camMatr2_32f, 9);
1903 
1904  cvComputeEssentialMatrix(convRotMatr_32f,
1905  convTransVect_32f,
1906  essMatr);
1907 
1909  fundMatr_32f,
1910  camMatr1_32f,
1911  camMatr2_32f);
1912 
1913  CvPoint3D32f epipole1_32f;
1914  CvPoint3D32f epipole2_32f;
1915 
1916  cvComputeEpipolesFromFundMatrix(fundMatr_32f,
1917  &epipole1_32f,
1918  &epipole2_32f);
1919  /* copy to 64d epipoles */
1920  epipole1->x = epipole1_32f.x;
1921  epipole1->y = epipole1_32f.y;
1922  epipole1->z = epipole1_32f.z;
1923 
1924  epipole2->x = epipole2_32f.x;
1925  epipole2->y = epipole2_32f.y;
1926  epipole2->z = epipole2_32f.z;
1927 
1928  /* Convert fundamental matrix */
1929  icvCvt_32f_64d(fundMatr_32f, fundMatr, 9);
1930  }
1931 
1932  double coeff11[3];
1933  double coeff12[3];
1934  double coeff21[3];
1935  double coeff22[3];
1936 
1937  icvGetCommonArea(imageSize,
1938  *epipole1, *epipole2,
1939  fundMatr,
1940  coeff11, coeff12,
1941  coeff21, coeff22,
1942  &res);
1943 
1944  CvPoint2D64d point11, point12, point21, point22;
1945  double width1, width2;
1946  double height1, height2;
1947  double tmpHeight1, tmpHeight2;
1948 
1949  CvPoint2D64d epipole1_2d;
1950  CvPoint2D64d epipole2_2d;
1951 
1952  /* ----- Image 1 ----- */
1953  if (fabs(epipole1->z) < 1e-8)
1954  {
1955  return;
1956  }
1957  epipole1_2d.x = epipole1->x / epipole1->z;
1958  epipole1_2d.y = epipole1->y / epipole1->z;
1959 
1960  icvGetCutPiece(coeff11, coeff12,
1961  epipole1_2d,
1962  imageSize,
1963  &point11, &point12,
1964  &point21, &point22,
1965  &res);
1966 
1967  /* Compute distance */
1968  icvGetPieceLength(point11, point21, &width1);
1969  icvGetPieceLength(point11, point12, &tmpHeight1);
1970  icvGetPieceLength(point21, point22, &tmpHeight2);
1971  height1 = MAX(tmpHeight1, tmpHeight2);
1972 
1973  quad1[0][0] = point11.x;
1974  quad1[0][1] = point11.y;
1975 
1976  quad1[1][0] = point21.x;
1977  quad1[1][1] = point21.y;
1978 
1979  quad1[2][0] = point22.x;
1980  quad1[2][1] = point22.y;
1981 
1982  quad1[3][0] = point12.x;
1983  quad1[3][1] = point12.y;
1984 
1985  /* ----- Image 2 ----- */
1986  if (fabs(epipole2->z) < 1e-8)
1987  {
1988  return;
1989  }
1990  epipole2_2d.x = epipole2->x / epipole2->z;
1991  epipole2_2d.y = epipole2->y / epipole2->z;
1992 
1993  icvGetCutPiece(coeff21, coeff22,
1994  epipole2_2d,
1995  imageSize,
1996  &point11, &point12,
1997  &point21, &point22,
1998  &res);
1999 
2000  /* Compute distance */
2001  icvGetPieceLength(point11, point21, &width2);
2002  icvGetPieceLength(point11, point12, &tmpHeight1);
2003  icvGetPieceLength(point21, point22, &tmpHeight2);
2004  height2 = MAX(tmpHeight1, tmpHeight2);
2005 
2006  quad2[0][0] = point11.x;
2007  quad2[0][1] = point11.y;
2008 
2009  quad2[1][0] = point21.x;
2010  quad2[1][1] = point21.y;
2011 
2012  quad2[2][0] = point22.x;
2013  quad2[2][1] = point22.y;
2014 
2015  quad2[3][0] = point12.x;
2016  quad2[3][1] = point12.y;
2017 
2018 
2019  /*=======================================================*/
2020  /* This is a new additional way to compute quads. */
2021  /* We must correct quads */
2022  {
2023  double convRotMatr[9];
2024  double convTransVect[3];
2025 
2026  double newQuad1[4][2];
2027  double newQuad2[4][2];
2028 
2029 
2030  icvCreateConvertMatrVect(rotMatr1,
2031  transVect1,
2032  rotMatr2,
2033  transVect2,
2034  convRotMatr,
2035  convTransVect);
2036 
2037  /* -------------Compute for first image-------------- */
2038  CvPoint2D32f pointb1;
2039  CvPoint2D32f pointe1;
2040 
2041  CvPoint2D32f pointb2;
2042  CvPoint2D32f pointe2;
2043 
2044  pointb1.x = (float)quad1[0][0];
2045  pointb1.y = (float)quad1[0][1];
2046 
2047  pointe1.x = (float)quad1[3][0];
2048  pointe1.y = (float)quad1[3][1];
2049 
2050  icvComputeeInfiniteProject1(convRotMatr,
2051  camMatr1,
2052  camMatr2,
2053  pointb1,
2054  &pointb2);
2055 
2056  icvComputeeInfiniteProject1(convRotMatr,
2057  camMatr1,
2058  camMatr2,
2059  pointe1,
2060  &pointe2);
2061 
2062  /* JUST TEST FOR POINT */
2063 
2064  /* Compute distances */
2065  double dxOld, dyOld;
2066  double dxNew, dyNew;
2067  double distOld, distNew;
2068 
2069  dxOld = quad2[1][0] - quad2[0][0];
2070  dyOld = quad2[1][1] - quad2[0][1];
2071  distOld = dxOld * dxOld + dyOld * dyOld;
2072 
2073  dxNew = quad2[1][0] - pointb2.x;
2074  dyNew = quad2[1][1] - pointb2.y;
2075  distNew = dxNew * dxNew + dyNew * dyNew;
2076 
2077  if (distNew > distOld)
2078  {
2079  /* Get new points for second quad */
2080  newQuad2[0][0] = pointb2.x;
2081  newQuad2[0][1] = pointb2.y;
2082  newQuad2[3][0] = pointe2.x;
2083  newQuad2[3][1] = pointe2.y;
2084  newQuad1[0][0] = quad1[0][0];
2085  newQuad1[0][1] = quad1[0][1];
2086  newQuad1[3][0] = quad1[3][0];
2087  newQuad1[3][1] = quad1[3][1];
2088  }
2089  else
2090  {
2091  /* Get new points for first quad */
2092 
2093  pointb2.x = (float)quad2[0][0];
2094  pointb2.y = (float)quad2[0][1];
2095 
2096  pointe2.x = (float)quad2[3][0];
2097  pointe2.y = (float)quad2[3][1];
2098 
2099  icvComputeeInfiniteProject2(convRotMatr,
2100  camMatr1,
2101  camMatr2,
2102  &pointb1,
2103  pointb2);
2104 
2105  icvComputeeInfiniteProject2(convRotMatr,
2106  camMatr1,
2107  camMatr2,
2108  &pointe1,
2109  pointe2);
2110 
2111 
2112  /* JUST TEST FOR POINT */
2113 
2114  newQuad2[0][0] = quad2[0][0];
2115  newQuad2[0][1] = quad2[0][1];
2116  newQuad2[3][0] = quad2[3][0];
2117  newQuad2[3][1] = quad2[3][1];
2118 
2119  newQuad1[0][0] = pointb1.x;
2120  newQuad1[0][1] = pointb1.y;
2121  newQuad1[3][0] = pointe1.x;
2122  newQuad1[3][1] = pointe1.y;
2123  }
2124 
2125  /* -------------Compute for second image-------------- */
2126  pointb1.x = (float)quad1[1][0];
2127  pointb1.y = (float)quad1[1][1];
2128 
2129  pointe1.x = (float)quad1[2][0];
2130  pointe1.y = (float)quad1[2][1];
2131 
2132  icvComputeeInfiniteProject1(convRotMatr,
2133  camMatr1,
2134  camMatr2,
2135  pointb1,
2136  &pointb2);
2137 
2138  icvComputeeInfiniteProject1(convRotMatr,
2139  camMatr1,
2140  camMatr2,
2141  pointe1,
2142  &pointe2);
2143 
2144  /* Compute distances */
2145 
2146  dxOld = quad2[0][0] - quad2[1][0];
2147  dyOld = quad2[0][1] - quad2[1][1];
2148  distOld = dxOld * dxOld + dyOld * dyOld;
2149 
2150  dxNew = quad2[0][0] - pointb2.x;
2151  dyNew = quad2[0][1] - pointb2.y;
2152  distNew = dxNew * dxNew + dyNew * dyNew;
2153 
2154  if (distNew > distOld)
2155  {
2156  /* Get new points for second quad */
2157  newQuad2[1][0] = pointb2.x;
2158  newQuad2[1][1] = pointb2.y;
2159  newQuad2[2][0] = pointe2.x;
2160  newQuad2[2][1] = pointe2.y;
2161  newQuad1[1][0] = quad1[1][0];
2162  newQuad1[1][1] = quad1[1][1];
2163  newQuad1[2][0] = quad1[2][0];
2164  newQuad1[2][1] = quad1[2][1];
2165  }
2166  else
2167  {
2168  /* Get new points for first quad */
2169 
2170  pointb2.x = (float)quad2[1][0];
2171  pointb2.y = (float)quad2[1][1];
2172 
2173  pointe2.x = (float)quad2[2][0];
2174  pointe2.y = (float)quad2[2][1];
2175 
2176  icvComputeeInfiniteProject2(convRotMatr,
2177  camMatr1,
2178  camMatr2,
2179  &pointb1,
2180  pointb2);
2181 
2182  icvComputeeInfiniteProject2(convRotMatr,
2183  camMatr1,
2184  camMatr2,
2185  &pointe1,
2186  pointe2);
2187 
2188  newQuad2[1][0] = quad2[1][0];
2189  newQuad2[1][1] = quad2[1][1];
2190  newQuad2[2][0] = quad2[2][0];
2191  newQuad2[2][1] = quad2[2][1];
2192 
2193  newQuad1[1][0] = pointb1.x;
2194  newQuad1[1][1] = pointb1.y;
2195  newQuad1[2][0] = pointe1.x;
2196  newQuad1[2][1] = pointe1.y;
2197  }
2198 
2199 
2200 
2201  /*-------------------------------------------------------------------------------*/
2202 
2203  /* Copy new quads to old quad */
2204  int i;
2205  for (i = 0; i < 4; i++)
2206  {
2207  {
2208  quad1[i][0] = newQuad1[i][0];
2209  quad1[i][1] = newQuad1[i][1];
2210  quad2[i][0] = newQuad2[i][0];
2211  quad2[i][1] = newQuad2[i][1];
2212  }
2213  }
2214  }
2215  /*=======================================================*/
2216 
2217  double warpWidth, warpHeight;
2218 
2219  warpWidth = MAX(width1, width2);
2220  warpHeight = MAX(height1, height2);
2221 
2222  warpSize->width = (int)warpWidth;
2223  warpSize->height = (int)warpHeight;
2224 
2225  warpSize->width = cvRound(warpWidth - 1);
2226  warpSize->height = cvRound(warpHeight - 1);
2227 
2228  /* !!! by Valery Mosyagin. this lines added just for test no warp */
2229  warpSize->width = imageSize.width;
2230  warpSize->height = imageSize.height;
2231 
2232  return;
2233 }
2234 
2235 
2236 /*---------------------------------------------------------------------------------------*/
2237 
2238 static void icvGetQuadsTransformNew(CvSize imageSize,
2239  CvMatr32f camMatr1,
2240  CvMatr32f camMatr2,
2241  CvMatr32f rotMatr1,
2242  CvVect32f transVect1,
2243  CvSize* warpSize,
2244  double quad1[4][2],
2245  double quad2[4][2],
2246  CvMatr32f fundMatr,
2247  CvPoint3D32f* epipole1,
2248  CvPoint3D32f* epipole2
2249  )
2250 {
2251  /* Convert data */
2252  /* Convert camera matrix */
2253  double camMatr1_64d[9];
2254  double camMatr2_64d[9];
2255  double rotMatr1_64d[9];
2256  double transVect1_64d[3];
2257  double rotMatr2_64d[9];
2258  double transVect2_64d[3];
2259  double fundMatr_64d[9];
2260  CvPoint3D64d epipole1_64d;
2261  CvPoint3D64d epipole2_64d;
2262 
2263  icvCvt_32f_64d(camMatr1, camMatr1_64d, 9);
2264  icvCvt_32f_64d(camMatr2, camMatr2_64d, 9);
2265  icvCvt_32f_64d(rotMatr1, rotMatr1_64d, 9);
2266  icvCvt_32f_64d(transVect1, transVect1_64d, 3);
2267 
2268  /* Create vector and matrix */
2269 
2270  rotMatr2_64d[0] = 1;
2271  rotMatr2_64d[1] = 0;
2272  rotMatr2_64d[2] = 0;
2273  rotMatr2_64d[3] = 0;
2274  rotMatr2_64d[4] = 1;
2275  rotMatr2_64d[5] = 0;
2276  rotMatr2_64d[6] = 0;
2277  rotMatr2_64d[7] = 0;
2278  rotMatr2_64d[8] = 1;
2279 
2280  transVect2_64d[0] = 0;
2281  transVect2_64d[1] = 0;
2282  transVect2_64d[2] = 0;
2283 
2284  icvGetQuadsTransform(imageSize,
2285  camMatr1_64d,
2286  rotMatr1_64d,
2287  transVect1_64d,
2288  camMatr2_64d,
2289  rotMatr2_64d,
2290  transVect2_64d,
2291  warpSize,
2292  quad1,
2293  quad2,
2294  fundMatr_64d,
2295  &epipole1_64d,
2296  &epipole2_64d
2297  );
2298 
2299  /* Convert epipoles */
2300  epipole1->x = (float)(epipole1_64d.x);
2301  epipole1->y = (float)(epipole1_64d.y);
2302  epipole1->z = (float)(epipole1_64d.z);
2303 
2304  epipole2->x = (float)(epipole2_64d.x);
2305  epipole2->y = (float)(epipole2_64d.y);
2306  epipole2->z = (float)(epipole2_64d.z);
2307 
2308  /* Convert fundamental matrix */
2309  icvCvt_64d_32f(fundMatr_64d, fundMatr, 9);
2310 
2311  return;
2312 }
2313 
2314 /*---------------------------------------------------------------------------------------*/
2315 void icvGetQuadsTransformStruct(CvStereoCamera* stereoCamera)
2316 {
2317  /* Wrapper for icvGetQuadsTransformNew */
2318 
2319 
2320  double quad1[4][2];
2321  double quad2[4][2];
2322 
2323  icvGetQuadsTransformNew(cvSize(cvRound(stereoCamera->camera[0]->imgSize[0]), cvRound(stereoCamera->camera[0]->imgSize[1])),
2324  stereoCamera->camera[0]->matrix,
2325  stereoCamera->camera[1]->matrix,
2326  stereoCamera->rotMatrix,
2327  stereoCamera->transVector,
2328  &(stereoCamera->warpSize),
2329  quad1,
2330  quad2,
2331  stereoCamera->fundMatr,
2332  &(stereoCamera->epipole[0]),
2333  &(stereoCamera->epipole[1])
2334  );
2335 
2336  int i;
2337  for (i = 0; i < 4; i++)
2338  {
2339  stereoCamera->quad[0][i] = cvPoint2D32f(quad1[i][0], quad1[i][1]);
2340  stereoCamera->quad[1][i] = cvPoint2D32f(quad2[i][0], quad2[i][1]);
2341  }
2342 
2343  return;
2344 }
2345 
2346 int icvComputeRestStereoParams(CvStereoCamera* stereoparams);
2347 
2348 /*---------------------------------------------------------------------------------------*/
2349 void icvComputeStereoParamsForCameras(CvStereoCamera* stereoCamera)
2350 {
2351  /* For given intrinsic and extrinsic parameters computes rest parameters
2352  ** such as fundamental matrix. warping coeffs, epipoles, ...
2353  */
2354 
2355 
2356  /* compute rotate matrix and translate vector */
2357  double rotMatr1[9];
2358  double rotMatr2[9];
2359 
2360  double transVect1[3];
2361  double transVect2[3];
2362 
2363  double convRotMatr[9];
2364  double convTransVect[3];
2365 
2366  /* fill matrices */
2367  icvCvt_32f_64d(stereoCamera->camera[0]->rotMatr, rotMatr1, 9);
2368  icvCvt_32f_64d(stereoCamera->camera[1]->rotMatr, rotMatr2, 9);
2369 
2370  icvCvt_32f_64d(stereoCamera->camera[0]->transVect, transVect1, 3);
2371  icvCvt_32f_64d(stereoCamera->camera[1]->transVect, transVect2, 3);
2372 
2373  icvCreateConvertMatrVect(rotMatr1,
2374  transVect1,
2375  rotMatr2,
2376  transVect2,
2377  convRotMatr,
2378  convTransVect);
2379 
2380  /* copy to stereo camera params */
2381  icvCvt_64d_32f(convRotMatr, stereoCamera->rotMatrix, 9);
2382  icvCvt_64d_32f(convTransVect, stereoCamera->transVector, 3);
2383 
2384 
2385  icvGetQuadsTransformStruct(stereoCamera);
2386  icvComputeRestStereoParams(stereoCamera);
2387 }
2388 
2389 void icvGetMiddleAnglePoint(CvPoint2D64d basePoint,
2390  CvPoint2D64d point1, CvPoint2D64d point2,
2391  CvPoint2D64d* midPoint);
2392 
2393 void icvProjectPointToDirect(CvPoint2D64d point, CvVect64d lineCoeff,
2394  CvPoint2D64d* projectPoint);
2395 
2396 /* Get normal direct to direct in line */
2397 void icvGetNormalDirect(CvVect64d direct, CvPoint2D64d point, CvVect64d normDirect)
2398 {
2399  normDirect[0] = direct[1];
2400  normDirect[1] = - direct[0];
2401  normDirect[2] = -(normDirect[0] * point.x + normDirect[1] * point.y);
2402  return;
2403 }
2404 
2405 /*---------------------------------------------------------------------------------------*/
2406 
2407 /* Get cut line for one image */
2408 void icvGetCutPiece(CvVect64d areaLineCoef1, CvVect64d areaLineCoef2,
2409  CvPoint2D64d epipole,
2410  CvSize imageSize,
2411  CvPoint2D64d* point11, CvPoint2D64d* point12,
2412  CvPoint2D64d* point21, CvPoint2D64d* point22,
2413  int* result)
2414 {
2415  /* Compute nearest cut line to epipole */
2416  /* Get corners inside sector */
2417  /* Collect all candidate point */
2418 
2419  CvPoint2D64d candPoints[8];
2420  CvPoint2D64d midPoint = {0, 0};
2421  int numPoints = 0;
2422  int res;
2423  int i;
2424 
2425  double cutLine1[3];
2426  double cutLine2[3];
2427 
2428  /* Find middle line of sector */
2429  double midLine[3] = {0, 0, 0};
2430 
2431 
2432  /* Different way */
2433  CvPoint2D64d pointOnLine1;
2434  pointOnLine1.x = pointOnLine1.y = 0;
2435  CvPoint2D64d pointOnLine2;
2436  pointOnLine2.x = pointOnLine2.y = 0;
2437 
2438  CvPoint2D64d start1, end1;
2439 
2440  icvGetCrossRectDirect(imageSize,
2441  areaLineCoef1[0], areaLineCoef1[1], areaLineCoef1[2],
2442  &start1, &end1, &res);
2443  if (res > 0)
2444  {
2445  pointOnLine1 = start1;
2446  }
2447 
2448  icvGetCrossRectDirect(imageSize,
2449  areaLineCoef2[0], areaLineCoef2[1], areaLineCoef2[2],
2450  &start1, &end1, &res);
2451  if (res > 0)
2452  {
2453  pointOnLine2 = start1;
2454  }
2455 
2456  icvGetMiddleAnglePoint(epipole, pointOnLine1, pointOnLine2, &midPoint);
2457 
2458  icvGetCoefForPiece(epipole, midPoint, &midLine[0], &midLine[1], &midLine[2], &res);
2459 
2460  /* Test corner points */
2461  CvPoint2D64d cornerPoint;
2462  CvPoint2D64d tmpPoints[2];
2463 
2464  cornerPoint.x = 0;
2465  cornerPoint.y = 0;
2466  icvTestPoint(cornerPoint, areaLineCoef1, areaLineCoef2, epipole, &res);
2467  if (res == 1)
2468  {
2469  /* Add point */
2470  candPoints[numPoints] = cornerPoint;
2471  numPoints++;
2472  }
2473 
2474  cornerPoint.x = imageSize.width;
2475  cornerPoint.y = 0;
2476  icvTestPoint(cornerPoint, areaLineCoef1, areaLineCoef2, epipole, &res);
2477  if (res == 1)
2478  {
2479  /* Add point */
2480  candPoints[numPoints] = cornerPoint;
2481  numPoints++;
2482  }
2483 
2484  cornerPoint.x = imageSize.width;
2485  cornerPoint.y = imageSize.height;
2486  icvTestPoint(cornerPoint, areaLineCoef1, areaLineCoef2, epipole, &res);
2487  if (res == 1)
2488  {
2489  /* Add point */
2490  candPoints[numPoints] = cornerPoint;
2491  numPoints++;
2492  }
2493 
2494  cornerPoint.x = 0;
2495  cornerPoint.y = imageSize.height;
2496  icvTestPoint(cornerPoint, areaLineCoef1, areaLineCoef2, epipole, &res);
2497  if (res == 1)
2498  {
2499  /* Add point */
2500  candPoints[numPoints] = cornerPoint;
2501  numPoints++;
2502  }
2503 
2504  /* Find cross line 1 with image border */
2505  icvGetCrossRectDirect(imageSize,
2506  areaLineCoef1[0], areaLineCoef1[1], areaLineCoef1[2],
2507  &tmpPoints[0], &tmpPoints[1],
2508  &res);
2509  for (i = 0; i < res; i++)
2510  {
2511  candPoints[numPoints++] = tmpPoints[i];
2512  }
2513 
2514  /* Find cross line 2 with image border */
2515  icvGetCrossRectDirect(imageSize,
2516  areaLineCoef2[0], areaLineCoef2[1], areaLineCoef2[2],
2517  &tmpPoints[0], &tmpPoints[1],
2518  &res);
2519 
2520  for (i = 0; i < res; i++)
2521  {
2522  candPoints[numPoints++] = tmpPoints[i];
2523  }
2524 
2525  if (numPoints < 2)
2526  {
2527  *result = 0;
2528  return;/* Error. Not enough points */
2529  }
2530  /* Project all points to middle line and get max and min */
2531 
2532  CvPoint2D64d projPoint;
2533  CvPoint2D64d minPoint;
2534  minPoint.x = minPoint.y = FLT_MAX;
2535  CvPoint2D64d maxPoint;
2536  maxPoint.x = maxPoint.y = -FLT_MAX;
2537 
2538 
2539  double dist;
2540  double maxDist = 0;
2541  double minDist = 10000000;
2542 
2543 
2544  for (i = 0; i < numPoints; i++)
2545  {
2546  icvProjectPointToDirect(candPoints[i], midLine, &projPoint);
2547  icvGetPieceLength(epipole, projPoint, &dist);
2548  if (dist < minDist)
2549  {
2550  minDist = dist;
2551  minPoint = projPoint;
2552  }
2553 
2554  if (dist > maxDist)
2555  {
2556  maxDist = dist;
2557  maxPoint = projPoint;
2558  }
2559  }
2560 
2561  /* We know maximum and minimum points. Now we can compute cut lines */
2562 
2563  icvGetNormalDirect(midLine, minPoint, cutLine1);
2564  icvGetNormalDirect(midLine, maxPoint, cutLine2);
2565 
2566  /* Test for begin of line. */
2567  CvPoint2D64d tmpPoint2;
2568 
2569  /* Get cross with */
2570  icvGetCrossDirectDirect(areaLineCoef1, cutLine1, point11, &res);
2571  icvGetCrossDirectDirect(areaLineCoef2, cutLine1, point12, &res);
2572 
2573  icvGetCrossDirectDirect(areaLineCoef1, cutLine2, point21, &res);
2574  icvGetCrossDirectDirect(areaLineCoef2, cutLine2, point22, &res);
2575 
2576  if (epipole.x > imageSize.width * 0.5)
2577  {
2578  /* Need to change points */
2579  tmpPoint2 = *point11;
2580  *point11 = *point21;
2581  *point21 = tmpPoint2;
2582 
2583  tmpPoint2 = *point12;
2584  *point12 = *point22;
2585  *point22 = tmpPoint2;
2586  }
2587 
2588  return;
2589 }
2590 /*---------------------------------------------------------------------------------------*/
2591 /* Get middle angle */
2593  CvPoint2D64d point1, CvPoint2D64d point2,
2594  CvPoint2D64d* midPoint)
2595 {
2596  /* !!! May be need to return error */
2597 
2598  double dist1;
2599  double dist2;
2600  icvGetPieceLength(basePoint, point1, &dist1);
2601  icvGetPieceLength(basePoint, point2, &dist2);
2602  CvPoint2D64d pointNew1;
2603  CvPoint2D64d pointNew2;
2604  double alpha = dist2 / dist1;
2605 
2606  pointNew1.x = basePoint.x + (1.0 / alpha) * (point2.x - basePoint.x);
2607  pointNew1.y = basePoint.y + (1.0 / alpha) * (point2.y - basePoint.y);
2608 
2609  pointNew2.x = basePoint.x + alpha * (point1.x - basePoint.x);
2610  pointNew2.y = basePoint.y + alpha * (point1.y - basePoint.y);
2611 
2612  int res;
2613  icvGetCrossPiecePiece(point1, point2, pointNew1, pointNew2, midPoint, &res);
2614 
2615  return;
2616 }
2617 
2618 /*---------------------------------------------------------------------------------------*/
2619 
2620 
2621 /*---------------------------------------------------------------------------------------*/
2622 CV_IMPL double icvGetVect(CvPoint2D64d basePoint, CvPoint2D64d point1, CvPoint2D64d point2)
2623 {
2624  return (point1.x - basePoint.x) * (point2.y - basePoint.y) -
2625  (point2.x - basePoint.x) * (point1.y - basePoint.y);
2626 }
2627 /*---------------------------------------------------------------------------------------*/
2628 /* Test for point in sector */
2629 /* Return 0 - point not inside sector */
2630 /* Return 1 - point inside sector */
2632  CvVect64d line1, CvVect64d line2,
2633  CvPoint2D64d basePoint,
2634  int* result)
2635 {
2636  CvPoint2D64d point1, point2;
2637 
2638  icvProjectPointToDirect(testPoint, line1, &point1);
2639  icvProjectPointToDirect(testPoint, line2, &point2);
2640 
2641  double sign1 = icvGetVect(basePoint, point1, point2);
2642  double sign2 = icvGetVect(basePoint, point1, testPoint);
2643  if (sign1 * sign2 > 0)
2644  {
2645  /* Correct for first line */
2646  sign1 = - sign1;
2647  sign2 = icvGetVect(basePoint, point2, testPoint);
2648  if (sign1 * sign2 > 0)
2649  {
2650  /* Correct for both lines */
2651  *result = 1;
2652  }
2653  else
2654  {
2655  *result = 0;
2656  }
2657  }
2658  else
2659  {
2660  *result = 0;
2661  }
2662 
2663  return;
2664 }
2665 
2666 /*---------------------------------------------------------------------------------------*/
2667 /* Project point to line */
2669  CvPoint2D64d* projectPoint)
2670 {
2671  double a = lineCoeff[0];
2672  double b = lineCoeff[1];
2673 
2674  double det = 1.0 / (a * a + b * b);
2675  double delta = a * point.y - b * point.x;
2676 
2677  projectPoint->x = (-a * lineCoeff[2] - b * delta) * det;
2678  projectPoint->y = (-b * lineCoeff[2] + a * delta) * det ;
2679 
2680  return;
2681 }
2682 
2683 /*---------------------------------------------------------------------------------------*/
2684 /* Get distance from point to direction */
2685 void icvGetDistanceFromPointToDirect(CvPoint2D64d point, CvVect64d lineCoef, double* dist)
2686 {
2687  CvPoint2D64d tmpPoint;
2688  icvProjectPointToDirect(point, lineCoef, &tmpPoint);
2689  double dx = point.x - tmpPoint.x;
2690  double dy = point.y - tmpPoint.y;
2691  *dist = sqrt(dx * dx + dy * dy);
2692  return;
2693 }
2694 /*---------------------------------------------------------------------------------------*/
2695 
2696 CV_IMPL IplImage* icvCreateIsometricImage(IplImage* src, IplImage* dst,
2697  int desired_depth, int desired_num_channels)
2698 {
2699  CvSize src_size ;
2700  src_size.width = src->width;
2701  src_size.height = src->height;
2702 
2703  CvSize dst_size = src_size;
2704 
2705  if (dst)
2706  {
2707  dst_size.width = dst->width;
2708  dst_size.height = dst->height;
2709  }
2710 
2711  if (!dst || dst->depth != desired_depth ||
2712  dst->nChannels != desired_num_channels ||
2713  dst_size.width != src_size.width ||
2714  dst_size.height != src_size.height)
2715  {
2716  cvReleaseImage(&dst);
2717  dst = cvCreateImage(src_size, desired_depth, desired_num_channels);
2718  CvRect rect = cvRect(0, 0, src_size.width, src_size.height);
2719  cvSetImageROI(dst, rect);
2720 
2721  }
2722 
2723  return dst;
2724 }
2725 
2726 static int
2727 icvCvt_32f_64d(float* src, double* dst, int size)
2728 {
2729  int t;
2730 
2731  if (!src || !dst)
2732  {
2733  return CV_NULLPTR_ERR;
2734  }
2735  if (size <= 0)
2736  {
2737  return CV_BADRANGE_ERR;
2738  }
2739 
2740  for (t = 0; t < size; t++)
2741  {
2742  dst[t] = (double)(src[t]);
2743  }
2744 
2745  return CV_OK;
2746 }
2747 
2748 /*======================================================================================*/
2749 /* Type conversion double -> float */
2750 static int
2751 icvCvt_64d_32f(double* src, float* dst, int size)
2752 {
2753  int t;
2754 
2755  if (!src || !dst)
2756  {
2757  return CV_NULLPTR_ERR;
2758  }
2759  if (size <= 0)
2760  {
2761  return CV_BADRANGE_ERR;
2762  }
2763 
2764  for (t = 0; t < size; t++)
2765  {
2766  dst[t] = (float)(src[t]);
2767  }
2768 
2769  return CV_OK;
2770 }
2771 
2772 CV_INLINE CvSize cvGetMatSize(const CvMat* mat)
2773 {
2774  CvSize size;
2775  size.width = mat->cols;
2776  size.height = mat->rows;
2777  return size;
2778 }
2779 
2780 /*----------------------------------------------------------------------------------*/
2781 
2782 #define __BEGIN__ __CV_BEGIN__
2783 #define __END__ __CV_END__
2784 
2785 /*--------------------------------------------------------------------------------------*/
2786 
2787 CV_IMPL void cvComputePerspectiveMap(const double c[3][3], CvArr* rectMapX, CvArr* rectMapY)
2788 {
2789  CV_FUNCNAME("cvComputePerspectiveMap");
2790 
2791  __BEGIN__;
2792 
2793  CvSize size;
2794  CvMat stubx, *mapx = (CvMat*)rectMapX;
2795  CvMat stuby, *mapy = (CvMat*)rectMapY;
2796  int i, j;
2797 
2798  CV_CALL(mapx = cvGetMat(mapx, &stubx));
2799  CV_CALL(mapy = cvGetMat(mapy, &stuby));
2800 
2801  if (CV_MAT_TYPE(mapx->type) != CV_32FC1 || CV_MAT_TYPE(mapy->type) != CV_32FC1)
2802  {
2803  CV_ERROR(CV_StsUnsupportedFormat, "");
2804  }
2805 
2806  size = cvGetMatSize(mapx);
2807  assert(fabs(c[2][2] - 1.) < FLT_EPSILON);
2808 
2809  for (i = 0; i < size.height; i++)
2810  {
2811  float* mx = (float*)(mapx->data.ptr + mapx->step * i);
2812  float* my = (float*)(mapy->data.ptr + mapy->step * i);
2813 
2814  for (j = 0; j < size.width; j++)
2815  {
2816  double w = 1. / (c[2][0] * j + c[2][1] * i + 1.);
2817  double x = (c[0][0] * j + c[0][1] * i + c[0][2]) * w;
2818  double y = (c[1][0] * j + c[1][1] * i + c[1][2]) * w;
2819 
2820  mx[j] = (float)x;
2821  my[j] = (float)y;
2822  }
2823  }
2824 
2825  __END__;
2826 }
2827 
2828 /*--------------------------------------------------------------------------------------*/
2829 
2830 CV_IMPL void cvInitPerspectiveTransform(CvSize size, const CvPoint2D32f quad[4], double matrix[3][3],
2831  CvArr* rectMap)
2832 {
2833  /* Computes Perspective Transform coeffs and map if need
2834  for given image size and given result quad */
2835  CV_FUNCNAME("cvInitPerspectiveTransform");
2836 
2837  __BEGIN__;
2838 
2839  double A[64];
2840  double b[8];
2841  double c[8];
2842  CvPoint2D32f pt[4];
2843  CvMat mapstub, *map = (CvMat*)rectMap;
2844  int i, j;
2845 
2846  if (map)
2847  {
2848  CV_CALL(map = cvGetMat(map, &mapstub));
2849 
2850  if (CV_MAT_TYPE(map->type) != CV_32FC2)
2851  {
2852  CV_ERROR(CV_StsUnsupportedFormat, "");
2853  }
2854 
2855  if (map->width != size.width || map->height != size.height)
2856  {
2857  CV_ERROR(CV_StsUnmatchedSizes, "");
2858  }
2859  }
2860 
2861  pt[0] = cvPoint2D32f(0, 0);
2862  pt[1] = cvPoint2D32f(size.width, 0);
2863  pt[2] = cvPoint2D32f(size.width, size.height);
2864  pt[3] = cvPoint2D32f(0, size.height);
2865 
2866  for (i = 0; i < 4; i++)
2867  {
2868 #if 0
2869  double x = quad[i].x;
2870  double y = quad[i].y;
2871  double X = pt[i].x;
2872  double Y = pt[i].y;
2873 #else
2874  double x = pt[i].x;
2875  double y = pt[i].y;
2876  double X = quad[i].x;
2877  double Y = quad[i].y;
2878 #endif
2879  double* a = A + i * 16;
2880 
2881  a[0] = x;
2882  a[1] = y;
2883  a[2] = 1;
2884  a[3] = 0;
2885  a[4] = 0;
2886  a[5] = 0;
2887  a[6] = -X * x;
2888  a[7] = -X * y;
2889 
2890  a += 8;
2891 
2892  a[0] = 0;
2893  a[1] = 0;
2894  a[2] = 0;
2895  a[3] = x;
2896  a[4] = y;
2897  a[5] = 1;
2898  a[6] = -Y * x;
2899  a[7] = -Y * y;
2900 
2901  b[i * 2] = X;
2902  b[i * 2 + 1] = Y;
2903  }
2904 
2905  {
2906  double invA[64];
2907  CvMat matA = cvMat(8, 8, CV_64F, A);
2908  CvMat matInvA = cvMat(8, 8, CV_64F, invA);
2909  CvMat matB = cvMat(8, 1, CV_64F, b);
2910  CvMat matX = cvMat(8, 1, CV_64F, c);
2911 
2912  CV_CALL(cvPseudoInverse(&matA, &matInvA));
2913  CV_CALL(cvMatMulAdd(&matInvA, &matB, 0, &matX));
2914  }
2915 
2916  matrix[0][0] = c[0];
2917  matrix[0][1] = c[1];
2918  matrix[0][2] = c[2];
2919  matrix[1][0] = c[3];
2920  matrix[1][1] = c[4];
2921  matrix[1][2] = c[5];
2922  matrix[2][0] = c[6];
2923  matrix[2][1] = c[7];
2924  matrix[2][2] = 1.0;
2925 
2926  if (map)
2927  {
2928  for (i = 0; i < size.height; i++)
2929  {
2930  CvPoint2D32f* maprow = (CvPoint2D32f*)(map->data.ptr + map->step * i);
2931  for (j = 0; j < size.width; j++)
2932  {
2933  double w = 1. / (c[6] * j + c[7] * i + 1.);
2934  double x = (c[0] * j + c[1] * i + c[2]) * w;
2935  double y = (c[3] * j + c[4] * i + c[5]) * w;
2936 
2937  maprow[j].x = (float)x;
2938  maprow[j].y = (float)y;
2939  }
2940  }
2941  }
2942 
2943  __END__;
2944 
2945  return;
2946 }
2947 
2948 
2949 /*-----------------------------------------------------------------------*/
2950 /* Compute projected infinite point for second image if first image point is known */
2952  CvMatr64d camMatr1,
2953  CvMatr64d camMatr2,
2954  CvPoint2D32f point1,
2955  CvPoint2D32f* point2)
2956 {
2957  double invMatr1[9];
2958  icvInvertMatrix_64d(camMatr1, 3, invMatr1);
2959  double P1[3];
2960  double p1[3];
2961  p1[0] = (double)(point1.x);
2962  p1[1] = (double)(point1.y);
2963  p1[2] = 1;
2964 
2965  icvMulMatrix_64d(invMatr1,
2966  3, 3,
2967  p1,
2968  1, 3,
2969  P1);
2970 
2971  double invR[9];
2972  icvTransposeMatrix_64d(rotMatr, 3, 3, invR);
2973 
2974  /* Change system 1 to system 2 */
2975  double P2[3];
2976  icvMulMatrix_64d(invR,
2977  3, 3,
2978  P1,
2979  1, 3,
2980  P2);
2981 
2982  /* Now we can project this point to image 2 */
2983  double projP[3];
2984 
2985  icvMulMatrix_64d(camMatr2,
2986  3, 3,
2987  P2,
2988  1, 3,
2989  projP);
2990 
2991  point2->x = (float)(projP[0] / projP[2]);
2992  point2->y = (float)(projP[1] / projP[2]);
2993 
2994  return;
2995 }
2996 
2997 /*-----------------------------------------------------------------------*/
2998 /* Compute projected infinite point for second image if first image point is known */
3000  CvMatr64d camMatr1,
3001  CvMatr64d camMatr2,
3002  CvPoint2D32f* point1,
3003  CvPoint2D32f point2)
3004 {
3005  double invMatr2[9];
3006  icvInvertMatrix_64d(camMatr2, 3, invMatr2);
3007  double P2[3];
3008  double p2[3];
3009  p2[0] = (double)(point2.x);
3010  p2[1] = (double)(point2.y);
3011  p2[2] = 1;
3012 
3013  icvMulMatrix_64d(invMatr2,
3014  3, 3,
3015  p2,
3016  1, 3,
3017  P2);
3018 
3019  /* Change system 1 to system 2 */
3020 
3021  double P1[3];
3022  icvMulMatrix_64d(rotMatr,
3023  3, 3,
3024  P2,
3025  1, 3,
3026  P1);
3027 
3028  /* Now we can project this point to image 2 */
3029  double projP[3];
3030 
3031  icvMulMatrix_64d(camMatr1,
3032  3, 3,
3033  P1,
3034  1, 3,
3035  projP);
3036 
3037  point1->x = (float)(projP[0] / projP[2]);
3038  point1->y = (float)(projP[1] / projP[2]);
3039 
3040  return;
3041 }
3042 
3043 
3044 /* Simpler version of the previous function */
3045 void cvProjectPointsSimple(int point_count, CvPoint3D64f* _object_points,
3046  double* _rotation_matrix, double* _translation_vector,
3047  double* _camera_matrix, double* _distortion, CvPoint2D64f* _image_points)
3048 {
3049  CvMat object_points = cvMat(point_count, 1, CV_64FC3, _object_points);
3050  CvMat image_points = cvMat(point_count, 1, CV_64FC2, _image_points);
3051  CvMat rotation_matrix = cvMat(3, 3, CV_64FC1, _rotation_matrix);
3052  CvMat translation_vector = cvMat(3, 1, CV_64FC1, _translation_vector);
3053  CvMat camera_matrix = cvMat(3, 3, CV_64FC1, _camera_matrix);
3054  CvMat dist_coeffs = cvMat(4, 1, CV_64FC1, _distortion);
3055 
3056  cvProjectPoints2(&object_points, &rotation_matrix, &translation_vector,
3057  &camera_matrix, &dist_coeffs, &image_points,
3058  0, 0, 0, 0, 0, 0);
3059 }
3060 
3061 /* Select best R and t for given cameras, points, ... */
3062 /* For both cameras */
3063 static int icvSelectBestRt(int numImages,
3064  int* numPoints,
3065  CvPoint2D32f* imagePoints1,
3066  CvPoint2D32f* imagePoints2,
3067  CvPoint3D32f* objectPoints,
3068 
3069  CvMatr32f cameraMatrix1,
3070  CvVect32f distortion1,
3071  CvMatr32f rotMatrs1,
3072  CvVect32f transVects1,
3073 
3074  CvMatr32f cameraMatrix2,
3075  CvVect32f distortion2,
3076  CvMatr32f rotMatrs2,
3077  CvVect32f transVects2,
3078 
3079  CvMatr32f bestRotMatr,
3080  CvVect32f bestTransVect
3081  )
3082 {
3083 
3084  /* Need to convert input data 32 -> 64 */
3085  CvPoint3D64d* objectPoints_64d;
3086 
3087  double* rotMatrs1_64d;
3088  double* rotMatrs2_64d;
3089 
3090  double* transVects1_64d;
3091  double* transVects2_64d;
3092 
3093  double cameraMatrix1_64d[9];
3094  double cameraMatrix2_64d[9];
3095 
3096  double distortion1_64d[4];
3097  double distortion2_64d[4];
3098 
3099  /* allocate memory for 64d data */
3100  int totalNum = 0;
3101 
3102  for (int i = 0; i < numImages; i++)
3103  {
3104  totalNum += numPoints[i];
3105  }
3106 
3107  objectPoints_64d = (CvPoint3D64d*)calloc(totalNum, sizeof(CvPoint3D64d));
3108 
3109  rotMatrs1_64d = (double*)calloc(numImages, sizeof(double) * 9);
3110  rotMatrs2_64d = (double*)calloc(numImages, sizeof(double) * 9);
3111 
3112  transVects1_64d = (double*)calloc(numImages, sizeof(double) * 3);
3113  transVects2_64d = (double*)calloc(numImages, sizeof(double) * 3);
3114 
3115  /* Convert input data to 64d */
3116 
3117  icvCvt_32f_64d((float*)objectPoints, (double*)objectPoints_64d, totalNum * 3);
3118 
3119  icvCvt_32f_64d(rotMatrs1, rotMatrs1_64d, numImages * 9);
3120  icvCvt_32f_64d(rotMatrs2, rotMatrs2_64d, numImages * 9);
3121 
3122  icvCvt_32f_64d(transVects1, transVects1_64d, numImages * 3);
3123  icvCvt_32f_64d(transVects2, transVects2_64d, numImages * 3);
3124 
3125  /* Convert to arrays */
3126  icvCvt_32f_64d(cameraMatrix1, cameraMatrix1_64d, 9);
3127  icvCvt_32f_64d(cameraMatrix2, cameraMatrix2_64d, 9);
3128 
3129  icvCvt_32f_64d(distortion1, distortion1_64d, 4);
3130  icvCvt_32f_64d(distortion2, distortion2_64d, 4);
3131 
3132 
3133  /* for each R and t compute error for image pair */
3134  float* errors;
3135 
3136  errors = (float*)calloc(numImages * numImages, sizeof(float));
3137  if (errors == 0)
3138  {
3139  return CV_OUTOFMEM_ERR;
3140  }
3141 
3142  int currImagePair;
3143  int currRt;
3144  for (currRt = 0; currRt < numImages; currRt++)
3145  {
3146  int begPoint = 0;
3147  for (currImagePair = 0; currImagePair < numImages; currImagePair++)
3148  {
3149  /* For current R,t R,t compute relative position of cameras */
3150 
3151  double convRotMatr[9];
3152  double convTransVect[3];
3153 
3154  icvCreateConvertMatrVect(rotMatrs1_64d + currRt * 9,
3155  transVects1_64d + currRt * 3,
3156  rotMatrs2_64d + currRt * 9,
3157  transVects2_64d + currRt * 3,
3158  convRotMatr,
3159  convTransVect);
3160 
3161  /* Project points using relative position of cameras */
3162 
3163  double convRotMatr2[9];
3164  double convTransVect2[3];
3165 
3166  convRotMatr2[0] = 1;
3167  convRotMatr2[1] = 0;
3168  convRotMatr2[2] = 0;
3169 
3170  convRotMatr2[3] = 0;
3171  convRotMatr2[4] = 1;
3172  convRotMatr2[5] = 0;
3173 
3174  convRotMatr2[6] = 0;
3175  convRotMatr2[7] = 0;
3176  convRotMatr2[8] = 1;
3177 
3178  convTransVect2[0] = 0;
3179  convTransVect2[1] = 0;
3180  convTransVect2[2] = 0;
3181 
3182  /* Compute error for given pair and Rt */
3183  /* We must project points to image and compute error */
3184 
3185  CvPoint2D64d* projImagePoints1;
3186  CvPoint2D64d* projImagePoints2;
3187 
3188  CvPoint3D64d* points1;
3189  CvPoint3D64d* points2;
3190 
3191  int numberPnt;
3192  numberPnt = numPoints[currImagePair];
3193  projImagePoints1 = (CvPoint2D64d*)calloc(numberPnt, sizeof(CvPoint2D64d));
3194  projImagePoints2 = (CvPoint2D64d*)calloc(numberPnt, sizeof(CvPoint2D64d));
3195 
3196  points1 = (CvPoint3D64d*)calloc(numberPnt, sizeof(CvPoint3D64d));
3197  points2 = (CvPoint3D64d*)calloc(numberPnt, sizeof(CvPoint3D64d));
3198 
3199  /* Transform object points to first camera position */
3200  for (int i = 0; i < numberPnt; i++)
3201  {
3202  /* Create second camera point */
3203  CvPoint3D64d tmpPoint;
3204  tmpPoint.x = (double)(objectPoints[i].x);
3205  tmpPoint.y = (double)(objectPoints[i].y);
3206  tmpPoint.z = (double)(objectPoints[i].z);
3207 
3208  icvConvertPointSystem(tmpPoint,
3209  points2 + i,
3210  rotMatrs2_64d + currImagePair * 9,
3211  transVects2_64d + currImagePair * 3);
3212 
3213  /* Create first camera point using R, t */
3214  icvConvertPointSystem(points2[i],
3215  points1 + i,
3216  convRotMatr,
3217  convTransVect);
3218 
3219  CvPoint3D64d tmpPoint2 = { 0, 0, 0 };
3220  icvConvertPointSystem(tmpPoint,
3221  &tmpPoint2,
3222  rotMatrs1_64d + currImagePair * 9,
3223  transVects1_64d + currImagePair * 3);
3224  }
3225 
3226  /* Project with no translate and no rotation */
3227 
3228  cvProjectPointsSimple(numPoints[currImagePair],
3229  points1,
3230  convRotMatr2,
3231  convTransVect2,
3232  cameraMatrix1_64d,
3233  distortion1_64d,
3234  projImagePoints1);
3235 
3236  cvProjectPointsSimple(numPoints[currImagePair],
3237  points2,
3238  convRotMatr2,
3239  convTransVect2,
3240  cameraMatrix2_64d,
3241  distortion2_64d,
3242  projImagePoints2);
3243 
3244  /* points are projected. Compute error */
3245 
3246  int currPoint;
3247  double err1 = 0;
3248  double err2 = 0;
3249  double err;
3250  for (currPoint = 0; currPoint < numberPnt; currPoint++)
3251  {
3252  double len1, len2;
3253  double dx1, dy1;
3254  dx1 = imagePoints1[begPoint + currPoint].x - projImagePoints1[currPoint].x;
3255  dy1 = imagePoints1[begPoint + currPoint].y - projImagePoints1[currPoint].y;
3256  len1 = sqrt(dx1 * dx1 + dy1 * dy1);
3257  err1 += len1;
3258 
3259  double dx2, dy2;
3260  dx2 = imagePoints2[begPoint + currPoint].x - projImagePoints2[currPoint].x;
3261  dy2 = imagePoints2[begPoint + currPoint].y - projImagePoints2[currPoint].y;
3262  len2 = sqrt(dx2 * dx2 + dy2 * dy2);
3263  err2 += len2;
3264  }
3265 
3266  err1 /= (float)(numberPnt);
3267  err2 /= (float)(numberPnt);
3268 
3269  err = (err1 + err2) * 0.5;
3270  begPoint += numberPnt;
3271 
3272  /* Set this error to */
3273  errors[numImages * currImagePair + currRt] = (float)err;
3274 
3275  free(points1);
3276  free(points2);
3277  free(projImagePoints1);
3278  free(projImagePoints2);
3279  }
3280  }
3281 
3282  /* Just select R and t with minimal average error */
3283 
3284  int bestnumRt = 0;
3285  float minError = 0;/* Just for no warnings. Uses 'first' flag. */
3286  int first = 1;
3287  for (currRt = 0; currRt < numImages; currRt++)
3288  {
3289  float avErr = 0;
3290  for (currImagePair = 0; currImagePair < numImages; currImagePair++)
3291  {
3292  avErr += errors[numImages * currImagePair + currRt];
3293  }
3294  avErr /= (float)(numImages);
3295 
3296  if (first)
3297  {
3298  bestnumRt = 0;
3299  minError = avErr;
3300  first = 0;
3301  }
3302  else
3303  {
3304  if (avErr < minError)
3305  {
3306  bestnumRt = currRt;
3307  minError = avErr;
3308  }
3309  }
3310 
3311  }
3312 
3313  double bestRotMatr_64d[9];
3314  double bestTransVect_64d[3];
3315 
3316  icvCreateConvertMatrVect(rotMatrs1_64d + bestnumRt * 9,
3317  transVects1_64d + bestnumRt * 3,
3318  rotMatrs2_64d + bestnumRt * 9,
3319  transVects2_64d + bestnumRt * 3,
3320  bestRotMatr_64d,
3321  bestTransVect_64d);
3322 
3323  icvCvt_64d_32f(bestRotMatr_64d, bestRotMatr, 9);
3324  icvCvt_64d_32f(bestTransVect_64d, bestTransVect, 3);
3325 
3326 
3327  free(errors);
3328 
3329  return CV_OK;
3330 }
3331 
3332 
3333 /* ----------------- Stereo calibration functions --------------------- */
3334 
3335 float icvDefinePointPosition(CvPoint2D32f point1, CvPoint2D32f point2, CvPoint2D32f point)
3336 {
3337  float ax = point2.x - point1.x;
3338  float ay = point2.y - point1.y;
3339 
3340  float bx = point.x - point1.x;
3341  float by = point.y - point1.y;
3342 
3343  return (ax * by - ay * bx);
3344 }
3345 
3346 /* Convert function for stereo warping */
3347 int icvConvertWarpCoordinates(double coeffs[3][3],
3348  CvPoint2D32f* cameraPoint,
3349  CvPoint2D32f* warpPoint,
3350  int direction)
3351 {
3352  double x, y;
3353  double det;
3354  if (direction == CV_WARP_TO_CAMERA)
3355  {
3356  /* convert from camera image to warped image coordinates */
3357  x = warpPoint->x;
3358  y = warpPoint->y;
3359 
3360  det = (coeffs[2][0] * x + coeffs[2][1] * y + coeffs[2][2]);
3361  if (fabs(det) > 1e-8)
3362  {
3363  cameraPoint->x = (float)((coeffs[0][0] * x + coeffs[0][1] * y + coeffs[0][2]) / det);
3364  cameraPoint->y = (float)((coeffs[1][0] * x + coeffs[1][1] * y + coeffs[1][2]) / det);
3365  return CV_OK;
3366  }
3367  }
3368  else if (direction == CV_CAMERA_TO_WARP)
3369  {
3370  /* convert from warped image to camera image coordinates */
3371  x = cameraPoint->x;
3372  y = cameraPoint->y;
3373 
3374  det = (coeffs[2][0] * x - coeffs[0][0]) * (coeffs[2][1] * y - coeffs[1][1]) - (coeffs[2][1] * x - coeffs[0][1]) * (coeffs[2][0] * y - coeffs[1][0]);
3375 
3376  if (fabs(det) > 1e-8)
3377  {
3378  warpPoint->x = (float)(((coeffs[0][2] - coeffs[2][2] * x) * (coeffs[2][1] * y - coeffs[1][1]) - (coeffs[2][1] * x - coeffs[0][1]) * (coeffs[1][2] - coeffs[2][2] * y)) / det);
3379  warpPoint->y = (float)(((coeffs[2][0] * x - coeffs[0][0]) * (coeffs[1][2] - coeffs[2][2] * y) - (coeffs[0][2] - coeffs[2][2] * x) * (coeffs[2][0] * y - coeffs[1][0])) / det);
3380  return CV_OK;
3381  }
3382  }
3383 
3384  return CV_BADFACTOR_ERR;
3385 }
3386 
3387 /* Compute stereo params using some camera params */
3388 /* by Valery Mosyagin. int ComputeRestStereoParams(StereoParams *stereoparams) */
3389 int icvComputeRestStereoParams(CvStereoCamera* stereoparams)
3390 {
3391 
3392 
3393  icvGetQuadsTransformStruct(stereoparams);
3394 
3395  cvInitPerspectiveTransform(stereoparams->warpSize,
3396  stereoparams->quad[0],
3397  stereoparams->coeffs[0],
3398  0);
3399 
3400  cvInitPerspectiveTransform(stereoparams->warpSize,
3401  stereoparams->quad[1],
3402  stereoparams->coeffs[1],
3403  0);
3404 
3405  /* Create border for warped images */
3406  CvPoint2D32f corns[4];
3407  corns[0].x = 0;
3408  corns[0].y = 0;
3409 
3410  corns[1].x = (float)(stereoparams->camera[0]->imgSize[0] - 1);
3411  corns[1].y = 0;
3412 
3413  corns[2].x = (float)(stereoparams->camera[0]->imgSize[0] - 1);
3414  corns[2].y = (float)(stereoparams->camera[0]->imgSize[1] - 1);
3415 
3416  corns[3].x = 0;
3417  corns[3].y = (float)(stereoparams->camera[0]->imgSize[1] - 1);
3418 
3419  for (int i = 0; i < 4; i++)
3420  {
3421  /* For first camera */
3422  icvConvertWarpCoordinates(stereoparams->coeffs[0],
3423  corns + i,
3424  stereoparams->border[0] + i,
3426 
3427  /* For second camera */
3428  icvConvertWarpCoordinates(stereoparams->coeffs[1],
3429  corns + i,
3430  stereoparams->border[1] + i,
3432  }
3433 
3434  /* Test compute */
3435  {
3436  CvPoint2D32f warpPoints[4];
3437  warpPoints[0] = cvPoint2D32f(0, 0);
3438  warpPoints[1] = cvPoint2D32f(stereoparams->warpSize.width - 1, 0);
3439  warpPoints[2] = cvPoint2D32f(stereoparams->warpSize.width - 1, stereoparams->warpSize.height - 1);
3440  warpPoints[3] = cvPoint2D32f(0, stereoparams->warpSize.height - 1);
3441 
3442  CvPoint2D32f camPoints1[4];
3443  CvPoint2D32f camPoints2[4];
3444 
3445  for (int i = 0; i < 4; i++)
3446  {
3447  icvConvertWarpCoordinates(stereoparams->coeffs[0],
3448  camPoints1 + i,
3449  warpPoints + i,
3451 
3452  icvConvertWarpCoordinates(stereoparams->coeffs[1],
3453  camPoints2 + i,
3454  warpPoints + i,
3456  }
3457  }
3458 
3459 
3460  /* Allocate memory for scanlines coeffs */
3461 
3462  stereoparams->lineCoeffs = (CvStereoLineCoeff*)calloc(stereoparams->warpSize.height, sizeof(CvStereoLineCoeff));
3463 
3464  /* Compute coeffs for epilines */
3465 
3466  icvComputeCoeffForStereo(stereoparams);
3467 
3468  /* all coeffs are known */
3469  return CV_OK;
3470 }
3471 
3472 /*-------------------------------------------------------------------------------------------*/
3473 
3474 int icvStereoCalibration(int numImages,
3475  int* nums,
3476  CvSize imageSize,
3477  CvPoint2D32f* imagePoints1,
3478  CvPoint2D32f* imagePoints2,
3479  CvPoint3D32f* objectPoints,
3480  CvStereoCamera* stereoparams
3481  )
3482 {
3483  /* Firstly we must calibrate both cameras */
3484  /* Alocate memory for data */
3485  /* Allocate for translate vectors */
3486  float* transVects1;
3487  float* transVects2;
3488  float* rotMatrs1;
3489  float* rotMatrs2;
3490 
3491  transVects1 = (float*)calloc(numImages, sizeof(float) * 3);
3492  transVects2 = (float*)calloc(numImages, sizeof(float) * 3);
3493 
3494  rotMatrs1 = (float*)calloc(numImages, sizeof(float) * 9);
3495  rotMatrs2 = (float*)calloc(numImages, sizeof(float) * 9);
3496 
3497  /* Calibrate first camera */
3498  cvCalibrateCamera(numImages,
3499  nums,
3500  imageSize,
3501  imagePoints1,
3502  objectPoints,
3503  stereoparams->camera[0]->distortion,
3504  stereoparams->camera[0]->matrix,
3505  transVects1,
3506  rotMatrs1,
3507  1);
3508 
3509  /* Calibrate second camera */
3510  cvCalibrateCamera(numImages,
3511  nums,
3512  imageSize,
3513  imagePoints2,
3514  objectPoints,
3515  stereoparams->camera[1]->distortion,
3516  stereoparams->camera[1]->matrix,
3517  transVects2,
3518  rotMatrs2,
3519  1);
3520 
3521  /* Cameras are calibrated */
3522 
3523  stereoparams->camera[0]->imgSize[0] = (float)imageSize.width;
3524  stereoparams->camera[0]->imgSize[1] = (float)imageSize.height;
3525 
3526  stereoparams->camera[1]->imgSize[0] = (float)imageSize.width;
3527  stereoparams->camera[1]->imgSize[1] = (float)imageSize.height;
3528 
3529  icvSelectBestRt(numImages,
3530  nums,
3531  imagePoints1,
3532  imagePoints2,
3533  objectPoints,
3534  stereoparams->camera[0]->matrix,
3535  stereoparams->camera[0]->distortion,
3536  rotMatrs1,
3537  transVects1,
3538  stereoparams->camera[1]->matrix,
3539  stereoparams->camera[1]->distortion,
3540  rotMatrs2,
3541  transVects2,
3542  stereoparams->rotMatrix,
3543  stereoparams->transVector
3544  );
3545 
3546  /* Free memory */
3547  free(transVects1);
3548  free(transVects2);
3549  free(rotMatrs1);
3550  free(rotMatrs2);
3551 
3552  icvComputeRestStereoParams(stereoparams);
3553 
3554  return CV_NO_ERR;
3555 }
3556 
3557 int icvGetCrossPieceVector(CvPoint2D32f p1_start, CvPoint2D32f p1_end, CvPoint2D32f v2_start, CvPoint2D32f v2_end, CvPoint2D32f* cross)
3558 {
3559  double ex1 = p1_start.x;
3560  double ey1 = p1_start.y;
3561  double ex2 = p1_end.x;
3562  double ey2 = p1_end.y;
3563 
3564  double px1 = v2_start.x;
3565  double py1 = v2_start.y;
3566  double px2 = v2_end.x;
3567  double py2 = v2_end.y;
3568 
3569  double del = (ex1 - ex2) * (py2 - py1) + (ey2 - ey1) * (px2 - px1);
3570  if (del == 0)
3571  {
3572  return -1;
3573  }
3574 
3575  double delA = (px1 - ex1) * (py1 - py2) + (ey1 - py1) * (px1 - px2);
3576  //double delB = (ex1-px1)*(ey1-ey2) + (py1-ey1)*(ex1-ex2);
3577 
3578  double alpha = delA / del;
3579  //double betta = -delB / del;
3580 
3581  if (alpha < 0 || alpha > 1.0)
3582  {
3583  return -1;
3584  }
3585 
3586  double delX = (ex1 - ex2) * (py1 * (px1 - px2) - px1 * (py1 - py2)) +
3587  (px1 - px2) * (ex1 * (ey1 - ey2) - ey1 * (ex1 - ex2));
3588 
3589  double delY = (ey1 - ey2) * (px1 * (py1 - py2) - py1 * (px1 - px2)) +
3590  (py1 - py2) * (ey1 * (ex1 - ex2) - ex1 * (ey1 - ey2));
3591 
3592  cross->x = (float)(delX / del);
3593  cross->y = (float)(-delY / del);
3594  return 1;
3595 }
3596 
3597 
3598 int icvGetCrossLineDirect(CvPoint2D32f p1, CvPoint2D32f p2, float a, float b, float c, CvPoint2D32f* cross)
3599 {
3600  double del;
3601  double delX, delY, delA;
3602 
3603  double px1, px2, py1, py2;
3604  double X, Y, alpha;
3605 
3606  px1 = p1.x;
3607  py1 = p1.y;
3608 
3609  px2 = p2.x;
3610  py2 = p2.y;
3611 
3612  del = a * (px2 - px1) + b * (py2 - py1);
3613  if (del == 0)
3614  {
3615  return -1;
3616  }
3617 
3618  delA = - c - a * px1 - b * py1;
3619  alpha = delA / del;
3620 
3621  if (alpha < 0 || alpha > 1.0)
3622  {
3623  return -1;/* no cross */
3624  }
3625 
3626  delX = b * (py1 * (px1 - px2) - px1 * (py1 - py2)) + c * (px1 - px2);
3627  delY = a * (px1 * (py1 - py2) - py1 * (px1 - px2)) + c * (py1 - py2);
3628 
3629  X = delX / del;
3630  Y = delY / del;
3631 
3632  cross->x = (float)X;
3633  cross->y = (float)Y;
3634 
3635  return 1;
3636 }
3637 
3638 /* Compute epipoles for fundamental matrix */
3640  CvPoint3D32f* epipole1,
3641  CvPoint3D32f* epipole2)
3642 {
3643  /* Decompose fundamental matrix using SVD ( A = U W V') */
3644  CvMat fundMatrC = cvMat(3, 3, CV_MAT32F, fundMatr);
3645 
3646  CvMat* matrW = cvCreateMat(3, 3, CV_MAT32F);
3647  CvMat* matrU = cvCreateMat(3, 3, CV_MAT32F);
3648  CvMat* matrV = cvCreateMat(3, 3, CV_MAT32F);
3649 
3650  /* From svd we need just last vector of U and V or last row from U' and V' */
3651  /* We get transposed matrices U and V */
3652  cvSVD(&fundMatrC, matrW, matrU, matrV, CV_SVD_V_T | CV_SVD_U_T);
3653 
3654  /* Get last row from U' and compute epipole1 */
3655  epipole1->x = matrU->data.fl[6];
3656  epipole1->y = matrU->data.fl[7];
3657  epipole1->z = matrU->data.fl[8];
3658 
3659  /* Get last row from V' and compute epipole2 */
3660  epipole2->x = matrV->data.fl[6];
3661  epipole2->y = matrV->data.fl[7];
3662  epipole2->z = matrV->data.fl[8];
3663 
3664  cvReleaseMat(&matrW);
3665  cvReleaseMat(&matrU);
3666  cvReleaseMat(&matrV);
3667  return CV_OK;
3668 }
3669 
3671  CvMatr32f fundMatr,
3672  CvMatr32f cameraMatr1,
3673  CvMatr32f cameraMatr2)
3674 {
3675  /* Fund = inv(CM1') * Ess * inv(CM2) */
3676 
3677  CvMat essMatrC = cvMat(3, 3, CV_MAT32F, essMatr);
3678  CvMat fundMatrC = cvMat(3, 3, CV_MAT32F, fundMatr);
3679  CvMat cameraMatr1C = cvMat(3, 3, CV_MAT32F, cameraMatr1);
3680  CvMat cameraMatr2C = cvMat(3, 3, CV_MAT32F, cameraMatr2);
3681 
3682  CvMat* invCM2 = cvCreateMat(3, 3, CV_MAT32F);
3683  CvMat* tmpMatr = cvCreateMat(3, 3, CV_MAT32F);
3684  CvMat* invCM1T = cvCreateMat(3, 3, CV_MAT32F);
3685 
3686  cvTranspose(&cameraMatr1C, tmpMatr);
3687  cvInvert(tmpMatr, invCM1T);
3688  cvmMul(invCM1T, &essMatrC, tmpMatr);
3689  cvInvert(&cameraMatr2C, invCM2);
3690  cvmMul(tmpMatr, invCM2, &fundMatrC);
3691 
3692  /* Scale fundamental matrix */
3693  double scale;
3694  scale = 1.0 / fundMatrC.data.fl[8];
3695  cvConvertScale(&fundMatrC, &fundMatrC, scale);
3696 
3697  cvReleaseMat(&invCM2);
3698  cvReleaseMat(&tmpMatr);
3699  cvReleaseMat(&invCM1T);
3700 
3701  return CV_OK;
3702 }
3703 
3704 /* Compute essential matrix */
3705 
3707  CvMatr32f transVect,
3708  CvMatr32f essMatr)
3709 {
3710  float transMatr[9];
3711 
3712  /* Make antisymmetric matrix from transpose vector */
3713  transMatr[0] = 0;
3714  transMatr[1] = - transVect[2];
3715  transMatr[2] = transVect[1];
3716 
3717  transMatr[3] = transVect[2];
3718  transMatr[4] = 0;
3719  transMatr[5] = - transVect[0];
3720 
3721  transMatr[6] = - transVect[1];
3722  transMatr[7] = transVect[0];
3723  transMatr[8] = 0;
3724 
3725  icvMulMatrix_32f(transMatr, 3, 3, rotMatr, 3, 3, essMatr);
3726 
3727  return CV_OK;
3728 }
3729 // END
3730 
3731 void CvCalibFilter::Stop(bool calibrate)
3732 {
3733  int i, j;
3734  isCalibrated = false;
3735 
3736  // deallocate undistortion maps
3737  for (i = 0; i < cameraCount; i++)
3738  {
3739  cvReleaseMat(&undistMap[i][0]);
3740  cvReleaseMat(&undistMap[i][1]);
3741  cvReleaseMat(&rectMap[i][0]);
3742  cvReleaseMat(&rectMap[i][1]);
3743  }
3744 
3745  if (calibrate && framesAccepted > 0)
3746  {
3747  int n = framesAccepted;
3748  CvPoint3D32f* buffer =
3749  (CvPoint3D32f*)cvAlloc(n * etalonPointCount * sizeof(buffer[0]));
3750  CvMat mat;
3751  float* rotMatr = (float*)cvAlloc(n * 9 * sizeof(rotMatr[0]));
3752  float* transVect = (float*)cvAlloc(n * 3 * sizeof(transVect[0]));
3753  int* counts = (int*)cvAlloc(n * sizeof(counts[0]));
3754 
3755  cvInitMatHeader(&mat, 1, sizeof(CvCamera) / sizeof(float), CV_32FC1, 0);
3756  memset(cameraParams, 0, cameraCount * sizeof(cameraParams[0]));
3757 
3758  for (i = 0; i < framesAccepted; i++)
3759  {
3760  counts[i] = etalonPointCount;
3761  for (j = 0; j < etalonPointCount; j++)
3762  buffer[i * etalonPointCount + j] = cvPoint3D32f(etalonPoints[j].x,
3763  etalonPoints[j].y, 0);
3764  }
3765 
3766  for (i = 0; i < cameraCount; i++)
3767  {
3768  cvCalibrateCamera(framesAccepted, counts,
3769  imgSize, points[i], buffer,
3770  cameraParams[i].distortion,
3771  cameraParams[i].matrix,
3772  transVect, rotMatr, 0);
3773 
3774  cameraParams[i].imgSize[0] = (float)imgSize.width;
3775  cameraParams[i].imgSize[1] = (float)imgSize.height;
3776 
3777  // cameraParams[i].focalLength[0] = cameraParams[i].matrix[0];
3778  // cameraParams[i].focalLength[1] = cameraParams[i].matrix[4];
3779 
3780  // cameraParams[i].principalPoint[0] = cameraParams[i].matrix[2];
3781  // cameraParams[i].principalPoint[1] = cameraParams[i].matrix[5];
3782 
3783  memcpy(cameraParams[i].rotMatr, rotMatr, 9 * sizeof(rotMatr[0]));
3784  memcpy(cameraParams[i].transVect, transVect, 3 * sizeof(transVect[0]));
3785 
3786  mat.data.ptr = (uchar*)(cameraParams + i);
3787 
3788  /* check resultant camera parameters: if there are some INF's or NAN's,
3789  stop and reset results */
3790  if (!cvCheckArr(&mat, CV_CHECK_RANGE | CV_CHECK_QUIET, -10000, 10000))
3791  {
3792  break;
3793  }
3794  }
3795 
3796 
3797 
3798  isCalibrated = i == cameraCount;
3799 
3800  {
3801  /* calibrate stereo cameras */
3802  if (cameraCount == 2)
3803  {
3804  stereo.camera[0] = &cameraParams[0];
3805  stereo.camera[1] = &cameraParams[1];
3806 
3808  imgSize,
3809  points[0], points[1],
3810  buffer,
3811  &stereo);
3812  }
3813 
3814  }
3815 
3816  cvFree(&buffer);
3817  cvFree(&counts);
3818  cvFree(&rotMatr);
3819  cvFree(&transVect);
3820  }
3821 
3822  framesAccepted = 0;
3823 }
3824 
3825 
3826 bool CvCalibFilter::FindEtalon(IplImage** imgs)
3827 {
3828  return FindEtalon((CvMat**)imgs);
3829 }
3830 
3831 int cvFindChessBoardCornerGuesses(const void* arr, void*,
3832  CvMemStorage*, CvSize pattern_size,
3833  CvPoint2D32f* corners, int* corner_count)
3834 {
3835  return cvFindChessboardCorners(arr, pattern_size, corners,
3836  corner_count, CV_CALIB_CB_ADAPTIVE_THRESH);
3837 }
3838 
3839 bool CvCalibFilter::FindEtalon(CvMat** mats)
3840 {
3841  bool result = true;
3842 
3843  if (!mats || etalonPointCount == 0)
3844  {
3845  assert(0);
3846  result = false;
3847  }
3848 
3849  if (result)
3850  {
3851  int i, tempPointCount0 = etalonPointCount * 2;
3852 
3853  for (i = 0; i < cameraCount; i++)
3854  {
3855  if (!latestPoints[i])
3856  latestPoints[i] = (CvPoint2D32f*)
3857  cvAlloc(tempPointCount0 * 2 * sizeof(latestPoints[0]));
3858  }
3859 
3860  for (i = 0; i < cameraCount; i++)
3861  {
3862  CvSize size;
3863  int tempPointCount = tempPointCount0;
3864  bool found = false;
3865 
3866  if (!CV_IS_MAT(mats[i]) && !CV_IS_IMAGE(mats[i]))
3867  {
3868  assert(0);
3869  break;
3870  }
3871 
3872  size = cvGetSize(mats[i]);
3873 
3874  if (size.width != imgSize.width || size.height != imgSize.height)
3875  {
3876  imgSize = size;
3877  }
3878 
3879  if (!grayImg || grayImg->width != imgSize.width ||
3880  grayImg->height != imgSize.height)
3881  {
3882  cvReleaseMat(&grayImg);
3883  cvReleaseMat(&tempImg);
3884  grayImg = cvCreateMat(imgSize.height, imgSize.width, CV_8UC1);
3885  tempImg = cvCreateMat(imgSize.height, imgSize.width, CV_8UC1);
3886  }
3887 
3888  if (!storage)
3889  {
3890  storage = cvCreateMemStorage();
3891  }
3892 
3893  switch (etalonType)
3894  {
3896  if (CV_MAT_CN(cvGetElemType(mats[i])) == 1)
3897  {
3898  cvCopy(mats[i], grayImg);
3899  }
3900  else
3901  {
3902  cvCvtColor(mats[i], grayImg, CV_BGR2GRAY);
3903  }
3905  cvSize(cvRound(etalonParams[0]),
3906  cvRound(etalonParams[1])),
3907  latestPoints[i], &tempPointCount) != 0;
3908  if (found)
3909  cvFindCornerSubPix(grayImg, latestPoints[i], tempPointCount,
3910  cvSize(5, 5), cvSize(-1, -1),
3911  cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10, 0.1));
3912  break;
3913  default:
3914  assert(0);
3915  result = false;
3916  break;
3917  }
3918 
3919  latestCounts[i] = found ? tempPointCount : -tempPointCount;
3920  result = result && found;
3921  }
3922  }
3923 
3924  if (storage)
3925  {
3926  cvClearMemStorage(storage);
3927  }
3928 
3929  return result;
3930 }
3931 
3932 
3933 bool CvCalibFilter::Push(const CvPoint2D32f** pts)
3934 {
3935  bool result = true;
3936  int i, newMaxPoints = etalonPointCount * (MAX(framesAccepted, framesTotal) + 1);
3937 
3938  isCalibrated = false;
3939 
3940  if (!pts)
3941  {
3942  for (i = 0; i < cameraCount; i++)
3943  if (latestCounts[i] <= 0)
3944  {
3945  return false;
3946  }
3947  pts = (const CvPoint2D32f**)latestPoints;
3948  }
3949 
3950  for (i = 0; i < cameraCount; i++)
3951  {
3952  if (!pts[i])
3953  {
3954  assert(0);
3955  break;
3956  }
3957 
3958  if (maxPoints < newMaxPoints)
3959  {
3960  CvPoint2D32f* prev = points[i];
3961  cvFree(points + i);
3962  points[i] = (CvPoint2D32f*)cvAlloc(newMaxPoints * sizeof(prev[0]));
3963  memcpy(points[i], prev, maxPoints * sizeof(prev[0]));
3964  }
3965 
3966  memcpy(points[i] + framesAccepted * etalonPointCount, pts[i],
3967  etalonPointCount * sizeof(points[0][0]));
3968  }
3969 
3970  if (maxPoints < newMaxPoints)
3971  {
3972  maxPoints = newMaxPoints;
3973  }
3974 
3975  result = i == cameraCount;
3976 
3977  if (++framesAccepted >= framesTotal)
3978  {
3979  Stop(true);
3980  }
3981  return result;
3982 }
3983 
3984 
3985 bool CvCalibFilter::GetLatestPoints(int idx, CvPoint2D32f** pts,
3986  int* count, bool* found)
3987 {
3988  int n;
3989 
3990  if ((unsigned)idx >= (unsigned)cameraCount ||
3991  !pts || !count || !found)
3992  {
3993  assert(0);
3994  return false;
3995  }
3996 
3997  n = latestCounts[idx];
3998 
3999  *found = n > 0;
4000  *count = abs(n);
4001  *pts = latestPoints[idx];
4002 
4003  return true;
4004 }
4005 
4006 
4007 void CvCalibFilter::DrawPoints(IplImage** dst)
4008 {
4009  DrawPoints((CvMat**)dst);
4010 }
4011 
4012 
4013 void CvCalibFilter::DrawPoints(CvMat** dstarr)
4014 {
4015  int i, j;
4016 
4017  if (!dstarr)
4018  {
4019  assert(0);
4020  return;
4021  }
4022 
4023  for (i = 0; i < cameraCount; i++)
4024  {
4025  if (dstarr[i] && latestCounts[i])
4026  {
4027  CvMat dst_stub, *dst;
4028  int count = 0;
4029  bool found = false;
4030  CvPoint2D32f* pts = 0;
4031 
4032  GetLatestPoints(i, &pts, &count, &found);
4033 
4034  dst = cvGetMat(dstarr[i], &dst_stub);
4035 
4036  static const CvScalar line_colors[] =
4037  {
4038  CvScalar(0, 0, 255),
4039  CvScalar(0, 128, 255),
4040  CvScalar(0, 200, 200),
4041  CvScalar(0, 255, 0),
4042  CvScalar(200, 200, 0),
4043  CvScalar(255, 0, 0),
4044  CvScalar(255, 0, 255)
4045  };
4046 
4047  const int colorCount = sizeof(line_colors) / sizeof(line_colors[0]);
4048  const int r = 4;
4049  CvScalar color = line_colors[0];
4050  CvPoint prev_pt = { 0, 0};
4051 
4052  for (j = 0; j < count; j++)
4053  {
4054  CvPoint pt;
4055  pt.x = cvRound(pts[j].x);
4056  pt.y = cvRound(pts[j].y);
4057 
4058  if (found)
4059  {
4061  {
4062  color = line_colors[(j / cvRound(etalonParams[0])) % colorCount];
4063  }
4064  else
4065  {
4066  color = CV_RGB(0, 255, 0);
4067  }
4068 
4069  if (j != 0)
4070  {
4071  cvLine(dst, prev_pt, pt, color, 1, CV_AA);
4072  }
4073  }
4074 
4075  cvLine(dst, cvPoint(pt.x - r, pt.y - r),
4076  cvPoint(pt.x + r, pt.y + r), color, 1, CV_AA);
4077 
4078  cvLine(dst, cvPoint(pt.x - r, pt.y + r),
4079  cvPoint(pt.x + r, pt.y - r), color, 1, CV_AA);
4080 
4081  cvCircle(dst, pt, r + 1, color, 1, CV_AA);
4082 
4083  prev_pt = pt;
4084  }
4085  }
4086  }
4087 }
4088 
4089 
4090 /* Get total number of frames and already accepted pair of frames */
4091 int CvCalibFilter::GetFrameCount(int* total) const
4092 {
4093  if (total)
4094  {
4095  *total = framesTotal;
4096  }
4097 
4098  return framesAccepted;
4099 }
4100 
4101 
4102 /* Get camera parameters for specified camera. If camera is not calibrated
4103  the function returns 0 */
4104 const CvCamera* CvCalibFilter::GetCameraParams(int idx) const
4105 {
4106  if ((unsigned)idx >= (unsigned)cameraCount)
4107  {
4108  assert(0);
4109  return 0;
4110  }
4111 
4112  return isCalibrated ? cameraParams + idx : 0;
4113 }
4114 
4115 
4116 /* Get camera parameters for specified camera. If camera is not calibrated
4117  the function returns 0 */
4118 const CvStereoCamera* CvCalibFilter::GetStereoParams() const
4119 {
4120  if (!(isCalibrated && cameraCount == 2))
4121  {
4122  assert(0);
4123  return 0;
4124  }
4125 
4126  return &stereo;
4127 }
4128 
4129 
4130 /* Sets camera parameters for all cameras */
4131 bool CvCalibFilter::SetCameraParams(CvCamera* params)
4132 {
4133  CvMat mat;
4134  int arrSize;
4135 
4136  Stop();
4137 
4138  if (!params)
4139  {
4140  assert(0);
4141  return false;
4142  }
4143 
4144  arrSize = cameraCount * sizeof(params[0]);
4145 
4146  cvInitMatHeader(&mat, 1, cameraCount * (arrSize / sizeof(float)),
4147  CV_32FC1, params);
4148  cvCheckArr(&mat, CV_CHECK_RANGE, -10000, 10000);
4149 
4150  memcpy(cameraParams, params, arrSize);
4151  isCalibrated = true;
4152 
4153  return true;
4154 }
4155 
4156 
4158 {
4159  if (isCalibrated)
4160  {
4161  int i, j;
4162 
4163  FILE* f = fopen(filename, "w");
4164 
4165  if (!f)
4166  {
4167  return false;
4168  }
4169 
4170  fprintf(f, "%d\n\n", cameraCount);
4171 
4172  for (i = 0; i < cameraCount; i++)
4173  {
4174  for (j = 0; j < (int)(sizeof(cameraParams[i]) / sizeof(float)); j++)
4175  {
4176  fprintf(f, "%15.10f ", ((float*)(cameraParams + i))[j]);
4177  }
4178  fprintf(f, "\n\n");
4179  }
4180 
4181  /* Save stereo params */
4182 
4183  /* Save quad */
4184  for (i = 0; i < 2; i++)
4185  {
4186  for (j = 0; j < 4; j++)
4187  {
4188  fprintf(f, "%15.10f ", stereo.quad[i][j].x);
4189  fprintf(f, "%15.10f ", stereo.quad[i][j].y);
4190  }
4191  fprintf(f, "\n");
4192  }
4193 
4194  /* Save coeffs */
4195  for (i = 0; i < 2; i++)
4196  {
4197  for (j = 0; j < 9; j++)
4198  {
4199  fprintf(f, "%15.10lf ", stereo.coeffs[i][j / 3][j % 3]);
4200  }
4201  fprintf(f, "\n");
4202  }
4203 
4204 
4205  fclose(f);
4206  return true;
4207  }
4208 
4209  return true;
4210 }
4211 
4212 
4214 {
4215  int i, j;
4216  int d = 0;
4217  FILE* f = fopen(filename, "r");
4218 
4219  isCalibrated = false;
4220 
4221  if (!f)
4222  {
4223  return false;
4224  }
4225 
4226  if (fscanf(f, "%d", &d) != 1 || d <= 0 || d > 10)
4227  {
4228  return false;
4229  }
4230 
4231  SetCameraCount(d);
4232 
4233  for (i = 0; i < cameraCount; i++)
4234  {
4235  for (j = 0; j < (int)(sizeof(cameraParams[i]) / sizeof(float)); j++)
4236  {
4237  int values_read = fscanf(f, "%f", &((float*)(cameraParams + i))[j]);
4238  CV_Assert(values_read == 1);
4239  }
4240  }
4241 
4242 
4243  /* Load stereo params */
4244 
4245  /* load quad */
4246  for (i = 0; i < 2; i++)
4247  {
4248  for (j = 0; j < 4; j++)
4249  {
4250  int values_read = fscanf(f, "%f ", &(stereo.quad[i][j].x));
4251  CV_Assert(values_read == 1);
4252  values_read = fscanf(f, "%f ", &(stereo.quad[i][j].y));
4253  CV_Assert(values_read == 1);
4254  }
4255  }
4256 
4257  /* Load coeffs */
4258  for (i = 0; i < 2; i++)
4259  {
4260  for (j = 0; j < 9; j++)
4261  {
4262  int values_read = fscanf(f, "%lf ", &(stereo.coeffs[i][j / 3][j % 3]));
4263  CV_Assert(values_read == 1);
4264  }
4265  }
4266 
4267 
4268 
4269 
4270  fclose(f);
4271 
4272  stereo.warpSize = cvSize(cvRound(cameraParams[0].imgSize[0]), cvRound(cameraParams[0].imgSize[1]));
4273 
4274  isCalibrated = true;
4275 
4276  return true;
4277 }
4278 
4279 
4280 bool CvCalibFilter::Rectify(IplImage** srcarr, IplImage** dstarr)
4281 {
4282  return Rectify((CvMat**)srcarr, (CvMat**)dstarr);
4283 }
4284 
4285 bool CvCalibFilter::Rectify(CvMat** srcarr, CvMat** dstarr)
4286 {
4287  int i;
4288 
4289  if (!srcarr || !dstarr)
4290  {
4291  assert(0);
4292  return false;
4293  }
4294 
4295  if (isCalibrated && cameraCount == 2)
4296  {
4297  for (i = 0; i < cameraCount; i++)
4298  {
4299  if (srcarr[i] && dstarr[i])
4300  {
4301  IplImage src_stub, *src;
4302  IplImage dst_stub, *dst;
4303 
4304  src = cvGetImage(srcarr[i], &src_stub);
4305  dst = cvGetImage(dstarr[i], &dst_stub);
4306 
4307  if (src->imageData == dst->imageData)
4308  {
4309  if (!undistImg ||
4310  undistImg->width != src->width ||
4311  undistImg->height != src->height ||
4312  CV_MAT_CN(undistImg->type) != src->nChannels)
4313  {
4314  cvReleaseMat(&undistImg);
4315  undistImg = cvCreateMat(src->height, src->width,
4316  CV_8U + (src->nChannels - 1) * 8);
4317  }
4318  cvCopy(src, undistImg);
4319  src = cvGetImage(undistImg, &src_stub);
4320  }
4321 
4322  cvZero(dst);
4323 
4324  if (!rectMap[i][0] || rectMap[i][0]->width != src->width ||
4325  rectMap[i][0]->height != src->height)
4326  {
4327  cvReleaseMat(&rectMap[i][0]);
4328  cvReleaseMat(&rectMap[i][1]);
4329  rectMap[i][0] = cvCreateMat(stereo.warpSize.height, stereo.warpSize.width, CV_32FC1);
4330  rectMap[i][1] = cvCreateMat(stereo.warpSize.height, stereo.warpSize.width, CV_32FC1);
4331  cvComputePerspectiveMap(stereo.coeffs[i], rectMap[i][0], rectMap[i][1]);
4332  }
4333  cvRemap(src, dst, rectMap[i][0], rectMap[i][1]);
4334  }
4335  }
4336  }
4337  else
4338  {
4339  for (i = 0; i < cameraCount; i++)
4340  {
4341  if (srcarr[i] != dstarr[i])
4342  {
4343  cvCopy(srcarr[i], dstarr[i]);
4344  }
4345  }
4346  }
4347 
4348  return true;
4349 }
4350 
4351 bool CvCalibFilter::Undistort(IplImage** srcarr, IplImage** dstarr)
4352 {
4353  return Undistort((CvMat**)srcarr, (CvMat**)dstarr);
4354 }
4355 
4356 
4357 bool CvCalibFilter::Undistort(CvMat** srcarr, CvMat** dstarr)
4358 {
4359  int i;
4360 
4361  if (!srcarr || !dstarr)
4362  {
4363  assert(0);
4364  return false;
4365  }
4366 
4367  if (isCalibrated)
4368  {
4369  for (i = 0; i < cameraCount; i++)
4370  {
4371  if (srcarr[i] && dstarr[i])
4372  {
4373  CvMat src_stub, *src;
4374  CvMat dst_stub, *dst;
4375 
4376  src = cvGetMat(srcarr[i], &src_stub);
4377  dst = cvGetMat(dstarr[i], &dst_stub);
4378 
4379  if (src->data.ptr == dst->data.ptr)
4380  {
4381  if (!undistImg || undistImg->width != src->width ||
4382  undistImg->height != src->height ||
4383  CV_ARE_TYPES_EQ(undistImg, src))
4384  {
4385  cvReleaseMat(&undistImg);
4386  undistImg = cvCreateMat(src->height, src->width, src->type);
4387  }
4388 
4389  cvCopy(src, undistImg);
4390  src = undistImg;
4391  }
4392 
4393 #if 1
4394  {
4395  CvMat A = cvMat(3, 3, CV_32FC1, cameraParams[i].matrix);
4396  CvMat k = cvMat(1, 4, CV_32FC1, cameraParams[i].distortion);
4397 
4398  if (!undistMap[i][0] || undistMap[i][0]->width != src->width ||
4399  undistMap[i][0]->height != src->height)
4400  {
4401  cvReleaseMat(&undistMap[i][0]);
4402  cvReleaseMat(&undistMap[i][1]);
4403  undistMap[i][0] = cvCreateMat(src->height, src->width, CV_32FC1);
4404  undistMap[i][1] = cvCreateMat(src->height, src->width, CV_32FC1);
4405  cvInitUndistortMap(&A, &k, undistMap[i][0], undistMap[i][1]);
4406  }
4407 
4408  cvRemap(src, dst, undistMap[i][0], undistMap[i][1]);
4409 #else
4410  cvUndistort2(src, dst, &A, &k);
4411 #endif
4412  }
4413  }
4414  }
4415  }
4416  else
4417  {
4418  for (i = 0; i < cameraCount; i++)
4419  {
4420  if (srcarr[i] != dstarr[i])
4421  {
4422  cvCopy(srcarr[i], dstarr[i]);
4423  }
4424  }
4425  }
4426 
4427 
4428  return true;
4429 }
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:662
CvCalibFilter::Stop
virtual void Stop(bool calibrate=false)
Definition: calibfilter.cpp:3731
CvCalibFilter::SetFrames
virtual bool SetFrames(int totalFrames)
Definition: calibfilter.cpp:258
CV_OK
@ CV_OK
Definition: calibfilter.cpp:500
CV_MAT4x4_64D
@ CV_MAT4x4_64D
Definition: calibfilter.cpp:531
icvCheckVector_32f
#define icvCheckVector_32f(ptr, len)
Definition: calibfilter.cpp:310
CV_UNMATCHED_ROI_ERR
@ CV_UNMATCHED_ROI_ERR
Definition: calibfilter.cpp:469
CvCalibFilter::imgSize
CvSize imgSize
Definition: calibfilter.h:185
icvGetSymPoint3D
int icvGetSymPoint3D(CvPoint3D64d pointCorner, CvPoint3D64d point1, CvPoint3D64d point2, CvPoint3D64d *pointSym2)
Definition: calibfilter.cpp:555
EPS64D
#define EPS64D
Definition: calibfilter.cpp:508
icvGetCrossPieceVector
int icvGetCrossPieceVector(CvPoint2D32f p1_start, CvPoint2D32f p1_end, CvPoint2D32f v2_start, CvPoint2D32f v2_end, CvPoint2D32f *cross)
Definition: calibfilter.cpp:3557
icvGetCoefForPiece
void icvGetCoefForPiece(CvPoint2D64d p_start, CvPoint2D64d p_end, double *a, double *b, double *c, int *result)
Definition: calibfilter.cpp:1281
CvVect64d
double * CvVect64d
Definition: calibfilter.cpp:513
CV_UNSUPPORTED_CHANNELS_ERR
@ CV_UNSUPPORTED_CHANNELS_ERR
Definition: calibfilter.cpp:478
CV_NOTFOUND_ERR
@ CV_NOTFOUND_ERR
Definition: calibfilter.cpp:470
icvProjectPointToImage
void icvProjectPointToImage(CvPoint3D64d point, CvMatr64d camMatr, CvMatr64d rotMatr, CvVect64d transVect, CvPoint2D64d *projPoint)
Definition: calibfilter.cpp:1805
CV_BADCONVERGENCE_ERR
@ CV_BADCONVERGENCE_ERR
Definition: calibfilter.cpp:471
icvComputeRestStereoParams
int icvComputeRestStereoParams(CvStereoCamera *stereoparams)
Definition: calibfilter.cpp:3389
CvCalibFilter::Push
virtual bool Push(const CvPoint2D32f **points=0)
Definition: calibfilter.cpp:3933
icvComputeeInfiniteProject1
void icvComputeeInfiniteProject1(CvMatr64d rotMatr, CvMatr64d camMatr1, CvMatr64d camMatr2, CvPoint2D32f point1, CvPoint2D32f *point2)
Definition: calibfilter.cpp:2951
CV_MAT3x3_32F
@ CV_MAT3x3_32F
Definition: calibfilter.cpp:524
CV_INPLACE_NOT_SUPPORTED_ERR
@ CV_INPLACE_NOT_SUPPORTED_ERR
Definition: calibfilter.cpp:468
CvCalibFilter::GetFrameCount
virtual int GetFrameCount(int *framesTotal=0) const
Definition: calibfilter.cpp:4091
CvCalibFilter::Undistort
virtual bool Undistort(IplImage **src, IplImage **dst)
Definition: calibfilter.cpp:4351
__END__
#define __END__
Definition: calibfilter.cpp:2783
CV_BADSTEP_ERR
@ CV_BADSTEP_ERR
Definition: calibfilter.cpp:487
CvCalibFilter::points
CvPoint2D32f * points[MAX_CAMERAS]
Definition: calibfilter.h:194
CV_BADMEMBLOCK_ERR
@ CV_BADMEMBLOCK_ERR
Definition: calibfilter.cpp:467
CvCalibFilter::etalonParams
double * etalonParams
Definition: calibfilter.h:182
CvCalibFilter::latestCounts
int latestCounts[MAX_CAMERAS]
Definition: calibfilter.h:197
icvGetMiddleAnglePoint
void icvGetMiddleAnglePoint(CvPoint2D64d basePoint, CvPoint2D64d point1, CvPoint2D64d point2, CvPoint2D64d *midPoint)
Definition: calibfilter.cpp:2592
CvCalibFilter::cameraParams
CvCamera cameraParams[MAX_CAMERAS]
Definition: calibfilter.h:192
CvVect32f
float * CvVect32f
Definition: calibfilter.cpp:515
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
cvGetMatSize
CV_INLINE CvSize cvGetMatSize(const CvMat *mat)
Definition: calibfilter.cpp:2772
icvComputeeInfiniteProject2
void icvComputeeInfiniteProject2(CvMatr64d rotMatr, CvMatr64d camMatr1, CvMatr64d camMatr2, CvPoint2D32f *point1, CvPoint2D32f point2)
Definition: calibfilter.cpp:2999
CvCalibFilter::tempImg
CvMat * tempImg
Definition: calibfilter.h:187
CV_BADFACTOR_ERR
@ CV_BADFACTOR_ERR
Definition: calibfilter.cpp:493
icvCompute3DPoint
int icvCompute3DPoint(double alpha, double betta, CvStereoLineCoeff *coeffs, CvPoint3D64d *point)
Definition: calibfilter.cpp:579
icvComputeStereoParamsForCameras
void icvComputeStereoParamsForCameras(CvStereoCamera *stereoCamera)
Definition: calibfilter.cpp:2349
CvCalibFilter::isCalibrated
bool isCalibrated
Definition: calibfilter.h:207
CvCalibFilter::stereo
CvStereoCamera stereo
Definition: calibfilter.h:193
CV_BADSCALE_ERR
@ CV_BADSCALE_ERR
Definition: calibfilter.cpp:495
CvMatr32f
float * CvMatr32f
Definition: calibfilter.cpp:510
CvCalibFilter::FindEtalon
virtual bool FindEtalon(IplImage **imgs)
Definition: calibfilter.cpp:3826
CvCalibFilter::GetStereoParams
virtual const CvStereoCamera * GetStereoParams() const
Definition: calibfilter.cpp:4118
CvCalibFilter::undistImg
CvMat * undistImg
Definition: calibfilter.h:196
icvSubVector_64d
CV_INLINE void icvSubVector_64d(const double *src1, const double *src2, double *dst, int len)
Definition: calibfilter.cpp:339
CvCalibFilter::SetCameraParams
virtual bool SetCameraParams(CvCamera *params)
Definition: calibfilter.cpp:4131
CV_WARP_TO_CAMERA
#define CV_WARP_TO_CAMERA
Definition: calibfilter.h:63
CvStatus
CvStatus
Definition: calibfilter.cpp:465
icvGetCrossDirectDirect
void icvGetCrossDirectDirect(CvVect64d direct1, CvVect64d direct2, CvPoint2D64d *cross, int *result)
Definition: calibfilter.cpp:1549
icvGetCrossLineDirect
int icvGetCrossLineDirect(CvPoint2D32f p1, CvPoint2D32f p2, float a, float b, float c, CvPoint2D32f *cross)
Definition: calibfilter.cpp:3598
__BEGIN__
#define __BEGIN__
Definition: calibfilter.cpp:2782
CvCalibFilter::cameraCount
int cameraCount
Definition: calibfilter.h:191
CV_BADARG_ERR
@ CV_BADARG_ERR
Definition: calibfilter.cpp:482
icvGetQuadsTransform
void icvGetQuadsTransform(CvSize imageSize, CvMatr64d camMatr1, CvMatr64d rotMatr1, CvVect64d transVect1, CvMatr64d camMatr2, CvMatr64d rotMatr2, CvVect64d transVect2, CvSize *warpSize, double quad1[4][2], double quad2[4][2], CvMatr64d fundMatr, CvPoint3D64d *epipole1, CvPoint3D64d *epipole2)
Definition: calibfilter.cpp:1856
cvConvertEssential2Fundamental
int cvConvertEssential2Fundamental(CvMatr32f essMatr, CvMatr32f fundMatr, CvMatr32f cameraMatr1, CvMatr32f cameraMatr2)
Definition: calibfilter.cpp:3670
CvPoint2D64d
CvPoint2D64f CvPoint2D64d
Definition: calibfilter.cpp:511
CvCalibFilter::GetEtalon
virtual CvCalibEtalonType GetEtalon(int *paramCount=0, const double **etalonParams=0, int *pointCount=0, const CvPoint2D32f **etalonPoints=0) const
Definition: calibfilter.cpp:208
CV_OUTOFMEM_ERR
@ CV_OUTOFMEM_ERR
Definition: calibfilter.cpp:496
CvCalibFilter::framesAccepted
int framesAccepted
Definition: calibfilter.h:206
cvComputePerspectiveMap
CV_IMPL void cvComputePerspectiveMap(const double c[3][3], CvArr *rectMapX, CvArr *rectMapY)
Definition: calibfilter.cpp:2787
CV_BADCHANNELS_ERR
@ CV_BADCHANNELS_ERR
Definition: calibfilter.cpp:485
CV_BADSIZE_ERR
@ CV_BADSIZE_ERR
Definition: calibfilter.cpp:498
CV_BADCOEF_ERR
@ CV_BADCOEF_ERR
Definition: calibfilter.cpp:491
icvTransposeMatrix_64d
CV_INLINE void icvTransposeMatrix_64d(const double *src, int w, int h, double *dst)
Definition: calibfilter.cpp:397
icvMulMatrix_64d
CV_INLINE void icvMulMatrix_64d(const double *src1, int w1, int h1, const double *src2, int w2, int h2, double *dst)
Definition: calibfilter.cpp:351
CV_MAT4x4_32F
@ CV_MAT4x4_32F
Definition: calibfilter.cpp:525
icvConvertWarpCoordinates
int icvConvertWarpCoordinates(double coeffs[3][3], CvPoint2D32f *cameraPoint, CvPoint2D32f *warpPoint, int direction)
Definition: calibfilter.cpp:3347
icvGetNormalDirect
void icvGetNormalDirect(CvVect64d direct, CvPoint2D64d point, CvVect64d normDirect)
Definition: calibfilter.cpp:2397
armarx::status
status
Definition: FiniteStateMachine.h:259
CvCalibFilter::MAX_CAMERAS
@ MAX_CAMERAS
Definition: calibfilter.h:177
CV_BADFLAG_ERR
@ CV_BADFLAG_ERR
Definition: calibfilter.cpp:489
CV_BADROI_ERR
@ CV_BADROI_ERR
Definition: calibfilter.cpp:474
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
CvCalibFilter::Rectify
virtual bool Rectify(IplImage **srcarr, IplImage **dstarr)
Definition: calibfilter.cpp:4280
CV_CAMERA_TO_WARP
#define CV_CAMERA_TO_WARP
Definition: calibfilter.h:62
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:253
CvCalibFilter::CvCalibFilter
CvCalibFilter()
Definition: calibfilter.cpp:50
icvGetCrossPieceDirect
void icvGetCrossPieceDirect(CvPoint2D64d p_start, CvPoint2D64d p_end, double a, double b, double c, CvPoint2D64d *cross, int *result)
Definition: calibfilter.cpp:1588
CvCalibFilter::etalonPoints
CvPoint2D32f * etalonPoints
Definition: calibfilter.h:184
icvDefinePointPosition
float icvDefinePointPosition(CvPoint2D32f point1, CvPoint2D32f point2, CvPoint2D32f point)
Definition: calibfilter.cpp:3335
icvComputeStereoLineCoeffs
int icvComputeStereoLineCoeffs(CvPoint3D64d pointA, CvPoint3D64d pointB, CvPoint3D64d pointCam1, double gamma, CvStereoLineCoeff *coeffs)
Definition: calibfilter.cpp:1103
icvGetDistanceFromPointToDirect
void icvGetDistanceFromPointToDirect(CvPoint2D64d point, CvVect64d lineCoef, double *dist)
Definition: calibfilter.cpp:2685
CV_NOTDEFINED_ERR
@ CV_NOTDEFINED_ERR
Definition: calibfilter.cpp:483
CvCalibFilter::DrawPoints
virtual void DrawPoints(IplImage **dst)
Definition: calibfilter.cpp:4007
CvPoint3D64d
CvPoint3D64f CvPoint3D64d
Definition: calibfilter.cpp:512
icvConvertPointSystem
int icvConvertPointSystem(CvPoint3D64d M2, CvPoint3D64d *M1, CvMatr64d rotMatr, CvMatr64d transVect)
Definition: calibfilter.cpp:656
CV_UNSUPPORTED_DEPTH_ERR
@ CV_UNSUPPORTED_DEPTH_ERR
Definition: calibfilter.cpp:479
calibfilter.h
icvGetDirectionForPoint
int icvGetDirectionForPoint(CvPoint2D64d point, CvMatr64d camMatr, CvPoint3D64d *direct)
Definition: calibfilter.cpp:1000
icvCheckVector_64f
#define icvCheckVector_64f(ptr, len)
Definition: calibfilter.cpp:311
CvCalibFilter::grayImg
CvMat * grayImg
Definition: calibfilter.h:186
CvCalibFilter::framesTotal
int framesTotal
Definition: calibfilter.h:205
icvProjectPointToDirect
void icvProjectPointToDirect(CvPoint2D64d point, CvVect64d lineCoeff, CvPoint2D64d *projectPoint)
Definition: calibfilter.cpp:2668
icvInvertMatrix_64d
CV_INLINE void icvInvertMatrix_64d(double *A, int n, double *invA)
Definition: calibfilter.cpp:377
CV_MAT64D
@ CV_MAT64D
Definition: calibfilter.cpp:527
cross
Point cross(const Point &x, const Point &y)
Definition: point.hpp:33
icvAddVector_64d
CV_INLINE void icvAddVector_64d(const double *src1, const double *src2, double *dst, int len)
Definition: calibfilter.cpp:385
filename
std::string filename
Definition: VisualizationRobot.cpp:84
cvPseudoInverse
double cvPseudoInverse(const CvArr *src, CvArr *dst)
Definition: calibfilter.cpp:410
icvTestPoint
void icvTestPoint(CvPoint2D64d testPoint, CvVect64d line1, CvVect64d line2, CvPoint2D64d basePoint, int *result)
Definition: calibfilter.cpp:2631
CV_MAT32F
@ CV_MAT32F
Definition: calibfilter.cpp:521
icvGetPieceLength
void icvGetPieceLength(CvPoint2D64d point1, CvPoint2D64d point2, double *dist)
Definition: calibfilter.cpp:1690
icvGetAngleLine
int icvGetAngleLine(CvPoint2D64d startPoint, CvSize imageSize, CvPoint2D64d *point1, CvPoint2D64d *point2)
Definition: calibfilter.cpp:1172
CvCalibFilter::etalonPointCount
int etalonPointCount
Definition: calibfilter.h:183
CV_UNSUPPORTED_FORMAT_ERR
@ CV_UNSUPPORTED_FORMAT_ERR
Definition: calibfilter.cpp:480
CvCalibFilter::rectMap
CvMat * rectMap[MAX_CAMERAS][2]
Definition: calibfilter.h:199
CV_BADDEPTH_ERR
@ CV_BADDEPTH_ERR
Definition: calibfilter.cpp:473
CV_UNSUPPORTED_COI_ERR
@ CV_UNSUPPORTED_COI_ERR
Definition: calibfilter.cpp:477
CvCalibFilter::latestPoints
CvPoint2D32f * latestPoints[MAX_CAMERAS]
Definition: calibfilter.h:198
icvGetCutPiece
void icvGetCutPiece(CvVect64d areaLineCoef1, CvVect64d areaLineCoef2, CvPoint2D64d epipole, CvSize imageSize, CvPoint2D64d *point11, CvPoint2D64d *point12, CvPoint2D64d *point21, CvPoint2D64d *point22, int *result)
Definition: calibfilter.cpp:2408
icvMulMatrix_32f
CV_INLINE void icvMulMatrix_32f(const float *src1, int w1, int h1, const float *src2, int w2, int h2, float *dst)
Definition: calibfilter.cpp:313
CvCalibFilter::undistMap
CvMat * undistMap[MAX_CAMERAS][2]
Definition: calibfilter.h:195
icvGetPieceLength3D
void icvGetPieceLength3D(CvPoint3D64d point1, CvPoint3D64d point2, double *dist)
Definition: calibfilter.cpp:1700
CV_MAT3x1_32F
@ CV_MAT3x1_32F
Definition: calibfilter.cpp:522
icvTransformVector_64d
#define icvTransformVector_64d(matr, src, dst, w, h)
Definition: calibfilter.cpp:1310
icvGetCrossRectDirect
void icvGetCrossRectDirect(CvSize imageSize, double a, double b, double c, CvPoint2D64d *start, CvPoint2D64d *end, int *result)
Definition: calibfilter.cpp:1713
CV_BADHEADER_ERR
@ CV_BADHEADER_ERR
Definition: calibfilter.cpp:475
CV_CALIB_ETALON_CHESSBOARD
@ CV_CALIB_ETALON_CHESSBOARD
Definition: calibfilter.h:73
CV_DIV_BY_ZERO_ERR
@ CV_DIV_BY_ZERO_ERR
Definition: calibfilter.cpp:490
A
class A(deque< T, A >)) ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T
Enables hashing of std::list.
CvCalibFilter::SetEtalon
virtual bool SetEtalon(CvCalibEtalonType etalonType, double *etalonParams, int pointCount=0, CvPoint2D32f *points=0)
Definition: calibfilter.cpp:97
CvCalibEtalonType
CvCalibEtalonType
Definition: calibfilter.h:70
CV_MAT4x1_32F
@ CV_MAT4x1_32F
Definition: calibfilter.cpp:523
CvCalibFilter::storage
CvMemStorage * storage
Definition: calibfilter.h:188
cvInitPerspectiveTransform
CV_IMPL void cvInitPerspectiveTransform(CvSize size, const CvPoint2D32f quad[4], double matrix[3][3], CvArr *rectMap)
Definition: calibfilter.cpp:2830
icvComputeCoeffForStereo
int icvComputeCoeffForStereo(CvStereoCamera *stereoCamera)
Definition: calibfilter.cpp:806
CV_MAT4x1_64D
@ CV_MAT4x1_64D
Definition: calibfilter.cpp:529
CvCalibFilter::maxPoints
int maxPoints
Definition: calibfilter.h:204
float
#define float
Definition: 16_Level.h:22
CvCalibFilter::GetCameraParams
virtual const CvCamera * GetCameraParams(int idx=0) const
Definition: calibfilter.cpp:4104
CV_MAT3x1_64D
@ CV_MAT3x1_64D
Definition: calibfilter.cpp:528
CV_CALIB_ETALON_USER
@ CV_CALIB_ETALON_USER
Definition: calibfilter.h:72
CvCalibFilter::GetLatestPoints
virtual bool GetLatestPoints(int idx, CvPoint2D32f **pts, int *count, bool *found)
Definition: calibfilter.cpp:3985
CV_MAT3x3_64D
@ CV_MAT3x3_64D
Definition: calibfilter.cpp:530
CV_NULLPTR_ERR
@ CV_NULLPTR_ERR
Definition: calibfilter.cpp:497
CV_NO_ERR
@ CV_NO_ERR
Definition: calibfilter.cpp:499
icvCreateIsometricImage
CV_IMPL IplImage * icvCreateIsometricImage(IplImage *src, IplImage *dst, int desired_depth, int desired_num_channels)
Definition: calibfilter.cpp:2696
CvCalibFilter::etalonParamCount
int etalonParamCount
Definition: calibfilter.h:181
icvGetCrossPiecePiece
void icvGetCrossPiecePiece(CvPoint2D64d p1_start, CvPoint2D64d p1_end, CvPoint2D64d p2_start, CvPoint2D64d p2_end, CvPoint2D64d *cross, int *result)
Definition: calibfilter.cpp:1633
CV_BADRANGE_ERR
@ CV_BADRANGE_ERR
Definition: calibfilter.cpp:486
CV_BADPOINT_ERR
@ CV_BADPOINT_ERR
Definition: calibfilter.cpp:494
icvGetQuadsTransformStruct
void icvGetQuadsTransformStruct(CvStereoCamera *stereoCamera)
Definition: calibfilter.cpp:2315
cvProjectPointsSimple
void cvProjectPointsSimple(int point_count, CvPoint3D64f *_object_points, double *_rotation_matrix, double *_translation_vector, double *_camera_matrix, double *_distortion, CvPoint2D64f *_image_points)
Definition: calibfilter.cpp:3045
CvCalibFilter::SaveCameraParams
virtual bool SaveCameraParams(const char *filename)
Definition: calibfilter.cpp:4157
cvComputeEssentialMatrix
int cvComputeEssentialMatrix(CvMatr32f rotMatr, CvMatr32f transVect, CvMatr32f essMatr)
Definition: calibfilter.cpp:3706
cvComputeEpipolesFromFundMatrix
int cvComputeEpipolesFromFundMatrix(CvMatr32f fundMatr, CvPoint3D32f *epipole1, CvPoint3D32f *epipole2)
Definition: calibfilter.cpp:3639
distance
double distance(const Point &a, const Point &b)
Definition: point.hpp:88
cvFindChessBoardCornerGuesses
int cvFindChessBoardCornerGuesses(const void *arr, void *, CvMemStorage *, CvSize pattern_size, CvPoint2D32f *corners, int *corner_count)
Definition: calibfilter.cpp:3831
pc
Introduction Thank you for taking interest in our work and downloading this software This library implements the algorithm described in the paper R R R Klein Efficient RANSAC for Point Cloud Shape in Computer Graphics Blackwell June If you use this software you should cite the aforementioned paper in any resulting publication Please send comments or bug reports to Ruwen Roland BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE Example usage This section shows how to use the library to detect the shapes in a point cloud PointCloud pc
Definition: ReadMe.txt:68
icvStereoCalibration
int icvStereoCalibration(int numImages, int *nums, CvSize imageSize, CvPoint2D32f *imagePoints1, CvPoint2D32f *imagePoints2, CvPoint3D32f *objectPoints, CvStereoCamera *stereoparams)
Definition: calibfilter.cpp:3474
CV_UNMATCHED_FORMATS_ERR
@ CV_UNMATCHED_FORMATS_ERR
Definition: calibfilter.cpp:476
CvCalibFilter::etalonType
CvCalibEtalonType etalonType
Definition: calibfilter.h:180
icvComCoeffForLine
int icvComCoeffForLine(CvPoint2D64d point1, CvPoint2D64d point2, CvPoint2D64d point3, CvPoint2D64d point4, CvMatr64d camMatr1, CvMatr64d rotMatr1, CvMatr64d transVect1, CvMatr64d camMatr2, CvMatr64d rotMatr2, CvMatr64d transVect2, CvStereoLineCoeff *coeffs, int *needSwapCamera)
Definition: calibfilter.cpp:849
icvCreateConvertMatrVect
int icvCreateConvertMatrVect(CvMatr64d rotMatr1, CvMatr64d transVect1, CvMatr64d rotMatr2, CvMatr64d transVect2, CvMatr64d convRotMatr, CvMatr64d convTransVect)
Definition: calibfilter.cpp:621
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
CvCalibFilter::SetCameraCount
virtual void SetCameraCount(int cameraCount)
Definition: calibfilter.cpp:235
icvGetVect
CV_IMPL double icvGetVect(CvPoint2D64d basePoint, CvPoint2D64d point1, CvPoint2D64d point2)
Definition: calibfilter.cpp:2622
CvCalibFilter::LoadCameraParams
virtual bool LoadCameraParams(const char *filename)
Definition: calibfilter.cpp:4213
CvCalibFilter::~CvCalibFilter
virtual ~CvCalibFilter()
Definition: calibfilter.cpp:85
cvmMul
#define cvmMul(src1, src2, dst)
Definition: calibfilter.cpp:517
CvMatr64d
double * CvMatr64d
Definition: calibfilter.cpp:514
icvGetCrossLines
int icvGetCrossLines(CvPoint3D64d point11, CvPoint3D64d point12, CvPoint3D64d point21, CvPoint3D64d point22, CvPoint3D64d *midPoint)
Definition: calibfilter.cpp:1029