int main(int argc, char **argv) { // Parse command line options. arg_base::set_help_option("-h"); arg_parse(argc, argv); // Set debug level to 1. ntk::ntk_debug_level = 1; // Set current directory to application directory. // This is to find Nite config in config/ directory. // FIXME: this is disabled for OpenCV QT compatibility. // QApplication app (argc, argv); // QDir::setCurrent(QApplication::applicationDirPath()); // Prepare body event listeners. MyBodyListener body_event_listener; BodyEventDetector detector; detector.addListener(&body_event_listener); // Declare the global OpenNI driver. Only one can be instantiated in a program. OpenniDriver ni_driver; // Declare the frame grabber. OpenniGrabber grabber(ni_driver, opt::kinect_id()); grabber.setBodyEventDetector(&detector); // High resolution 1280x1024 RGB Image. if (opt::high_resolution()) grabber.setHighRgbResolution(true); // Start the grabber. grabber.connectToDevice(); grabber.start(); // Holder for the current image. RGBDImage image; // Image post processor. Compute mappings when RGB resolution is 1280x1024. OpenniRGBDProcessor post_processor; namedWindow("depth"); namedWindow("color"); namedWindow("users"); while (true) { // Wait for a new frame, get a local copy and postprocess it. grabber.waitForNextFrame(); grabber.copyImageTo(image); post_processor.processImage(image); // Get the last hand point position. cv::Point3f handpoint = body_event_listener.getLastHandPosInImage(); ntk_dbg_print(handpoint, 1); // Prepare the depth view, with skeleton and handpoint. cv::Mat1b debug_depth_img = normalize_toMat1b(image.depth()); if (image.skeleton()) image.skeleton()->drawOnImage(debug_depth_img); circle(debug_depth_img, Point(handpoint.x, handpoint.y), 5, Scalar(0, 255, 255)); // Prepare the color view, with skeleton and handpoint. cv::Mat3b debug_color_img; image.mappedRgb().copyTo(debug_color_img); if (image.skeleton()) image.skeleton()->drawOnImage(debug_color_img); circle(debug_color_img, Point(handpoint.x, handpoint.y), 5, Scalar(0, 255, 255)); // Prepare the user mask view as colors. cv::Mat3b debug_users; image.fillRgbFromUserLabels(debug_users); imshow("depth", debug_depth_img); imshow("color", debug_color_img); imshow("users", debug_users); cv::waitKey(10); } // return app.exec(); }
bool SurfelsRGBDModeler :: addNewView(const RGBDImage& image_, Pose3D& depth_pose) { ntk::TimeCount tc("SurfelsRGBDModeler::addNewView", 1); const float max_camera_normal_angle = ntk::deg_to_rad(90); RGBDImage image; image_.copyTo(image); if (!image_.normal().data) { OpenniRGBDProcessor processor; processor.computeNormalsPCL(image); } Pose3D rgb_pose = depth_pose; rgb_pose.toRightCamera(image.calibration()->rgb_intrinsics, image.calibration()->R, image.calibration()->T); Pose3D world_to_camera_normal_pose; world_to_camera_normal_pose.applyTransformBefore(cv::Vec3f(0,0,0), depth_pose.cvEulerRotation()); Pose3D camera_to_world_normal_pose = world_to_camera_normal_pose; camera_to_world_normal_pose.invert(); const Mat1f& depth_im = image.depth(); Mat1b covered_pixels (depth_im.size()); covered_pixels = 0; std::list<Surfel> surfels_to_reinsert; // Surfel updating. for (SurfelMap::iterator next_it = m_surfels.begin(); next_it != m_surfels.end(); ) { SurfelMap::iterator surfel_it = next_it; ++next_it; Surfel& surfel = surfel_it->second; if (!surfel.enabled()) continue; Point3f surfel_2d = depth_pose.projectToImage(surfel.location); bool surfel_deleted = false; int r = ntk::math::rnd(surfel_2d.y); int c = ntk::math::rnd(surfel_2d.x); int d = ntk::math::rnd(surfel_2d.z); if (!is_yx_in_range(depth_im, r, c) || !image.depthMask()(r, c) || !image.isValidNormal(r,c)) continue; const float update_max_dist = getCompatibilityDistance(depth_im(r,c)); Vec3f camera_normal = image.normal()(r, c); normalize(camera_normal); Vec3f world_normal = camera_to_world_normal_pose.cameraTransform(camera_normal); normalize(world_normal); Vec3f eyev = camera_eye_vector(depth_pose, r, c); double camera_angle = acos(camera_normal.dot(-eyev)); if (camera_angle > max_camera_normal_angle) continue; float normal_angle = acos(world_normal.dot(surfel.normal)); // Surfels have different normals, maybe two different faces of the same object. if (normal_angle > (m_update_max_normal_angle*M_PI/180.0)) { // Removal check. If a surfel has a different normal and is closer to the camera // than the new scan, remove it. if ((-surfel_2d.z) < depth_im(r,c) && surfel.n_views < 3) { m_surfels.erase(surfel_it); surfel_deleted = true; } continue; } // If existing surfel is far from new depth value: // - If existing one had a worst point of view, and was seen only once, remove it. // - Otherwise do not include the new one. if (std::abs(surfel_2d.z - depth_im(r,c)) > update_max_dist) { if (surfel.min_camera_angle > camera_angle && surfel.n_views < 3) { m_surfels.erase(surfel_it); surfel_deleted = true; } else covered_pixels(r,c) = 1; continue; } // Compatible surfel found. const float depth = depth_im(r,c) + m_global_depth_offset; Point3f p3d = depth_pose.unprojectFromImage(Point2f(c,r), depth); cv::Vec3b rgb_color = bgr_to_rgb(image.mappedRgb()(r, c)); Surfel image_surfel; image_surfel.location = p3d; image_surfel.normal = world_normal; image_surfel.color = rgb_color; image_surfel.min_camera_angle = camera_angle; image_surfel.n_views = 1; image_surfel.radius = computeSurfelRadius(depth, camera_normal[2], depth_pose.meanFocal()); mergeToLeftSurfel(surfel, image_surfel); covered_pixels(r,c) = 1; // needs to change the cell? Cell new_cell = worldToCell(surfel.location); if (new_cell != surfel_it->first) { surfels_to_reinsert.push_back(surfel); m_surfels.erase(surfel_it); } } foreach_const_it(it, surfels_to_reinsert, std::list<Surfel>) { Cell new_cell = worldToCell(it->location); m_surfels.insert(std::make_pair(new_cell, *it)); }
void RGBDFrameRecorder :: saveCurrentFrame(const RGBDImage& image) { std::string frame_dir = format("%s/view%04d", m_dir.absolutePath().toStdString().c_str(), m_frame_index); std::string raw_frame_dir = format("%s/raw", frame_dir.c_str(), m_frame_index); QDir dir (frame_dir.c_str()); dir.mkpath("raw"); std::string filename; if (!m_only_raw) { filename = cv::format("%s/color.png", frame_dir.c_str()); imwrite(filename, image.rgb()); } filename = cv::format("%s/raw/color.png", frame_dir.c_str()); imwrite(filename, image.rawRgb()); if (!m_only_raw && image.mappedDepth().data) { filename = cv::format("%s/mapped_depth.png", frame_dir.c_str()); imwrite_normalized(filename, image.mappedDepth()); filename = cv::format("%s/mapped_color.png", frame_dir.c_str()); imwrite(filename, image.mappedRgb()); filename = cv::format("%s/depth.yml", frame_dir.c_str()); imwrite_yml(filename, image.mappedDepth()); } if (!m_only_raw) { filename = cv::format("%s/raw/depth.png", frame_dir.c_str()); if (image.rawDepth().data) imwrite_normalized(filename.c_str(), image.rawDepth()); filename = cv::format("%s/depth.png", frame_dir.c_str()); if (image.depth().data) imwrite_normalized(filename.c_str(), image.depth()); filename = cv::format("%s/intensity.png", frame_dir.c_str()); if (image.intensity().data) imwrite_normalized(filename.c_str(), image.intensity()); } if (image.rawDepth().data) { if (m_use_binary_raw) { filename = cv::format("%s/raw/depth.raw", frame_dir.c_str()); imwrite_Mat1f_raw(filename.c_str(), image.rawDepth()); } else { filename = cv::format("%s/raw/depth.yml", frame_dir.c_str()); imwrite_yml(filename.c_str(), image.rawDepth()); } } if (image.rawIntensity().data) { if (m_use_binary_raw) { filename = cv::format("%s/raw/intensity.raw", frame_dir.c_str()); imwrite_Mat1f_raw(filename.c_str(), image.rawIntensity()); } else { filename = cv::format("%s/raw/intensity.yml", frame_dir.c_str()); imwrite_yml(filename.c_str(), image.rawIntensity()); } } if (!m_only_raw) { filename = cv::format("%s/raw/amplitude.png", frame_dir.c_str()); if (image.rawAmplitude().data) imwrite_normalized(filename.c_str(), image.rawAmplitude()); filename = cv::format("%s/amplitude.png", frame_dir.c_str()); if (image.amplitude().data) imwrite_normalized(filename.c_str(), image.amplitude()); } if (image.rawAmplitude().data) { if (m_use_binary_raw) { filename = cv::format("%s/raw/amplitude.raw", frame_dir.c_str()); imwrite_Mat1f_raw(filename.c_str(), image.rawAmplitude()); } else { filename = cv::format("%s/raw/amplitude.yml", frame_dir.c_str()); imwrite_yml(filename.c_str(), image.rawAmplitude()); } } ++m_frame_index; }
void RGBDFrameRecorder :: writeFrame(const RGBDImage& image, const std::string& frame_dir) { std::string raw_frame_dir = format("%s/raw", frame_dir.c_str(), m_frame_index); QDir dir (frame_dir.c_str()); dir.mkpath("raw"); std::string filename; if (m_save_rgb_pose && image.calibration()) { filename = cv::format("%s/rgb_pose.avs", frame_dir.c_str()); image.rgbPose().saveToAvsFile(filename.c_str()); } if (!m_only_raw) { filename = cv::format("%s/color.png", frame_dir.c_str()); imwrite(filename, image.rgb()); } if (m_save_pcl_point_cloud) { filename = cv::format("%s/cloud.pcd", frame_dir.c_str()); #ifdef NESTK_USE_PCL pcl::PointCloud<pcl::PointXYZ> cloud; rgbdImageToPointCloud(cloud, image); pcl::io::savePCDFileASCII(filename.c_str(), cloud); #endif } if (m_use_compressed_format) filename = cv::format("%s/raw/color.png", frame_dir.c_str()); else filename = cv::format("%s/raw/color.bmp", frame_dir.c_str()); imwrite(filename, image.rawRgb()); if (!m_only_raw && image.mappedDepth().data) { filename = cv::format("%s/mapped_depth.png", frame_dir.c_str()); imwrite_normalized(filename, image.mappedDepth()); filename = cv::format("%s/mapped_color.png", frame_dir.c_str()); imwrite(filename, image.mappedRgb()); filename = cv::format("%s/depth.yml", frame_dir.c_str()); imwrite_yml(filename, image.mappedDepth()); } if (!m_only_raw) { filename = cv::format("%s/raw/depth.png", frame_dir.c_str()); if (image.rawDepth().data) imwrite_normalized(filename.c_str(), image.rawDepth()); filename = cv::format("%s/depth.png", frame_dir.c_str()); if (image.depth().data) imwrite_normalized(filename.c_str(), image.depth()); filename = cv::format("%s/intensity.png", frame_dir.c_str()); if (image.intensity().data) imwrite_normalized(filename.c_str(), image.intensity()); } if (image.rawDepth().data) { if (m_use_binary_raw) { filename = cv::format("%s/raw/depth.raw", frame_dir.c_str()); imwrite_Mat1f_raw(filename.c_str(), image.rawDepth()); } else { filename = cv::format("%s/raw/depth.yml", frame_dir.c_str()); imwrite_yml(filename.c_str(), image.rawDepth()); } } if (m_save_intensity && image.rawIntensity().data) { if (m_use_binary_raw) { filename = cv::format("%s/raw/intensity.raw", frame_dir.c_str()); imwrite_Mat1f_raw(filename.c_str(), image.rawIntensity()); } else { filename = cv::format("%s/raw/intensity.yml", frame_dir.c_str()); imwrite_yml(filename.c_str(), image.rawIntensity()); } } if (!m_only_raw) { filename = cv::format("%s/raw/amplitude.png", frame_dir.c_str()); if (image.rawAmplitude().data) imwrite_normalized(filename.c_str(), image.rawAmplitude()); filename = cv::format("%s/amplitude.png", frame_dir.c_str()); if (image.amplitude().data) imwrite_normalized(filename.c_str(), image.amplitude()); } if (image.rawAmplitude().data) { if (m_use_binary_raw) { filename = cv::format("%s/raw/amplitude.raw", frame_dir.c_str()); imwrite_Mat1f_raw(filename.c_str(), image.rawAmplitude()); } else { filename = cv::format("%s/raw/amplitude.yml", frame_dir.c_str()); imwrite_yml(filename.c_str(), image.rawAmplitude()); } } }
int main(int argc, char **argv) { // Parse command line options. arg_base::set_help_option("-h"); arg_parse(argc, argv); // Set debug level to 1. ntk::ntk_debug_level = 1; // Set current directory to application directory. // This is to find Nite config in config/ directory. QApplication app (argc, argv); QDir::setCurrent(QApplication::applicationDirPath()); // Declare the global OpenNI driver. Only one can be instantiated in a program. OpenniDriver ni_driver; // Declare the frame grabber. OpenniGrabber grabber(ni_driver, opt::kinect_id()); // High resolution 1280x1024 RGB Image. if (opt::high_resolution()) grabber.setHighRgbResolution(true); // Use mirrored images. grabber.setMirrored(true); // Start the grabber. grabber.connectToDevice(); grabber.start(); // Holder for the current image. RGBDImage image; // Image post processor. Compute mappings when RGB resolution is 1280x1024. OpenniRGBDProcessor post_processor; namedWindow("depth"); namedWindow("color"); namedWindow("users"); char last_c = 0; while (true && (last_c != 27)) { // Wait for a new frame, get a local copy and postprocess it. grabber.waitForNextFrame(); grabber.copyImageTo(image); post_processor.processImage(image); // Prepare the depth view, with skeleton and handpoint. cv::Mat1b debug_depth_img = normalize_toMat1b(image.depth()); if (image.skeleton()) image.skeleton()->drawOnImage(debug_depth_img); // Prepare the color view (mapped to depth frame), with skeleton and handpoint. cv::Mat3b debug_color_img; image.mappedRgb().copyTo(debug_color_img); if (image.skeleton()) image.skeleton()->drawOnImage(debug_color_img); // Prepare the user mask view as colors. cv::Mat3b debug_users; image.fillRgbFromUserLabels(debug_users); imshow("depth", debug_depth_img); imshow("color", debug_color_img); imshow("users", debug_users); last_c = (cv::waitKey(10) & 0xff); } }