From df491588638d294ac68054bc4744684936064e8c Mon Sep 17 00:00:00 2001 From: Bernat Gabor Date: Mon, 22 Aug 2011 12:15:31 +0000 Subject: [PATCH] Added the "Camera calibration With OpenCV" tutorial. Extended with a few global links the conf.py file. Corrected an error in the linux_install.rst and one in the cascade_classifier.rst file. --- doc/conf.py | 77 +-- .../camera_calibration/camera_calibration.rst | 444 ++++++++++++++ .../images/asymetricalPattern.jpg | Bin 0 -> 46120 bytes .../images/fileListImage.jpg | Bin 0 -> 34363 bytes .../images/fileListImageUnDist.jpg | Bin 0 -> 29861 bytes .../images/camera_calibration.png | Bin 0 -> 8159 bytes .../table_of_content_calib3d.rst | 20 + .../linux_install/linux_install.rst | 2 +- .../cascade_classifier/cascade_classifier.rst | 14 +- .../calib3d/camera_calibration/VID5.xml | 13 + .../camera_calibration/camera_calibration.cpp | 551 ++++++++++++++++++ .../calib3d/camera_calibration/in_VID5.xml | 46 ++ .../camera_calibration/out_camera_data.yml | 352 +++++++++++ 13 files changed, 1475 insertions(+), 44 deletions(-) create mode 100644 doc/tutorials/calib3d/camera_calibration/camera_calibration.rst create mode 100644 doc/tutorials/calib3d/camera_calibration/images/asymetricalPattern.jpg create mode 100644 doc/tutorials/calib3d/camera_calibration/images/fileListImage.jpg create mode 100644 doc/tutorials/calib3d/camera_calibration/images/fileListImageUnDist.jpg create mode 100644 doc/tutorials/calib3d/table_of_content_calib3d/images/camera_calibration.png create mode 100644 samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml create mode 100644 samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp create mode 100644 samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml create mode 100644 samples/cpp/tutorial_code/calib3d/camera_calibration/out_camera_data.yml diff --git a/doc/conf.py b/doc/conf.py index 41b190ad81..cce41878dc 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -276,7 +276,32 @@ man_pages = [ ] # ---- External links for tutorials ----------------- -extlinks = {'cvt_color': ('http://opencv.willowgarage.com/documentation/cpp/imgproc_miscellaneous_image_transformations.html#cv-cvtcolor%s', None), +extlinks = { + 'basicstructures' : ('http://opencv.itseez.com/modules/core/doc/basic_structures.html#%s', None), + 'oldbasicstructures' : ('http://opencv.itseez.com/modules/core/doc/old_basic_structures.html#%s', None), + 'readwriteimagevideo' : ('http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None), + 'operationsonarrays' : ('http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html#%s', None), + 'utilitysystemfunctions':('http://opencv.itseez.com/modules/core/doc/utility_and_system_functions_and_macros.html#%s', None), + 'imgprocfilter':('http://opencv.itseez.com/modules/imgproc/doc/filtering.html#%s', None), + 'svms':('http://opencv.itseez.com/modules/ml/doc/support_vector_machines.html#%s', None), + 'drawingfunc':('http://opencv.itseez.com/modules/core/doc/drawing_functions.html#%s', None), + 'xmlymlpers':('http://opencv.itseez.com/modules/core/doc/xml_yaml_persistence.html#%s', None), + 'huivideo' : ('http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None), + 'gpuinit' : ('http://opencv.itseez.com/modules/gpu/doc/initalization_and_information.html#%s', None), + 'gpudatastructure' : ('http://opencv.itseez.com/modules/gpu/doc/data_structures.html#%s', None), + 'gpuopmatrices' : ('http://opencv.itseez.com/modules/gpu/doc/operations_on_matrices.html#%s', None), + 'gpuperelement' : ('http://opencv.itseez.com/modules/gpu/doc/per_element_operations.html#%s', None), + 'gpuimgproc' : ('http://opencv.itseez.com/modules/gpu/doc/image_processing.html#%s', None), + 'gpumatrixreduct' : ('http://opencv.itseez.com/modules/gpu/doc/matrix_reductions.html#%s', None), + 'filtering':('http://opencv.itseez.com/modules/imgproc/doc/filtering.html#%s', None), + 'flann' : ('http://opencv.willowgarage.com/documentation/cpp/flann_fast_approximate_nearest_neighbor_search.html#%s', None ), + 'calib3d' : ('http://opencv.itseez.com/trunk/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#%s', None ), + 'feature2d' : ('http://opencv.itseez.com/trunk/modules/imgproc/doc/feature_detection.html#%s', None ), + 'imgproc_geometric' : ('http://opencv.itseez.com/trunk/modules/imgproc/doc/geometric_transformations.html#%s', None ), + + 'opencv_group' : ('http://tech.groups.yahoo.com/group/OpenCV/%s', None), + + 'cvt_color': ('http://opencv.willowgarage.com/documentation/cpp/imgproc_miscellaneous_image_transformations.html#cv-cvtcolor%s', None), 'imread': ('http://opencv.willowgarage.com/documentation/cpp/highgui_reading_and_writing_images_and_video.html?highlight=imread#imread%s', None), 'imwrite': ('http://opencv.willowgarage.com/documentation/cpp/highgui_reading_and_writing_images_and_video.html?highlight=imread#cv-imwrite%s', None), 'imshow': ('http://opencv.willowgarage.com/documentation/cpp/highgui_user_interface.html?highlight=imshow#imshow%s', None), @@ -316,7 +341,6 @@ extlinks = {'cvt_color': ('http://opencv.willowgarage.com/documentation/cpp/imgp 'laplacian': ('http://opencv.willowgarage.com/documentation/cpp/image_filtering.html#cv-laplacian%s', None), 'canny': ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#Canny%s', None), 'copy_to': ('http://opencv.willowgarage.com/documentation/cpp/core_basic_structures.html?#Mat::copyTo%s', None), - 'opencv_group' : ('http://tech.groups.yahoo.com/group/OpenCV/%s', None), 'hough_lines' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-houghlines%s', None), 'hough_lines_p' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-houghlinesp%s', None), 'hough_circles' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-houghcircles%s', None), @@ -348,39 +372,20 @@ extlinks = {'cvt_color': ('http://opencv.willowgarage.com/documentation/cpp/imgp 'moments' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-moments%s', None), 'contour_area' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-contourarea%s', None), 'arc_length' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-arclength%s', None), - 'basicstructures' : ('http://opencv.itseez.com/modules/core/doc/basic_structures.html#%s', None), - 'oldbasicstructures' : ('http://opencv.itseez.com/modules/core/doc/old_basic_structures.html#%s', None), - 'readwriteimagevideo' : ('http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None), - 'operationsonarrays' : ('http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html#%s', None), - 'utilitysystemfunctions':('http://opencv.itseez.com/modules/core/doc/utility_and_system_functions_and_macros.html#%s', None), - 'imgprocfilter':('http://opencv.itseez.com/modules/imgproc/doc/filtering.html#%s', None), - 'svms':('http://opencv.itseez.com/modules/ml/doc/support_vector_machines.html#%s', None), - 'drawingfunc':('http://opencv.itseez.com/modules/core/doc/drawing_functions.html#%s', None), - 'xmlymlpers':('http://opencv.itseez.com/modules/core/doc/xml_yaml_persistence.html#%s', None), - 'huivideo' : ('http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None), - 'gpuinit' : ('http://opencv.itseez.com/modules/gpu/doc/initalization_and_information.html#%s', None), - 'gpudatastructure' : ('http://opencv.itseez.com/modules/gpu/doc/data_structures.html#%s', None), - 'gpuopmatrices' : ('http://opencv.itseez.com/modules/gpu/doc/operations_on_matrices.html#%s', None), - 'gpuperelement' : ('http://opencv.itseez.com/modules/gpu/doc/per_element_operations.html#%s', None), - 'gpuimgproc' : ('http://opencv.itseez.com/modules/gpu/doc/image_processing.html#%s', None), - 'gpumatrixreduct' : ('http://opencv.itseez.com/modules/gpu/doc/matrix_reductions.html#%s', None),'filtering':('http://opencv.itseez.com/modules/imgproc/doc/filtering.html#%s', None), 'point_polygon_test' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-pointpolygontest%s', None), 'feature_detector' : ( 'http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_feature_detectors.html#featuredetector%s', None), - 'feature_detector_detect' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_feature_detectors.html#cv-featuredetector-detect%s', None ), - 'surf_feature_detector' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_feature_detectors.html#surffeaturedetector%s', None ), - 'draw_keypoints' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_drawing_function_of_keypoints_and_matches.html#cv-drawkeypoints%s', None ), - 'descriptor_extractor': ( 'http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_extractors.html#descriptorextractor%s', None ), - 'descriptor_extractor_compute' : ( 'http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_extractors.html#cv-descriptorextractor-compute%s', None ), - 'surf_descriptor_extractor' : ( 'http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_extractors.html#surfdescriptorextractor%s', None ), - 'draw_matches' : ( 'http://opencv.willowgarage.com/documentation/cpp/features2d_drawing_function_of_keypoints_and_matches.html#cv-drawmatches%s', None ), - 'find_homography' : ('http://opencv.willowgarage.com/documentation/cpp/calib3d_camera_calibration_and_3d_reconstruction.html?#findHomography%s', None), - 'perspective_transform' : ('http://opencv.willowgarage.com/documentation/cpp/core_operations_on_arrays.html?#perspectiveTransform%s', None ), - 'flann_based_matcher' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_matchers.html?#FlannBasedMatcher%s', None), - 'brute_force_matcher' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_matchers.html?#BruteForceMatcher%s', None ), - 'flann' : ('http://opencv.willowgarage.com/documentation/cpp/flann_fast_approximate_nearest_neighbor_search.html?%s', None ), - 'cascade_classifier' : ('http://opencv.willowgarage.com/documentation/cpp/objdetect_cascade_classification.html#cascadeclassifier%s', None ), - 'cascade_classifier_load' : ('http://opencv.willowgarage.com/documentation/cpp/objdetect_cascade_classification.html#cv-cascadeclassifier-load%s', None ), - 'cascade_classifier_detect_multiscale' : ('http://opencv.willowgarage.com/documentation/cpp/objdetect_cascade_classification.html#cv-cascadeclassifier-detectmultiscale%s', None ) - } - - + 'feature_detector_detect' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_feature_detectors.html#cv-featuredetector-detect%s', None ), + 'surf_feature_detector' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_feature_detectors.html#surffeaturedetector%s', None ), + 'draw_keypoints' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_drawing_function_of_keypoints_and_matches.html#cv-drawkeypoints%s', None ), + 'descriptor_extractor': ( 'http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_extractors.html#descriptorextractor%s', None ), + 'descriptor_extractor_compute' : ( 'http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_extractors.html#cv-descriptorextractor-compute%s', None ), + 'surf_descriptor_extractor' : ( 'http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_extractors.html#surfdescriptorextractor%s', None ), + 'draw_matches' : ( 'http://opencv.willowgarage.com/documentation/cpp/features2d_drawing_function_of_keypoints_and_matches.html#cv-drawmatches%s', None ), + 'find_homography' : ('http://opencv.willowgarage.com/documentation/cpp/calib3d_camera_calibration_and_3d_reconstruction.html?#findHomography%s', None), + 'perspective_transform' : ('http://opencv.willowgarage.com/documentation/cpp/core_operations_on_arrays.html?#perspectiveTransform%s', None ), + 'flann_based_matcher' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_matchers.html?#FlannBasedMatcher%s', None), + 'brute_force_matcher' : ('http://opencv.willowgarage.com/documentation/cpp/features2d_common_interfaces_of_descriptor_matchers.html?#BruteForceMatcher%s', None ), + 'cascade_classifier' : ('http://opencv.willowgarage.com/documentation/cpp/objdetect_cascade_classification.html#cascadeclassifier%s', None ), + 'cascade_classifier_load' : ('http://opencv.willowgarage.com/documentation/cpp/objdetect_cascade_classification.html#cv-cascadeclassifier-load%s', None ), + 'cascade_classifier_detect_multiscale' : ('http://opencv.willowgarage.com/documentation/cpp/objdetect_cascade_classification.html#cv-cascadeclassifier-detectmultiscale%s', None ) + } \ No newline at end of file diff --git a/doc/tutorials/calib3d/camera_calibration/camera_calibration.rst b/doc/tutorials/calib3d/camera_calibration/camera_calibration.rst new file mode 100644 index 0000000000..ca9c1bba76 --- /dev/null +++ b/doc/tutorials/calib3d/camera_calibration/camera_calibration.rst @@ -0,0 +1,444 @@ +.. _cameraCalibrationOpenCV: + +Camera calibration With OpenCV +****************************** + +Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole* cameras in the late 20th century, they became a common occurrence in our everyday life. Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are constants and with a calibration and some remapping we can correct this. Furthermore, with calibration you may also determinate the relation between the camera's natural units (pixels) and the real world units (for example millimeters). + +Theory +====== + +For the distortion OpenCV takes into account the radial and tangential factors. For the radial one uses the following formula: + +.. math:: + + x_{corrected} = x( 1 + k_1 r^2 + k_2 r^4 + k^3 r^6 \\ + y_{corrected} = y( 1 + k_1 r^2 + k_2 r^4 + k^3 r^6 + +So for an old pixel point at :math:`(x,y)` coordinate in the input image, for a corrected output image its position will be :math:`(x_{corrected} y_{corrected})` . The presence of the radial distortion manifests in form of the "barrel" or "fish-eye" effect. + +Tangential distortion occurs because the image taking lenses are not perfectly parallel to the imaging plane. Correcting this is made via the formulas: + +.. math:: + + x_{corrected} = x + [ 2p_1y + p_2(r^2+2x^2)] \\ + y_{corrected} = y + [ 2p_1(r^2+ 2y^2)+ 2p_2x] + +So we have five distortion parameters, which in OpenCV are organized in a 5 column one row matrix: + +.. math:: + + Distortion_{coefficients}=(k_1 \hspace{10pt} k_2 \hspace{10pt} p_1 \hspace{10pt} p_2 \hspace{10pt} k_3) + +Now for the unit conversion, we use the following formula: + +.. math:: + + \left [ \begin{matrix} x \\ y \\ w \end{matrix} \right ] = \left [ \begin{matrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{matrix} \right ] \left [ \begin{matrix} X \\ Y \\ Z \end{matrix} \right ] + +Here the presence of the :math:`w` is cause we use a homography coordinate system (and :math:`w=Z`). The unknown parameters are :math:`f_x` and :math:`f_y` (camera focal lengths) and :math:`(c_x, c_y)` what are the optical centers expressed in pixels coordinates. If for both axes a common focal length is used with a given :math:`a` aspect ratio (usually 1), then :math:`f_y=f_x*a` and in the upper formula we will have a single :math:`f` focal length. The matrix containing these four parameters is referred to as the *camera matrix*. While the distortion coefficients are the same regardless of the camera resolutions used, these should be scaled along with the current resolution from the calibrated resolution. + +The process of determining these two matrices is the calibration. Calculating these parameters is done by some basic geometrical equations. The equations used depend on the calibrating objects used. Currently OpenCV supports three types of object for calibration: + +.. container:: enumeratevisibleitemswithsquare + + + Classical black-white chessboard + + Symmetrical circle pattern + + Asymmetrical circle pattern + +Basically, you need to take snapshots of these patterns with your camera and let OpenCV find them. Each found pattern equals in a new equation. To solve the equation you need at least a predetermined number of pattern snapshots to form a well-posed equation system. This number is higher for the chessboard pattern and less for the circle ones. For example, in theory the chessboard one requires at least two. However, in practice we have a good amount of noise present in our input images, so for good results you will probably want at least 10 good snapshots of the input pattern in different position. + +Goal +==== + +The sample application will: + +.. container:: enumeratevisibleitemswithsquare + + + Determinate the distortion matrix + + Determinate the camera matrix + + Input from Camera, Video and Image file list + + Configuration from XML/YAML file + + Save the results into XML/YAML file + + Calculate re-projection error + +Source code +=========== + +You may also find the source code in the :file:`samples/cpp/tutorial_code/calib3d/camera_calibration/` folder of the OpenCV source library or :download:`download it from here <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp>`. The program has a single argument. The name of its configuration file. If none given it will try to open the one named "default.xml". :download:`Here's a sample configuration file <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml>` in XML format. In the configuration file you may choose to use as input a camera, a video file or an image list. If you opt for the later one, you need to create a configuration file where you enumerate the images to use. Here's :download:`an example of this <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml>`. The important part to remember is that the images needs to be specified using the absolute path or the relative one from your applications working directory. You may find all this in the beforehand mentioned directory. + +The application starts up with reading the settings from the configuration file. Although, this is an important part of it, it has nothing to do with the subject of this tutorial: *camera calibration*. Therefore, I've chosen to do not post here the code part for that. The technical background on how to do this you can find in the :ref:`fileInputOutputXMLYAML` tutorial. + +Explanation +=========== + +1. **Read the settings.** + + .. code-block:: cpp + + Settings s; + const string inputSettingsFile = argc > 1 ? argv[1] : "default.xml"; + FileStorage fs(inputSettingsFile, FileStorage::READ); // Read the settings + if (!fs.isOpened()) + { + cout << "Could not open the configuration file: \"" << inputSettingsFile << "\"" << endl; + return -1; + } + fs["Settings"] >> s; + fs.release(); // close Settings file + + if (!s.goodInput) + { + cout << "Invalid input detected. Application stopping. " << endl; + return -1; + } + + For this I've used simple OpenCV class input operation. After reading the file I've an additional post-process function that checks for the validity of the input. Only if all of them are good will be the *goodInput* variable true. + +#. **Get next input, if it fails or we have enough of them calibrate**. After this we have a big loop where we do the following operations: get the next image from the image list, camera or video file. If this fails or we have enough images we run the calibration process. In case of image we step out of the loop and otherwise the remaining frames will be undistorted (if the option is set) via changing from *DETECTION* mode to *CALIBRATED* one. + + .. code-block:: cpp + + for(int i = 0;;++i) + { + Mat view; + bool blinkOutput = false; + + view = s.nextImage(); + + //----- If no more image, or got enough, then stop calibration and show result ------------- + if( mode == CAPTURING && imagePoints.size() >= (unsigned)s.nrFrames ) + { + if( runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints)) + mode = CALIBRATED; + else + mode = DETECTION; + } + if(view.empty()) // If no more images then run calibration, save and stop loop. + { + if( imagePoints.size() > 0 ) + runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints); + break; + imageSize = view.size(); // Format input image. + if( s.flipVertical ) flip( view, view, 0 ); + } + + For some cameras we may need to flip the input image. Here we do this too. + +#. **Find the pattern in the current input**. The formation of the equations I mentioned above consists of finding the major patterns in the input: in case of the chessboard this is their corners of the squares and for the circles, well, the circles itself. The position of these will form the result and is collected into the *pointBuf* vector. + + .. code-block:: cpp + + vector pointBuf; + + bool found; + switch( s.calibrationPattern ) // Find feature points on the input format + { + case Settings::CHESSBOARD: + found = findChessboardCorners( view, s.boardSize, pointBuf, + CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE); + break; + case Settings::CIRCLES_GRID: + found = findCirclesGrid( view, s.boardSize, pointBuf ); + break; + case Settings::ASYMMETRIC_CIRCLES_GRID: + found = findCirclesGrid( view, s.boardSize, pointBuf, CALIB_CB_ASYMMETRIC_GRID ); + break; + } + + Depending on the type of the input pattern you use either the :calib3d:`findChessboardCorners ` or the :calib3d:`findCirclesGrid ` function. For both of them you pass on the current image, the size of the board and you'll get back the positions of the patterns. Furthermore, they return a boolean variable that states if in the input we could find or not the pattern (we only need to take into account images where this is true!). + + Then again in case of cameras we only take camera images after an input delay time passed. This is in order to allow for the user to move the chessboard around and as getting different images. Same images mean same equations, and same equations at the calibration will form an ill-posed problem, so the calibration will fail. For square images the position of the corners are only approximate. We may improve this by calling the :feature2d:`cornerSubPix ` function. This way will get a better calibration result. After this we add a valid inputs result to the *imagePoints* vector to collect all of the equations into a single container. Finally, for visualization feedback purposes we will draw the found points on the input image with the :calib3d:`findChessboardCorners ` function. + + .. code-block:: cpp + + if ( found) // If done with success, + { + // improve the found corners' coordinate accuracy for chessboard + if( s.calibrationPattern == Settings::CHESSBOARD) + { + Mat viewGray; + cvtColor(view, viewGray, CV_BGR2GRAY); + cornerSubPix( viewGray, pointBuf, Size(11,11), + Size(-1,-1), TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 )); + } + + if( mode == CAPTURING && // For camera only take new samples after delay time + (!s.inputCapture.isOpened() || clock() - prevTimestamp > s.delay*1e-3*CLOCKS_PER_SEC) ) + { + imagePoints.push_back(pointBuf); + prevTimestamp = clock(); + blinkOutput = s.inputCapture.isOpened(); + } + + // Draw the corners. + drawChessboardCorners( view, s.boardSize, Mat(pointBuf), found ); + } + +#. **Show state and result for the user, plus command line control of the application**. The showing part consists of a text output on the live feed, and for video or camera input to show the "capturing" frame we simply bitwise negate the input image. + + .. code-block:: cpp + + //----------------------------- Output Text ------------------------------------------------ + string msg = (mode == CAPTURING) ? "100/100" : + mode == CALIBRATED ? "Calibrated" : "Press 'g' to start"; + int baseLine = 0; + Size textSize = getTextSize(msg, 1, 1, 1, &baseLine); + Point textOrigin(view.cols - 2*textSize.width - 10, view.rows - 2*baseLine - 10); + + if( mode == CAPTURING ) + { + if(s.showUndistorsed) + msg = format( "%d/%d Undist", (int)imagePoints.size(), s.nrFrames ); + else + msg = format( "%d/%d", (int)imagePoints.size(), s.nrFrames ); + } + + putText( view, msg, textOrigin, 1, 1, mode == CALIBRATED ? GREEN : RED); + + if( blinkOutput ) + bitwise_not(view, view); + + If we only ran the calibration and got the camera matrix plus the distortion coefficients we may just as correct the image with the :imgproc_geometric:`undistort ` function: + + .. code-block:: cpp + + //------------------------- Video capture output undistorted ------------------------------ + if( mode == CALIBRATED && s.showUndistorsed ) + { + Mat temp = view.clone(); + undistort(temp, view, cameraMatrix, distCoeffs); + } + //------------------------------ Show image and check for input commands ------------------- + imshow("Image View", view); + + Then we wait for an input key and if this is *u* we toggle the distortion removal, if it is *g* we start all over the detection process (or simply start it), and finally for the *ESC* key quit the application: + + .. code-block:: cpp + + char key = waitKey(s.inputCapture.isOpened() ? 50 : s.delay); + if( key == ESC_KEY ) + break; + + if( key == 'u' && mode == CALIBRATED ) + s.showUndistorsed = !s.showUndistorsed; + + if( s.inputCapture.isOpened() && key == 'g' ) + { + mode = CAPTURING; + imagePoints.clear(); + } + +#. **Show the distortion removal for the images too**. When you work with an image list it is not possible to remove the distortion inside the loop. Therefore, you must append this after the loop. Taking advantage of this now I'll expand the :imgproc_geometric:`undistort ` function, which is in fact first a call of the :imgproc_geometric:`initUndistortRectifyMap ` to find out the transformation matrices and then doing the transformation with the :imgproc_geometric:`remap ` function. Because, after a successful calibration the map calculation needs to be done only once, by using this expanded form you may speed up your application: + + .. code-block:: cpp + + if( s.inputType == Settings::IMAGE_LIST && s.showUndistorsed ) + { + Mat view, rview, map1, map2; + initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(), + getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0), + imageSize, CV_16SC2, map1, map2); + + for(int i = 0; i < (int)s.imageList.size(); i++ ) + { + view = imread(s.imageList[i], 1); + if(view.empty()) + continue; + remap(view, rview, map1, map2, INTER_LINEAR); + imshow("Image View", rview); + char c = waitKey(); + if( c == ESC_KEY || c == 'q' || c == 'Q' ) + break; + } + } + +The calibration and save +======================== + +Because the calibration needs to be only once per camera it makes sense to save them after a successful calibration. This way later on you can just load these values into your program. Due to this we first make the calibration, and if it succeeds we save the result into an OpenCV style XML or YAML file, depending on the extension you give in the configuration file. + +Therefore in the first function we just split up these two processes. Because we want to save many of the calibration variables we'll create these variables here and pass on both of them to the calibration and saving function. Again, I'll not show the saving part as that has little in common with the calibration. Explore the source file in order to find out how and what: + +.. code-block:: cpp + + + bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,vector > imagePoints ) + { + vector rvecs, tvecs; + vector reprojErrs; + double totalAvgErr = 0; + + bool ok = runCalibration(s,imageSize, cameraMatrix, distCoeffs, imagePoints, rvecs, tvecs, + reprojErrs, totalAvgErr); + cout << (ok ? "Calibration succeeded" : "Calibration failed") + << ". avg re projection error = " << totalAvgErr ; + + if( ok ) // save only if the calibration was done with success + saveCameraParams( s, imageSize, cameraMatrix, distCoeffs, rvecs ,tvecs, reprojErrs, + imagePoints, totalAvgErr); + return ok; + } + +We do the calibration with the help of the :calib3d:`calibrateCamera ` function. This has the following parameters: + +.. container:: enumeratevisibleitemswithsquare + + + The object points. This is a vector of *Point3f* vector that for each input image describes how should the pattern look. If we have a planar pattern (like a chessboard) then we can simply set all Z coordinates to zero. This is a collection of the points where these important points are present. Because, we use a single pattern for all the input images we can calculate this just once and multiply it for all the other input views. We calculate the corner points with the *calcBoardCornerPositions* function as: + + .. code-block:: cpp + + void calcBoardCornerPositions(Size boardSize, float squareSize, vector& corners, + Settings::Pattern patternType /*= Settings::CHESSBOARD*/) + { + corners.clear(); + + switch(patternType) + { + case Settings::CHESSBOARD: + case Settings::CIRCLES_GRID: + for( int i = 0; i < boardSize.height; ++i ) + for( int j = 0; j < boardSize.width; ++j ) + corners.push_back(Point3f(float( j*squareSize ), float( i*squareSize ), 0)); + break; + + case Settings::ASYMMETRIC_CIRCLES_GRID: + for( int i = 0; i < boardSize.height; i++ ) + for( int j = 0; j < boardSize.width; j++ ) + corners.push_back(Point3f(float((2*j + i % 2)*squareSize), float(i*squareSize), 0)); + break; + } + } + + And then multiply it as: + + .. code-block:: cpp + + vector > objectPoints(1); + calcBoardCornerPositions(s.boardSize, s.squareSize, objectPoints[0], s.calibrationPattern); + objectPoints.resize(imagePoints.size(),objectPoints[0]); + + + The image points. This is a vector of *Point2f* vector that for each input image contains where the important points (corners for chessboard, and center of circles for the circle patterns) were found. We already collected this from what the :calib3d:`findChessboardCorners ` or the :calib3d:`findCirclesGrid ` function returned. We just need to pass it on. + + + The size of the image acquired from the camera, video file or the images. + + + The camera matrix. If we used the fix aspect ratio option we need to set the :math:`f_x` to zero: + + .. code-block:: cpp + + cameraMatrix = Mat::eye(3, 3, CV_64F); + if( s.flag & CV_CALIB_FIX_ASPECT_RATIO ) + cameraMatrix.at(0,0) = 1.0; + + + The distortion coefficient matrix. Initialize with zero. + + .. code-block:: cpp + + distCoeffs = Mat::zeros(8, 1, CV_64F); + + + The function will calculate for all the views the rotation and translation vector that transform the object points (given in the model coordinate space) to the image points (given in the world coordinate space). The 7th and 8th parameters are an output vector of matrices containing in the ith position the rotation and translation vector for the ith object point to the ith image point. + + + The final argument is a flag. You need to specify here options like fix the aspect ratio for the focal length, assume zero tangential distortion or to fix the principal point. + + .. code-block:: cpp + + double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, + distCoeffs, rvecs, tvecs, s.flag|CV_CALIB_FIX_K4|CV_CALIB_FIX_K5); + + + The function returns the average re-projection error. This number gives a good estimation of just how exact is the found parameters. This should be as close to zero as possible. Given the intrinsic, distortion, rotation and translation matrices we may calculate the error for one view by using the :calib3d:`projectPoints ` to first transform the object point to image point. Then we calculate the absolute norm between what we got with our transformation and the corner/circle finding algorithm. To find the average error we calculate the arithmetical mean of the errors calculate for all the calibration images. + + .. code-block:: cpp + + double computeReprojectionErrors( const vector >& objectPoints, + const vector >& imagePoints, + const vector& rvecs, const vector& tvecs, + const Mat& cameraMatrix , const Mat& distCoeffs, + vector& perViewErrors) + { + vector imagePoints2; + int i, totalPoints = 0; + double totalErr = 0, err; + perViewErrors.resize(objectPoints.size()); + + for( i = 0; i < (int)objectPoints.size(); ++i ) + { + projectPoints( Mat(objectPoints[i]), rvecs[i], tvecs[i], cameraMatrix, // project + distCoeffs, imagePoints2); + err = norm(Mat(imagePoints[i]), Mat(imagePoints2), CV_L2); // difference + + int n = (int)objectPoints[i].size(); + perViewErrors[i] = (float) std::sqrt(err*err/n); // save for this view + totalErr += err*err; // sum it up + totalPoints += n; + } + + return std::sqrt(totalErr/totalPoints); // calculate the arithmetical mean + } + +Results +======= + +Let there be :download:`this input chessboard pattern <../../../pattern.png>` that has a size of 9 X 6. I've used an AXIS IP camera to create a couple of snapshots of the board and saved it into a VID5 directory. I've put this inside the :file:`images/CameraCalibraation` folder of my working directory and created the following :file:`VID5.XML` file that describes which images to use: + +.. code-block:: xml + + + + + images/CameraCalibraation/VID5/xx1.jpg + images/CameraCalibraation/VID5/xx2.jpg + images/CameraCalibraation/VID5/xx3.jpg + images/CameraCalibraation/VID5/xx4.jpg + images/CameraCalibraation/VID5/xx5.jpg + images/CameraCalibraation/VID5/xx6.jpg + images/CameraCalibraation/VID5/xx7.jpg + images/CameraCalibraation/VID5/xx8.jpg + + + +Then specified the :file:`images/CameraCalibraation/VID5/VID5.XML` as input in the configuration file. Here's a chessboard pattern found during the runtime of the application: + +.. image:: images/fileListImage.jpg + :alt: A found chessboard + :align: center + +After applying the distortion removal we get: + +.. image:: images/fileListImageUnDist.jpg + :alt: Distortion removal for File List + :align: center + +The same works for :download:`this asymmetrical circle pattern <../../../acircles_pattern.png>` by setting the input width to 4 and height to 11. This time I've used a live camera feed by specifying its ID ("1") for the input. Here's, how a detected pattern should look: + +.. image:: images/asymetricalPattern.jpg + :alt: Asymmetrical circle detection + :align: center + +In both cases in the specified output XML/YAML file you'll find the camera and distortion coefficients matrices: + +.. code-block:: cpp + + + 3 + 3 +
d
+ + 6.5746697944293521e+002 0. 3.1950000000000000e+002 0. + 6.5746697944293521e+002 2.3950000000000000e+002 0. 0. 1.
+ + 5 + 1 +
d
+ + -4.1802327176423804e-001 5.0715244063187526e-001 0. 0. + -5.7843597214487474e-001
+ +Add these values as constants to your program, call the :imgproc_geometric:`initUndistortRectifyMap ` and the :imgproc_geometric:`remap ` function to remove distortion and enjoy distortion free inputs with cheap and low quality cameras. + +You may observe a runtime instance of this on the `YouTube here `_. + +.. raw:: html + +
+ +
diff --git a/doc/tutorials/calib3d/camera_calibration/images/asymetricalPattern.jpg b/doc/tutorials/calib3d/camera_calibration/images/asymetricalPattern.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6b9ea838b077501296dec65cf6534a30a04fb048 GIT binary patch literal 46120 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 XKkkR|HI=xv#RhvUo!Of2KCA!P2VSZR literal 0 HcmV?d00001 diff --git a/doc/tutorials/calib3d/camera_calibration/images/fileListImage.jpg b/doc/tutorials/calib3d/camera_calibration/images/fileListImage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5c86635254998bed5f23d53a1510486b87966d80 GIT binary patch literal 34363 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 E*-ckHjsO4v literal 0 HcmV?d00001 diff --git a/doc/tutorials/calib3d/camera_calibration/images/fileListImageUnDist.jpg b/doc/tutorials/calib3d/camera_calibration/images/fileListImageUnDist.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e70f910d719cfcca20da304b5cb801a9b1fbb6ab GIT binary patch literal 29861 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 S`Q1%VmoK`Nqf}!3TmL`HzXy5% literal 0 HcmV?d00001 diff --git a/doc/tutorials/calib3d/table_of_content_calib3d/images/camera_calibration.png b/doc/tutorials/calib3d/table_of_content_calib3d/images/camera_calibration.png new file mode 100644 index 0000000000000000000000000000000000000000..b010459c9d6b6f4b89fab5d44a27bb398a3fac41 GIT binary patch literal 8159 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 OpenCV 2.0 + + *Author:* |Author_BernatG| + + Camera calibration by using either the chessboard, circle or the asymmetrical circle pattern. Get the images either from a camera attached, a video file or from an image collection. + + ===================== ============================================== + + .. |CameraCalibration| image:: images/camera_calibration.png + :height: 90pt + :width: 90pt + .. raw:: latex \pagebreak @@ -34,3 +53,4 @@ Although we got most of our images in a 2D format they do come from a 3D world. :hidden: ../camera_calibration_square_chess/camera_calibration_square_chess + ../camera_calibration/camera_calibration diff --git a/doc/tutorials/introduction/linux_install/linux_install.rst b/doc/tutorials/introduction/linux_install/linux_install.rst index f41777c405..1f39f02084 100644 --- a/doc/tutorials/introduction/linux_install/linux_install.rst +++ b/doc/tutorials/introduction/linux_install/linux_install.rst @@ -28,7 +28,7 @@ All the libraries above can be installed via Terminal or by using Synaptic Manag Getting OpenCV source code ============================ -You can use the latest stable OpenCV version available in *sourceforge* or you can grab the latest snapshot from the `SVN repository < http://code.ros.org/svn/opencv/>`_. +You can use the latest stable OpenCV version available in *sourceforge* or you can grab the latest snapshot from the `SVN repository `_. Getting the latest stable OpenCV version ------------------------------------------ diff --git a/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.rst b/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.rst index 7dd36fb56a..fe426796fe 100644 --- a/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.rst +++ b/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.rst @@ -22,7 +22,7 @@ Theory Code ==== -This tutorial code's is shown lines below. You can also download it from `here `_ . The second version (using LBP for face detection) can be found `here `_ +This tutorial code's is shown lines below. You can also download it from `here `_ . The second version (using LBP for face detection) can be `found here `_ .. code-block:: cpp @@ -63,13 +63,13 @@ This tutorial code's is shown lines below. You can also download it from `here < { while( true ) { - frame = cvQueryFrame( capture ); + frame = cvQueryFrame( capture ); - //-- 3. Apply the classifier to the frame - if( !frame.empty() ) - { detectAndDisplay( frame ); } - else - { printf(" --(!) No captured frame -- Break!"); break; } + //-- 3. Apply the classifier to the frame + if( !frame.empty() ) + { detectAndDisplay( frame ); } + else + { printf(" --(!) No captured frame -- Break!"); break; } int c = waitKey(10); if( (char)c == 'c' ) { break; } diff --git a/samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml b/samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml new file mode 100644 index 0000000000..04979412c0 --- /dev/null +++ b/samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml @@ -0,0 +1,13 @@ + + + +images/CameraCalibraation/VID5/xx1.jpg +images/CameraCalibraation/VID5/xx2.jpg +images/CameraCalibraation/VID5/xx3.jpg +images/CameraCalibraation/VID5/xx4.jpg +images/CameraCalibraation/VID5/xx5.jpg +images/CameraCalibraation/VID5/xx6.jpg +images/CameraCalibraation/VID5/xx7.jpg +images/CameraCalibraation/VID5/xx8.jpg + + \ No newline at end of file diff --git a/samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp b/samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp new file mode 100644 index 0000000000..c773c04fa3 --- /dev/null +++ b/samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp @@ -0,0 +1,551 @@ +#include +#include +#include + +#include +#include +#include +#include + +using namespace cv; +using namespace std; + +void help() +{ + cout << "This is a camera calibration sample." << endl + << "Usage: calibration configurationFile" << endl + << "Near the sample file you'll find the configuration file, which has detailed help of " + "how to edit it. It may be any OpenCV supported file format XML/YAML." << endl; +} +class Settings +{ +public: + Settings() : goodInput(false) {} + enum Pattern { NOT_EXISTING, CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID }; + enum InputType {INVALID, CAMERA, VIDEO_FILE, IMAGE_LIST}; + + void write(FileStorage& fs) const //Write serialization for this class + { + fs << "{" << "BoardSize_Width" << boardSize.width + << "BoardSize_Height" << boardSize.height + << "Square_Size" << squareSize + << "Calibrate_Pattern" << patternToUse + << "Calibrate_NrOfFrameToUse" << nrFrames + << "Calibrate_FixAspectRatio" << aspectRatio + << "Calibrate_AssumeZeroTangentialDistortion" << calibZeroTangentDist + << "Calibrate_FixPrincipalPointAtTheCenter" << calibFixPrincipalPoint + + << "Write_DetectedFeaturePoints" << bwritePoints + << "Write_extrinsicParameters" << bwriteExtrinsics + << "Write_outputFileName" << outputFileName + + << "Show_UndistortedImage" << showUndistorsed + + << "Input_FlipAroundHorizontalAxis" << flipVertical + << "Input_Delay" << delay + << "Input" << input + << "}"; + } + void read(const FileNode& node) //Read serialization for this class + { + node["BoardSize_Width" ] >> boardSize.width; + node["BoardSize_Height"] >> boardSize.height; + node["Calibrate_Pattern"] >> patternToUse; + node["Square_Size"] >> squareSize; + node["Calibrate_NrOfFrameToUse"] >> nrFrames; + node["Calibrate_FixAspectRatio"] >> aspectRatio; + node["Write_DetectedFeaturePoints"] >> bwritePoints; + node["Write_extrinsicParameters"] >> bwriteExtrinsics; + node["Write_outputFileName"] >> outputFileName; + node["Calibrate_AssumeZeroTangentialDistortion"] >> calibZeroTangentDist; + node["Calibrate_FixPrincipalPointAtTheCenter"] >> calibFixPrincipalPoint; + node["Input_FlipAroundHorizontalAxis"] >> flipVertical; + node["Show_UndistortedImage"] >> showUndistorsed; + node["Input"] >> input; + node["Input_Delay"] >> delay; + interprate(); + } + void interprate() + { + goodInput = true; + if (boardSize.width <= 0 || boardSize.height <= 0) + { + cerr << "Invalid Board size: " << boardSize.width << " " << boardSize.height << endl; + goodInput = false; + } + if (squareSize <= 10e-6) + { + cerr << "Invalid square size " << squareSize << endl; + goodInput = false; + } + if (nrFrames <= 0) + { + cerr << "Invalid number of frames " << nrFrames << endl; + goodInput = false; + } + + if (input.empty()) // Check for valid input + inputType = INVALID; + else + { + if (input[0] >= '0' && input[0] <= '9') + { + stringstream ss(input); + ss >> cameraID; + inputType = CAMERA; + } + else + { + if (readStringList(input, imageList)) + { + inputType = IMAGE_LIST; + nrFrames = (nrFrames < imageList.size()) ? nrFrames : imageList.size(); + } + else + inputType = VIDEO_FILE; + } + if (inputType == CAMERA) + inputCapture.open(cameraID); + if (inputType == VIDEO_FILE) + inputCapture.open(input); + if (inputType != IMAGE_LIST && !inputCapture.isOpened()) + inputType = INVALID; + } + if (inputType == INVALID) + { + cerr << " Inexistent input: " << input; + goodInput = false; + } + + flag = 0; + if(calibFixPrincipalPoint) flag |= CV_CALIB_FIX_PRINCIPAL_POINT; + if(calibZeroTangentDist) flag |= CV_CALIB_ZERO_TANGENT_DIST; + if(aspectRatio) flag |= CV_CALIB_FIX_ASPECT_RATIO; + + + calibrationPattern = NOT_EXISTING; + if (!patternToUse.compare("CHESSBOARD")) calibrationPattern = CHESSBOARD; + if (!patternToUse.compare("CIRCLES_GRID")) calibrationPattern = CIRCLES_GRID; + if (!patternToUse.compare("ASYMMETRIC_CIRCLES_GRID")) calibrationPattern = ASYMMETRIC_CIRCLES_GRID; + if (calibrationPattern == NOT_EXISTING) + { + cerr << " Inexistent camera calibration mode: " << patternToUse << endl; + goodInput = false; + } + atImageList = 0; + + } + Mat nextImage() + { + Mat result; + if( inputCapture.isOpened() ) + { + Mat view0; + inputCapture >> view0; + view0.copyTo(result); + } + else if( atImageList < (int)imageList.size() ) + result = imread(imageList[atImageList++], CV_LOAD_IMAGE_COLOR); + + return result; + } + + static bool readStringList( const string& filename, vector& l ) + { + l.clear(); + FileStorage fs(filename, FileStorage::READ); + if( !fs.isOpened() ) + return false; + FileNode n = fs.getFirstTopLevelNode(); + if( n.type() != FileNode::SEQ ) + return false; + FileNodeIterator it = n.begin(), it_end = n.end(); + for( ; it != it_end; ++it ) + l.push_back((string)*it); + return true; + } +public: + Size boardSize; // The size of the board -> Number of items by width and height + Pattern calibrationPattern;// One of the Chessboard, circles, or asymmetric circle pattern + float squareSize; // The size of a square in your defined unit (point, millimeter,etc). + int nrFrames; // The number of frames to use from the input for calibration + float aspectRatio; // The aspect ratio + int delay; // In case of a video input + bool bwritePoints; // Write detected feature points + bool bwriteExtrinsics; // Write extrinsic parameters + bool calibZeroTangentDist; // Assume zero tangential distortion + bool calibFixPrincipalPoint;// Fix the principal point at the center + bool flipVertical; // Flip the captured images around the horizontal axis + string outputFileName; // The name of the file where to write + bool showUndistorsed; // Show undistorted images after calibration + string input; // The input -> + + + + int cameraID; + vector imageList; + int atImageList; + VideoCapture inputCapture; + InputType inputType; + bool goodInput; + int flag; + +private: + string patternToUse; + + +}; + +void write(FileStorage& fs, const std::string&, const Settings& x) +{ + x.write(fs); +} +void read(const FileNode& node, Settings& x, const Settings& default_value = Settings()) +{ + if(node.empty()) + x = default_value; + else + x.read(node); +} + +enum { DETECTION = 0, CAPTURING = 1, CALIBRATED = 2 }; + +bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs, + vector > imagePoints ); + +int main(int argc, char* argv[]) +{ + help(); + Settings s; + const string inputSettingsFile = argc > 1 ? argv[1] : "default.xml"; + FileStorage fs(inputSettingsFile, FileStorage::READ); // Read the settings + if (!fs.isOpened()) + { + cout << "Could not open the configuration file: \"" << inputSettingsFile << "\"" << endl; + return -1; + } + fs["Settings"] >> s; + fs.release(); // close Settings file + + if (!s.goodInput) + { + cout << "Invalid input detected. Application stopping. " << endl; + return -1; + } + + vector > imagePoints; + Mat cameraMatrix, distCoeffs; + Size imageSize; + int mode = s.inputType == Settings::IMAGE_LIST ? CAPTURING : DETECTION; + clock_t prevTimestamp = 0; + const Scalar RED(0,0,255), GREEN(0,255,0); + const char ESC_KEY = 27; + + for(int i = 0;;++i) + { + Mat view; + bool blinkOutput = false; + + view = s.nextImage(); + + //----- If no more image, or got enough, then stop calibration and show result ------------- + if( mode == CAPTURING && imagePoints.size() >= (unsigned)s.nrFrames ) + { + if( runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints)) + mode = CALIBRATED; + else + mode = DETECTION; + } + if(view.empty()) // If no more images then run calibration, save and stop loop. + { + if( imagePoints.size() > 0 ) + runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints); + break; + } + + + imageSize = view.size(); // Format input image. + if( s.flipVertical ) flip( view, view, 0 ); + + vector pointBuf; + + bool found; + switch( s.calibrationPattern ) // Find feature points on the input format + { + case Settings::CHESSBOARD: + found = findChessboardCorners( view, s.boardSize, pointBuf, + CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE); + break; + case Settings::CIRCLES_GRID: + found = findCirclesGrid( view, s.boardSize, pointBuf ); + break; + case Settings::ASYMMETRIC_CIRCLES_GRID: + found = findCirclesGrid( view, s.boardSize, pointBuf, CALIB_CB_ASYMMETRIC_GRID ); + break; + } + + if ( found) // If done with success, + { + // improve the found corners' coordinate accuracy for chessboard + if( s.calibrationPattern == Settings::CHESSBOARD) + { + Mat viewGray; + cvtColor(view, viewGray, CV_BGR2GRAY); + cornerSubPix( viewGray, pointBuf, Size(11,11), + Size(-1,-1), TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 )); + } + + if( mode == CAPTURING && // For camera only take new samples after delay time + (!s.inputCapture.isOpened() || clock() - prevTimestamp > s.delay*1e-3*CLOCKS_PER_SEC) ) + { + imagePoints.push_back(pointBuf); + prevTimestamp = clock(); + blinkOutput = s.inputCapture.isOpened(); + } + + // Draw the corners. + drawChessboardCorners( view, s.boardSize, Mat(pointBuf), found ); + } + + //----------------------------- Output Text ------------------------------------------------ + string msg = (mode == CAPTURING) ? "100/100" : + mode == CALIBRATED ? "Calibrated" : "Press 'g' to start"; + int baseLine = 0; + Size textSize = getTextSize(msg, 1, 1, 1, &baseLine); + Point textOrigin(view.cols - 2*textSize.width - 10, view.rows - 2*baseLine - 10); + + if( mode == CAPTURING ) + { + if(s.showUndistorsed) + msg = format( "%d/%d Undist", (int)imagePoints.size(), s.nrFrames ); + else + msg = format( "%d/%d", (int)imagePoints.size(), s.nrFrames ); + } + + putText( view, msg, textOrigin, 1, 1, mode == CALIBRATED ? GREEN : RED); + + if( blinkOutput ) + bitwise_not(view, view); + + //------------------------- Video capture output undistorted ------------------------------ + if( mode == CALIBRATED && s.showUndistorsed ) + { + Mat temp = view.clone(); + undistort(temp, view, cameraMatrix, distCoeffs); + } + + //------------------------------ Show image and check for input commands ------------------- + imshow("Image View", view); + char key = waitKey(s.inputCapture.isOpened() ? 50 : s.delay); + + if( key == ESC_KEY ) + break; + + if( key == 'u' && mode == CALIBRATED ) + s.showUndistorsed = !s.showUndistorsed; + + if( s.inputCapture.isOpened() && key == 'g' ) + { + mode = CAPTURING; + imagePoints.clear(); + } + } + + // -----------------------Show the undistorted image for the image list ------------------------ + if( s.inputType == Settings::IMAGE_LIST && s.showUndistorsed ) + { + Mat view, rview, map1, map2; + initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(), + getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0), + imageSize, CV_16SC2, map1, map2); + + for(int i = 0; i < (int)s.imageList.size(); i++ ) + { + view = imread(s.imageList[i], 1); + if(view.empty()) + continue; + remap(view, rview, map1, map2, INTER_LINEAR); + imshow("Image View", rview); + char c = waitKey(); + if( c == ESC_KEY || c == 'q' || c == 'Q' ) + break; + } + } + + + return 0; +} + +double computeReprojectionErrors( const vector >& objectPoints, + const vector >& imagePoints, + const vector& rvecs, const vector& tvecs, + const Mat& cameraMatrix , const Mat& distCoeffs, + vector& perViewErrors) +{ + vector imagePoints2; + int i, totalPoints = 0; + double totalErr = 0, err; + perViewErrors.resize(objectPoints.size()); + + for( i = 0; i < (int)objectPoints.size(); ++i ) + { + projectPoints( Mat(objectPoints[i]), rvecs[i], tvecs[i], cameraMatrix, + distCoeffs, imagePoints2); + err = norm(Mat(imagePoints[i]), Mat(imagePoints2), CV_L2); + + int n = (int)objectPoints[i].size(); + perViewErrors[i] = (float) std::sqrt(err*err/n); + totalErr += err*err; + totalPoints += n; + } + + return std::sqrt(totalErr/totalPoints); +} + +void calcBoardCornerPositions(Size boardSize, float squareSize, vector& corners, + Settings::Pattern patternType /*= Settings::CHESSBOARD*/) +{ + corners.clear(); + + switch(patternType) + { + case Settings::CHESSBOARD: + case Settings::CIRCLES_GRID: + for( int i = 0; i < boardSize.height; ++i ) + for( int j = 0; j < boardSize.width; ++j ) + corners.push_back(Point3f(float( j*squareSize ), float( i*squareSize ), 0)); + break; + + case Settings::ASYMMETRIC_CIRCLES_GRID: + for( int i = 0; i < boardSize.height; i++ ) + for( int j = 0; j < boardSize.width; j++ ) + corners.push_back(Point3f(float((2*j + i % 2)*squareSize), float(i*squareSize), 0)); + break; + } +} + +bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs, + vector > imagePoints, vector& rvecs, vector& tvecs, + vector& reprojErrs, double& totalAvgErr) +{ + + cameraMatrix = Mat::eye(3, 3, CV_64F); + if( s.flag & CV_CALIB_FIX_ASPECT_RATIO ) + cameraMatrix.at(0,0) = 1.0; + + distCoeffs = Mat::zeros(8, 1, CV_64F); + + vector > objectPoints(1); + calcBoardCornerPositions(s.boardSize, s.squareSize, objectPoints[0], s.calibrationPattern); + + objectPoints.resize(imagePoints.size(),objectPoints[0]); + + //Find intrinsic and extrinsic camera parameters + double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, + distCoeffs, rvecs, tvecs, s.flag|CV_CALIB_FIX_K4|CV_CALIB_FIX_K5); + + cout << "Re-projection error reported by calibrateCamera: "<< rms << endl; + + bool ok = checkRange(cameraMatrix) && checkRange(distCoeffs); + + totalAvgErr = computeReprojectionErrors(objectPoints, imagePoints, + rvecs, tvecs, cameraMatrix, distCoeffs, reprojErrs); + + return ok; +} + +// Print camera parameters to the output file +void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs, + const vector& rvecs, const vector& tvecs, + const vector& reprojErrs, const vector >& imagePoints, + double totalAvgErr ) +{ + FileStorage fs( s.outputFileName, FileStorage::WRITE ); + + time_t t; + time( &t ); + struct tm *t2 = localtime( &t ); + char buf[1024]; + strftime( buf, sizeof(buf)-1, "%c", t2 ); + + fs << "calibration_Time" << buf; + + if( !rvecs.empty() || !reprojErrs.empty() ) + fs << "nrOfFrames" << (int)std::max(rvecs.size(), reprojErrs.size()); + fs << "image_Width" << imageSize.width; + fs << "image_Height" << imageSize.height; + fs << "board_Width" << s.boardSize.width; + fs << "board_Height" << s.boardSize.height; + fs << "square_Size" << s.squareSize; + + if( s.flag & CV_CALIB_FIX_ASPECT_RATIO ) + fs << "FixAspectRatio" << s.aspectRatio; + + if( s.flag ) + { + sprintf( buf, "flags: %s%s%s%s", + s.flag & CV_CALIB_USE_INTRINSIC_GUESS ? " +use_intrinsic_guess" : "", + s.flag & CV_CALIB_FIX_ASPECT_RATIO ? " +fix_aspectRatio" : "", + s.flag & CV_CALIB_FIX_PRINCIPAL_POINT ? " +fix_principal_point" : "", + s.flag & CV_CALIB_ZERO_TANGENT_DIST ? " +zero_tangent_dist" : "" ); + cvWriteComment( *fs, buf, 0 ); + + } + + fs << "flagValue" << s.flag; + + fs << "Camera_Matrix" << cameraMatrix; + fs << "Distortion_Coefficients" << distCoeffs; + + fs << "Avg_Reprojection_Error" << totalAvgErr; + if( !reprojErrs.empty() ) + fs << "Per_View_Reprojection_Errors" << Mat(reprojErrs); + + if( !rvecs.empty() && !tvecs.empty() ) + { + CV_Assert(rvecs[0].type() == tvecs[0].type()); + Mat bigmat((int)rvecs.size(), 6, rvecs[0].type()); + for( int i = 0; i < (int)rvecs.size(); i++ ) + { + Mat r = bigmat(Range(i, i+1), Range(0,3)); + Mat t = bigmat(Range(i, i+1), Range(3,6)); + + CV_Assert(rvecs[i].rows == 3 && rvecs[i].cols == 1); + CV_Assert(tvecs[i].rows == 3 && tvecs[i].cols == 1); + //*.t() is MatExpr (not Mat) so we can use assignment operator + r = rvecs[i].t(); + t = tvecs[i].t(); + } + cvWriteComment( *fs, "a set of 6-tuples (rotation vector + translation vector) for each view", 0 ); + fs << "Extrinsic_Parameters" << bigmat; + } + + if( !imagePoints.empty() ) + { + Mat imagePtMat((int)imagePoints.size(), imagePoints[0].size(), CV_32FC2); + for( int i = 0; i < (int)imagePoints.size(); i++ ) + { + Mat r = imagePtMat.row(i).reshape(2, imagePtMat.cols); + Mat imgpti(imagePoints[i]); + imgpti.copyTo(r); + } + fs << "Image_points" << imagePtMat; + } +} + +bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,vector > imagePoints ) +{ + vector rvecs, tvecs; + vector reprojErrs; + double totalAvgErr = 0; + + bool ok = runCalibration(s,imageSize, cameraMatrix, distCoeffs, imagePoints, rvecs, tvecs, + reprojErrs, totalAvgErr); + cout << (ok ? "Calibration succeeded" : "Calibration failed") + << ". avg re projection error = " << totalAvgErr ; + + if( ok ) + saveCameraParams( s, imageSize, cameraMatrix, distCoeffs, rvecs ,tvecs, reprojErrs, + imagePoints, totalAvgErr); + return ok; +} diff --git a/samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml b/samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml new file mode 100644 index 0000000000..c741653209 --- /dev/null +++ b/samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml @@ -0,0 +1,46 @@ + + + + + 9 + 6 + + + 50 + + + "CHESSBOARD" + + + "images/CameraCalibraation/VID5/VID5.xml" + + 0 + + + 100 + + + 25 + + 1 + + 1 + + 1 + + + "out_camera_data.xml" + + 1 + + 1 + + 1 + + + \ No newline at end of file diff --git a/samples/cpp/tutorial_code/calib3d/camera_calibration/out_camera_data.yml b/samples/cpp/tutorial_code/calib3d/camera_calibration/out_camera_data.yml new file mode 100644 index 0000000000..f9e9839218 --- /dev/null +++ b/samples/cpp/tutorial_code/calib3d/camera_calibration/out_camera_data.yml @@ -0,0 +1,352 @@ +%YAML:1.0 +calibration_Time: "08/19/11 20:44:38" +nrOfFrames: 8 +image_Width: 640 +image_Height: 480 +board_Width: 9 +board_Height: 6 +square_Size: 50. +FixAspectRatio: 1. +# flags: +fix_aspectRatio +fix_principal_point +zero_tangent_dist +flagValue: 14 +Camera_Matrix: !!opencv-matrix + rows: 3 + cols: 3 + dt: d + data: [ 6.5746697810243404e+002, 0., 3.1950000000000000e+002, 0., + 6.5746697810243404e+002, 2.3950000000000000e+002, 0., 0., 1. ] +Distortion_Coefficients: !!opencv-matrix + rows: 5 + cols: 1 + dt: d + data: [ -4.1802327018241026e-001, 5.0715243805833121e-001, 0., 0., + -5.7843596847939704e-001 ] +Avg_Reprojection_Error: 3.8441346462381665e-001 +Per_View_Reprojection_Errors: !!opencv-matrix + rows: 8 + cols: 1 + dt: f + data: [ 5.04357755e-001, 4.85754758e-001, 3.99563968e-001, + 4.13829178e-001, 3.53570908e-001, 3.21116358e-001, + 2.74473161e-001, 2.39761785e-001 ] +# a set of 6-tuples (rotation vector + translation vector) for each view +Extrinsic_Parameters: !!opencv-matrix + rows: 8 + cols: 6 + dt: d + data: [ -7.8704123655486097e-002, -1.5922384772614945e-001, + 3.1166227207451498e+000, 2.4224388101960471e+002, + 1.1795590397660339e+002, 6.2576484126093249e+002, + -1.4117480285164308e-001, -1.7917415443804836e-002, + 3.1333182268743949e+000, 2.5943034781849354e+002, + 1.4039780562976958e+002, 6.3848706527260981e+002, + 7.2230525186138789e-002, -7.5445981266787754e-002, + 1.5712860749221762e+000, 1.7426560451795339e+002, + -1.9309240362258871e+002, 7.0891416556762647e+002, + 2.0367310600105853e-002, 6.8565520026996951e-002, + -5.4313033031644169e-004, -2.0146314940404827e+002, + -1.3305643514116997e+002, 7.4933554744027231e+002, + -3.4468530027734055e-002, 2.1921265175331925e-002, + -1.5731053528054522e+000, -1.1155718744299284e+002, + 2.0307615364261443e+002, 8.4915903914333899e+002, + 3.7425562109513817e-002, 7.4883169379022230e-002, + -3.6031632305130512e-002, -2.0094505419395196e+002, + -1.1627359108310560e+002, 9.2021583518760133e+002, + 6.8105689976949157e-002, 6.4426739692440949e-002, + -7.0967130057087435e-002, -1.9233852871740035e+002, + -1.0334652096641923e+002, 1.0755293563503658e+003, + -5.8017546499862287e-002, -1.6909812666033443e-003, + -1.5876137659782963e+000, -1.0242234847115104e+002, + 2.2583088401423066e+002, 1.1125972190244058e+003 ] +Image_points: !!opencv-matrix + rows: 8 + cols: 54 + dt: "2f" + data: [ 5.58494690e+002, 3.55650085e+002, 5.13314697e+002, + 3.59107666e+002, 4.65728333e+002, 3.62133911e+002, + 4.15701111e+002, 3.65026459e+002, 3.64399353e+002, + 3.67339203e+002, 3.12101196e+002, 3.69211914e+002, + 2.59208405e+002, 3.70413513e+002, 2.07456192e+002, + 3.71175995e+002, 1.56619507e+002, 3.72176544e+002, + 5.60868713e+002, 3.08104828e+002, 5.15191772e+002, + 3.10485626e+002, 4.67032959e+002, 3.12660004e+002, + 4.16112152e+002, 3.14887177e+002, 3.64010712e+002, + 3.16825775e+002, 3.10712372e+002, 3.18640808e+002, + 2.56853943e+002, 3.20017365e+002, 2.04168182e+002, + 3.20908417e+002, 1.52469528e+002, 3.22105377e+002, + 5.62328369e+002, 2.58646881e+002, 5.16396301e+002, + 2.59919281e+002, 4.67907654e+002, 2.61257874e+002, + 4.16463440e+002, 2.62675537e+002, 3.63546570e+002, + 2.64064117e+002, 3.09528137e+002, 2.65489990e+002, + 2.54765533e+002, 2.66862030e+002, 2.01299225e+002, + 2.67997345e+002, 1.48913437e+002, 2.69627167e+002, + 5.63098022e+002, 2.08423523e+002, 5.16782654e+002, + 2.08424667e+002, 4.68059296e+002, 2.08661697e+002, + 4.16216431e+002, 2.09268982e+002, 3.62888763e+002, + 2.10013397e+002, 3.08458557e+002, 2.11074738e+002, + 2.53267990e+002, 2.12496582e+002, 1.99121384e+002, + 2.14005814e+002, 1.46551376e+002, 2.15851318e+002, + 5.62997437e+002, 1.57966492e+002, 5.16406494e+002, + 1.56580688e+002, 4.67334900e+002, 1.55756500e+002, + 4.15378235e+002, 1.55492874e+002, 3.62096710e+002, + 1.55498734e+002, 3.07522827e+002, 1.56133240e+002, + 2.52235214e+002, 1.57516571e+002, 1.97876328e+002, + 1.59318787e+002, 1.45078247e+002, 1.61638428e+002, + 5.62097168e+002, 1.07469536e+002, 5.15766846e+002, + 1.04902527e+002, 4.66562866e+002, 1.03045807e+002, + 4.14651459e+002, 1.01924713e+002, 3.61240662e+002, + 1.01357826e+002, 3.06746613e+002, 1.01582802e+002, + 2.51568024e+002, 1.02920105e+002, 1.97343307e+002, + 1.04941299e+002, 1.44756821e+002, 1.07737488e+002, + 5.68062500e+002, 3.73591125e+002, 5.25272644e+002, + 3.77019318e+002, 4.79870941e+002, 3.80086578e+002, + 4.31823730e+002, 3.83036652e+002, 3.81995758e+002, + 3.85271759e+002, 3.30728729e+002, 3.86998779e+002, + 2.78071167e+002, 3.88151031e+002, 2.26231567e+002, + 3.88669586e+002, 1.74855331e+002, 3.89197998e+002, + 5.69792542e+002, 3.27097382e+002, 5.26866028e+002, + 3.29362366e+002, 4.81278229e+002, 3.31532928e+002, + 4.32783203e+002, 3.33552185e+002, 3.82408234e+002, + 3.35186554e+002, 3.30427399e+002, 3.36404053e+002, + 2.77138519e+002, 3.37450958e+002, 2.24525131e+002, + 3.37957092e+002, 1.72285507e+002, 3.38503540e+002, + 5.70942749e+002, 2.79243713e+002, 5.27789307e+002, + 2.80073486e+002, 4.82146576e+002, 2.81226410e+002, + 4.33247375e+002, 2.82237427e+002, 3.82503662e+002, + 2.83062286e+002, 3.30138885e+002, 2.83794434e+002, + 2.76433228e+002, 2.84549286e+002, 2.23158783e+002, + 2.84981049e+002, 1.70520218e+002, 2.85720886e+002, + 5.71001953e+002, 2.30928329e+002, 5.27846863e+002, + 2.30519928e+002, 4.82114563e+002, 2.30268906e+002, + 4.33114563e+002, 2.30243515e+002, 3.82384857e+002, + 2.30311340e+002, 3.29870392e+002, 2.30454620e+002, + 2.76012634e+002, 2.30882156e+002, 2.22529434e+002, + 2.31355362e+002, 1.69742065e+002, 2.32063004e+002, + 5.70199036e+002, 1.82609772e+002, 5.27030884e+002, + 1.80973267e+002, 4.81193573e+002, 1.79573792e+002, + 4.32409821e+002, 1.78475616e+002, 3.81855530e+002, + 1.77680283e+002, 3.29641937e+002, 1.77092087e+002, + 2.75895782e+002, 1.77155502e+002, 2.22438889e+002, + 1.77605667e+002, 1.69884583e+002, 1.78365585e+002, + 5.69026245e+002, 1.34654831e+002, 5.26171570e+002, + 1.31798691e+002, 4.80653503e+002, 1.29171509e+002, + 4.31869904e+002, 1.27280067e+002, 3.81419739e+002, + 1.25591202e+002, 3.29466644e+002, 1.24407089e+002, + 2.76225342e+002, 1.24174736e+002, 2.23024109e+002, + 1.24463333e+002, 1.70838898e+002, 1.25398903e+002, + 4.73812897e+002, 6.94673386e+001, 4.74245453e+002, + 1.12387466e+002, 4.74243347e+002, 1.56034164e+002, + 4.73834778e+002, 2.00523651e+002, 4.72891602e+002, + 2.44457306e+002, 4.71412811e+002, 2.87981171e+002, + 4.69708252e+002, 3.30783173e+002, 4.67558228e+002, + 3.71818420e+002, 4.65495667e+002, 4.11996979e+002, + 4.31027649e+002, 6.75546722e+001, 4.31269440e+002, + 1.10960022e+002, 4.31185486e+002, 1.55113556e+002, + 4.30830139e+002, 2.00061066e+002, 4.30168427e+002, + 2.44456863e+002, 4.29107544e+002, 2.88479645e+002, + 4.27829071e+002, 3.31813507e+002, 4.26131653e+002, + 3.73071228e+002, 4.24718811e+002, 4.13476563e+002, + 3.86868805e+002, 6.61982269e+001, 3.86895416e+002, + 1.09904411e+002, 3.86690216e+002, 1.54396423e+002, + 3.86368591e+002, 1.99800369e+002, 3.85792206e+002, + 2.44538574e+002, 3.85117279e+002, 2.88826447e+002, + 3.84405273e+002, 3.32408020e+002, 3.83303772e+002, + 3.74074097e+002, 3.82477448e+002, 4.14638977e+002, + 3.41941437e+002, 6.54462357e+001, 3.41628204e+002, + 1.09383698e+002, 3.41402344e+002, 1.54105545e+002, + 3.41168854e+002, 1.99655045e+002, 3.40816681e+002, + 2.44469910e+002, 3.40516937e+002, 2.88975800e+002, + 3.40365662e+002, 3.32670990e+002, 3.39935211e+002, + 3.74465759e+002, 3.39847626e+002, 4.14742279e+002, + 2.96694000e+002, 6.56859589e+001, 2.96075226e+002, + 1.09505333e+002, 2.95704895e+002, 1.54202652e+002, + 2.95653107e+002, 1.99734131e+002, 2.95589661e+002, + 2.44549530e+002, 2.95629547e+002, 2.88889496e+002, + 2.96138733e+002, 3.32610931e+002, 2.96520905e+002, + 3.74608551e+002, 2.96987091e+002, 4.14774902e+002, + 2.51414978e+002, 6.65755463e+001, 2.50681854e+002, + 1.10189331e+002, 2.50183380e+002, 1.54658005e+002, + 2.50331161e+002, 2.00073761e+002, 2.50590790e+002, + 2.44719513e+002, 2.51083817e+002, 2.88868286e+002, + 2.52134262e+002, 3.32266937e+002, 2.53097809e+002, + 3.74022491e+002, 2.54404007e+002, 4.14018066e+002, + 1.49524078e+002, 1.27699501e+002, 1.89511658e+002, + 1.25816605e+002, 2.31050888e+002, 1.24260918e+002, + 2.74076721e+002, 1.23023209e+002, 3.17643005e+002, + 1.22288109e+002, 3.61785889e+002, 1.22105164e+002, + 4.06142670e+002, 1.22401566e+002, 4.49623962e+002, + 1.23246025e+002, 4.92677216e+002, 1.24087708e+002, + 1.48706085e+002, 1.69077423e+002, 1.88827805e+002, + 1.67750443e+002, 2.30439865e+002, 1.66769333e+002, + 2.73830933e+002, 1.65871170e+002, 3.17596741e+002, + 1.65410919e+002, 3.61983459e+002, 1.65327866e+002, + 4.06748322e+002, 1.65463974e+002, 4.50450226e+002, + 1.66126526e+002, 4.93614655e+002, 1.66970413e+002, + 1.48312607e+002, 2.11499451e+002, 1.88574097e+002, + 2.10860214e+002, 2.30130676e+002, 2.10261612e+002, + 2.73557709e+002, 2.09837143e+002, 3.17542572e+002, + 2.09633057e+002, 3.62091248e+002, 2.09732620e+002, + 4.06934570e+002, 2.09926758e+002, 4.50914612e+002, + 2.10320221e+002, 4.94044495e+002, 2.10900925e+002, + 1.48613831e+002, 2.53997177e+002, 1.88797791e+002, + 2.53912842e+002, 2.30240204e+002, 2.53975067e+002, + 2.73746704e+002, 2.54010208e+002, 3.17718262e+002, + 2.54106003e+002, 3.62188965e+002, 2.54205475e+002, + 4.06908783e+002, 2.54317505e+002, 4.50824951e+002, + 2.54539490e+002, 4.93825714e+002, 2.54753876e+002, + 1.49541687e+002, 2.96404175e+002, 1.89357727e+002, + 2.97117523e+002, 2.30807007e+002, 2.97805603e+002, + 2.74325470e+002, 2.97966522e+002, 3.18042206e+002, + 2.98304535e+002, 3.62105774e+002, 2.98552643e+002, + 4.06672272e+002, 2.98572418e+002, 4.50363068e+002, + 2.98569550e+002, 4.93109894e+002, 2.98516205e+002, + 1.50883698e+002, 3.38493195e+002, 1.90633621e+002, + 3.39862610e+002, 2.31920990e+002, 3.40869415e+002, + 2.74971252e+002, 3.41453766e+002, 3.18235229e+002, + 3.41952637e+002, 3.62063477e+002, 3.42314026e+002, + 4.06098938e+002, 3.42221802e+002, 4.49477386e+002, + 3.42063812e+002, 4.91864716e+002, 3.41727600e+002, + 2.36129852e+002, 3.92798004e+002, 2.34999939e+002, + 3.56118683e+002, 2.34376099e+002, 3.18607025e+002, + 2.33822159e+002, 2.80400696e+002, 2.33565445e+002, + 2.42213104e+002, 2.33583069e+002, 2.03937286e+002, + 2.34028824e+002, 1.65756607e+002, 2.34613373e+002, + 1.28586639e+002, 2.35190308e+002, 9.18279037e+001, + 2.73031616e+002, 3.93267242e+002, 2.72295166e+002, + 3.56342743e+002, 2.71799347e+002, 3.18847412e+002, + 2.71418854e+002, 2.80287872e+002, 2.71161469e+002, + 2.41881134e+002, 2.71248962e+002, 2.03348145e+002, + 2.71379303e+002, 1.64895874e+002, 2.71946045e+002, + 1.27450935e+002, 2.72322418e+002, 9.06900787e+001, + 3.10670715e+002, 3.93568848e+002, 3.10389160e+002, + 3.56545959e+002, 3.10084625e+002, 3.18814514e+002, + 3.09801544e+002, 2.80242737e+002, 3.09678711e+002, + 2.41574814e+002, 3.09779663e+002, 2.02989838e+002, + 3.09842712e+002, 1.64338043e+002, 3.10076782e+002, + 1.26870911e+002, 3.10243286e+002, 8.98413315e+001, + 3.48618134e+002, 3.93563202e+002, 3.48617065e+002, + 3.56472382e+002, 3.48608795e+002, 3.18855621e+002, + 3.48544556e+002, 2.80011017e+002, 3.48556396e+002, + 2.41388168e+002, 3.48585388e+002, 2.02692429e+002, + 3.48435089e+002, 1.64099731e+002, 3.48442902e+002, + 1.26549957e+002, 3.48338043e+002, 8.98002014e+001, + 3.86625610e+002, 3.93188599e+002, 3.87047729e+002, + 3.56377594e+002, 3.87306274e+002, 3.18714752e+002, + 3.87337799e+002, 2.79868896e+002, 3.87402740e+002, + 2.41228760e+002, 3.87295166e+002, 2.02695313e+002, + 3.87030273e+002, 1.64203415e+002, 3.86741211e+002, + 1.26606262e+002, 3.86337311e+002, 8.99655075e+001, + 4.24534088e+002, 3.92702545e+002, 4.25310822e+002, + 3.55900452e+002, 4.25869019e+002, 3.18160614e+002, + 4.25909790e+002, 2.79615753e+002, 4.25977295e+002, + 2.41165100e+002, 4.25826477e+002, 2.02876389e+002, + 4.25331665e+002, 1.64527618e+002, 4.24775787e+002, + 1.27097328e+002, 4.23985138e+002, 9.08176651e+001, + 1.79142670e+002, 1.58573654e+002, 2.12791580e+002, + 1.56291031e+002, 2.47140106e+002, 1.54265656e+002, + 2.82607300e+002, 1.52373688e+002, 3.18175507e+002, + 1.50692184e+002, 3.54185852e+002, 1.49404175e+002, + 3.90455200e+002, 1.48229370e+002, 4.26106689e+002, + 1.47507843e+002, 4.61576141e+002, 1.46712479e+002, + 1.80388336e+002, 1.93027603e+002, 2.14026459e+002, + 1.91128204e+002, 2.48376541e+002, 1.89414978e+002, + 2.83795807e+002, 1.87720856e+002, 3.19472473e+002, + 1.86192383e+002, 3.55483826e+002, 1.84929199e+002, + 3.91970764e+002, 1.83747040e+002, 4.27654572e+002, + 1.82931534e+002, 4.63295227e+002, 1.81977234e+002, + 1.81914261e+002, 2.27955460e+002, 2.15291260e+002, + 2.26512482e+002, 2.49628265e+002, 2.25067520e+002, + 2.85066406e+002, 2.23593185e+002, 3.20846680e+002, + 2.22337708e+002, 3.56862885e+002, 2.21191040e+002, + 3.93279907e+002, 2.19905640e+002, 4.29202271e+002, + 2.18870361e+002, 4.64728424e+002, 2.17972977e+002, + 1.83496948e+002, 2.62963226e+002, 2.16930527e+002, + 2.61755219e+002, 2.51115829e+002, 2.60777222e+002, + 2.86553406e+002, 2.59500336e+002, 3.22299896e+002, + 2.58380737e+002, 3.58307648e+002, 2.57236694e+002, + 3.94551819e+002, 2.56009125e+002, 4.30358948e+002, + 2.54925797e+002, 4.65684998e+002, 2.54021484e+002, + 1.85461685e+002, 2.97687378e+002, 2.18712234e+002, + 2.96999207e+002, 2.52770218e+002, 2.96270752e+002, + 2.88213776e+002, 2.95168213e+002, 3.23698334e+002, + 2.94233032e+002, 3.59477722e+002, 2.93170715e+002, + 3.95647766e+002, 2.91897400e+002, 4.31309845e+002, + 2.90856995e+002, 4.66494110e+002, 2.89726410e+002, + 1.87661331e+002, 3.32186188e+002, 2.20767746e+002, + 3.31906250e+002, 2.54839096e+002, 3.31398651e+002, + 2.89963745e+002, 3.30524139e+002, 3.25207642e+002, + 3.29771820e+002, 3.60686035e+002, 3.28762695e+002, + 3.96576447e+002, 3.27542206e+002, 4.31994415e+002, + 3.26294189e+002, 4.66894653e+002, 3.24949921e+002, + 2.03543015e+002, 1.77473557e+002, 2.32777847e+002, + 1.74712509e+002, 2.62628723e+002, 1.72331970e+002, + 2.93045898e+002, 1.69686768e+002, 3.23527618e+002, + 1.67496246e+002, 3.54206787e+002, 1.65446075e+002, + 3.85180176e+002, 1.63360580e+002, 4.15484253e+002, + 1.61536423e+002, 4.45720947e+002, 1.59896164e+002, + 2.05864395e+002, 2.07228104e+002, 2.35242096e+002, + 2.04699326e+002, 2.64853973e+002, 2.02407455e+002, + 2.95353882e+002, 1.99972321e+002, 3.25811890e+002, + 1.97671921e+002, 3.56471252e+002, 1.95763168e+002, + 3.87280548e+002, 1.93597977e+002, 4.17615814e+002, + 1.91867371e+002, 4.48018677e+002, 1.90067413e+002, + 2.08421249e+002, 2.37166977e+002, 2.37513824e+002, + 2.34982773e+002, 2.67261261e+002, 2.32802841e+002, + 2.97555817e+002, 2.30466080e+002, 3.28118103e+002, + 2.28462463e+002, 3.58699707e+002, 2.26417038e+002, + 3.89468842e+002, 2.24356827e+002, 4.19895996e+002, + 2.22421921e+002, 4.50077850e+002, 2.20683517e+002, + 2.11095444e+002, 2.66940186e+002, 2.40241348e+002, + 2.64970093e+002, 2.69563019e+002, 2.63153290e+002, + 2.99863464e+002, 2.60983551e+002, 3.30282440e+002, + 2.58911560e+002, 3.60724792e+002, 2.56935730e+002, + 3.91487915e+002, 2.54799423e+002, 4.21789093e+002, + 2.52929688e+002, 4.51818481e+002, 2.51059357e+002, + 2.13829117e+002, 2.96591217e+002, 2.42742859e+002, + 2.94884583e+002, 2.72209076e+002, 2.93215668e+002, + 3.02402985e+002, 2.91230591e+002, 3.32536072e+002, + 2.89165192e+002, 3.62860901e+002, 2.87413605e+002, + 3.93481842e+002, 2.85199615e+002, 4.23728851e+002, + 2.83277496e+002, 4.53453094e+002, 2.81229309e+002, + 2.16799316e+002, 3.25975220e+002, 2.45605515e+002, + 3.24619904e+002, 2.74777344e+002, 3.22958679e+002, + 3.04762817e+002, 3.21008057e+002, 3.34797150e+002, + 3.19291443e+002, 3.65005798e+002, 3.17295044e+002, + 3.95311981e+002, 3.15296021e+002, 4.25312592e+002, + 3.13086945e+002, 4.54931152e+002, 3.11027130e+002, + 2.60550232e+002, 3.70739563e+002, 2.59674011e+002, + 3.42115936e+002, 2.58910492e+002, 3.13278015e+002, + 2.58195618e+002, 2.84013580e+002, 2.57727173e+002, + 2.55017166e+002, 2.57326263e+002, 2.25760986e+002, + 2.57096619e+002, 1.96577972e+002, 2.57031860e+002, + 1.68026199e+002, 2.56873383e+002, 1.39550308e+002, + 2.89019318e+002, 3.70481354e+002, 2.88355560e+002, + 3.41833252e+002, 2.87601471e+002, 3.12872925e+002, + 2.87057190e+002, 2.83485535e+002, 2.86599762e+002, + 2.54255096e+002, 2.86174438e+002, 2.25023285e+002, + 2.85775940e+002, 1.95715347e+002, 2.85577087e+002, + 1.66989502e+002, 2.85395477e+002, 1.38597382e+002, + 3.18072754e+002, 3.70118317e+002, 3.17432709e+002, + 3.41398743e+002, 3.16917267e+002, 3.12476044e+002, + 3.16284363e+002, 2.83001587e+002, 3.15799072e+002, + 2.53725845e+002, 3.15411957e+002, 2.24337708e+002, + 3.15070374e+002, 1.95034119e+002, 3.14736847e+002, + 1.66195313e+002, 3.14439789e+002, 1.37797058e+002, + 3.47083588e+002, 3.69678101e+002, 3.46717987e+002, + 3.40949524e+002, 3.46185303e+002, 3.12009857e+002, + 3.45728088e+002, 2.82454071e+002, 3.45226624e+002, + 2.53109863e+002, 3.44883606e+002, 2.23839539e+002, + 3.44373535e+002, 1.94399933e+002, 3.43879852e+002, + 1.65690643e+002, 3.43438629e+002, 1.37252930e+002, + 3.76341522e+002, 3.68972321e+002, 3.76086884e+002, + 3.40412842e+002, 3.75708893e+002, 3.11398376e+002, + 3.75143494e+002, 2.81901520e+002, 3.74762970e+002, + 2.52577988e+002, 3.74223969e+002, 2.23348221e+002, + 3.73600891e+002, 1.93979538e+002, 3.72983917e+002, + 1.65201294e+002, 3.72517273e+002, 1.36871033e+002, + 4.05512115e+002, 3.68243225e+002, 4.05366333e+002, + 3.39678650e+002, 4.05090027e+002, 3.10679108e+002, + 4.04612366e+002, 2.81203522e+002, 4.04152649e+002, + 2.52051605e+002, 4.03539703e+002, 2.22930420e+002, + 4.02903351e+002, 1.93625381e+002, 4.02272827e+002, + 1.65004440e+002, 4.01353333e+002, 1.36796814e+002 ]