void calibrate_kinect_depth(std::vector< std::vector<Point2f> >& stereo_corners, std::vector< DepthCalibrationPoint >& depth_values) { std::vector< std::vector<Point2f> > good_corners; stereo_corners.resize(global::images_list.size()); for (int i_image = 0; i_image < global::images_list.size(); ++i_image) { QString filename = global::images_list[i_image]; QDir cur_image_dir (global::images_dir.absoluteFilePath(filename)); std::string full_filename; cv::Mat3b image; load_intensity_file(cur_image_dir.path().toStdString(), full_filename, image); ntk_ensure(image.data, "Could not load color image"); kinect_shift_ir_to_depth(image); std::vector<Point2f> current_view_corners; calibrationCorners(full_filename, "corners", global::opt_pattern_width(), global::opt_pattern_height(), current_view_corners, image, 1); if (current_view_corners.size() == global::opt_pattern_height()*global::opt_pattern_width()) { good_corners.push_back(current_view_corners); stereo_corners[i_image] = current_view_corners; showCheckerboardCorners(image, current_view_corners, 1); } else { ntk_dbg(0) << "Warning: corners not detected"; stereo_corners[i_image].resize(0); } } std::vector< std::vector<Point3f> > pattern_points; calibrationPattern(pattern_points, global::opt_pattern_width(), global::opt_pattern_height(), global::opt_square_size(), good_corners.size()); ntk_assert(pattern_points.size() == good_corners.size(), "Invalid points size"); std::vector<Mat> rvecs, tvecs; int flags = 0; if (global::opt_ignore_distortions()) flags = CV_CALIB_ZERO_TANGENT_DIST; double error = calibrateCamera(pattern_points, good_corners, global::image_size, global::depth_intrinsics, global::depth_distortion, rvecs, tvecs, flags); if (global::opt_ignore_distortions()) global::depth_distortion = 0.f; ntk_dbg_print(error, 1); int good_i = 0; foreach_idx(stereo_i, stereo_corners) { if (stereo_corners[stereo_i].size() > 0) { QString filename = global::images_list[stereo_i]; QDir cur_image_dir (global::images_dir.absoluteFilePath(filename)); std::string full_filename; cv::Mat3b image; load_intensity_file(cur_image_dir.path().toStdString(), full_filename, image); ntk_ensure(image.data, "Could not load intensity image"); kinect_shift_ir_to_depth(image); cv::Mat1f depth_image; if (is_file(cur_image_dir.absoluteFilePath("raw/depth.yml").toStdString())) { full_filename = cur_image_dir.absoluteFilePath("raw/depth.yml").toStdString(); depth_image = imread_yml(full_filename); } else if (is_file(cur_image_dir.absoluteFilePath("raw/depth.raw").toStdString())) { full_filename = cur_image_dir.absoluteFilePath("raw/depth.raw").toStdString(); depth_image = imread_Mat1f_raw(full_filename); } ntk_ensure(depth_image.data, "Could not load depth image"); cv::Mat3b undistorted_image; if (global::opt_ignore_distortions()) image.copyTo(undistorted_image); else undistort(image, undistorted_image, global::depth_intrinsics, global::depth_distortion); std::vector<Point2f> current_view_corners; calibrationCorners(full_filename, "corners", global::opt_pattern_width(), global::opt_pattern_height(), current_view_corners, undistorted_image, 1); if (current_view_corners.size() == (global::opt_pattern_width()*global::opt_pattern_height())) { stereo_corners[stereo_i] = current_view_corners; showCheckerboardCorners(undistorted_image, stereo_corners[stereo_i], 200); } else { stereo_corners[stereo_i].resize(0); continue; } // Generate calibration points { // FIXME: why rvecs and tvecs from calibrateCamera seems to be nonsense ? // calling findExtrinsics another time to get good chessboard estimations. cv::Mat1f H; estimate_checkerboard_pose(pattern_points[0], current_view_corners, global::depth_intrinsics, H); Pose3D pose; pose.setCameraParametersFromOpencv(global::depth_intrinsics); ntk_dbg_print(pose, 1); pose.setCameraTransform(H); foreach_idx(pattern_i, pattern_points[0]) { ntk_dbg_print(pattern_points[0][pattern_i], 1); Point3f p = pose.projectToImage(pattern_points[0][pattern_i]); ntk_dbg_print(p, 1); double kinect_raw = depth_image(p.y, p.x); if (!(kinect_raw < 2047)) continue; ntk_dbg_print(kinect_raw, 1); double linear_depth = 1.0 / (kinect_raw * -0.0030711016 + 3.3309495161); const float k1 = 1.1863; const float k2 = 2842.5; const float k3 = 0.1236; double tan_depth = k3 * tanf(kinect_raw/k2 + k1); ntk_dbg_print(linear_depth, 1); ntk_dbg_print(tan_depth, 1); depth_values.push_back(DepthCalibrationPoint(kinect_raw, p.z)); } } ++good_i; }
void calibrate_kinect_depth(std::vector< DepthCalibrationPoint >& depth_values) { std::vector< std::vector<Point3f> > pattern_points; calibrationPattern(pattern_points, global::opt_pattern_width(), global::opt_pattern_height(), global::opt_square_size(), global::images_list.size()); for (int i_image = 0; i_image < global::images_list.size(); ++i_image) { // Generate depth calibration points QString filename = global::images_list[i_image]; QDir cur_image_dir (global::images_dir.absoluteFilePath(filename)); std::string full_filename = cur_image_dir.absoluteFilePath("raw/color.png").toStdString(); RGBDImage image; OpenniRGBDProcessor processor; processor.setFilterFlag(RGBDProcessorFlags::ComputeMapping, true); image.loadFromDir(cur_image_dir.absolutePath().toStdString(), &global::calibration, &processor); imshow_normalized("mapped depth", image.mappedDepth()); imshow("color", image.rgb()); std::vector<Point2f> current_view_corners; calibrationCorners(full_filename, "corners", global::opt_pattern_width(), global::opt_pattern_height(), current_view_corners, image.rgb(), 1, global::pattern_type); if (current_view_corners.size() != (global::opt_pattern_width()*global::opt_pattern_height())) { ntk_dbg(1) << "Corners not detected in " << cur_image_dir.absolutePath().toStdString(); continue; } // FIXME: why rvecs and tvecs from calibrateCamera seems to be nonsense ? // calling findExtrinsics another time to get good chessboard estimations. cv::Mat1f H; estimate_checkerboard_pose(pattern_points[0], current_view_corners, global::calibration.rgb_intrinsics, H); Pose3D pose; pose.setCameraParametersFromOpencv(global::calibration.rgb_intrinsics); pose.setCameraTransform(H); ntk_dbg_print(pose, 1); cv::Mat3b debug_img; image.rgb().copyTo(debug_img); foreach_idx(pattern_i, pattern_points[0]) { Point3f p = pose.projectToImage(pattern_points[0][pattern_i]); ntk_dbg_print(p, 1); float kinect_raw = image.mappedDepth()(p.y, p.x); ntk_dbg_print(kinect_raw, 1); if (kinect_raw < 1e-5) continue; float err = kinect_raw-p.z; cv::putText(debug_img, format("%d", (int)(err*1000)), Point(p.x, p.y), CV_FONT_NORMAL, 0.4, Scalar(255,0,0)); ntk_dbg_print(pattern_points[0][pattern_i], 1); ntk_dbg_print(p, 1); ntk_dbg_print(kinect_raw, 1); depth_values.push_back(DepthCalibrationPoint(kinect_raw, p.z)); } imshow("errors", debug_img); cv::waitKey(0); }