You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
4.8 KiB
175 lines
4.8 KiB
|
|
#include <librealsense2/rs.hpp> // Include RealSense Cross Platform API
|
|
#include <opencv2/opencv.hpp> // Include OpenCV API
|
|
|
|
using namespace cv;
|
|
|
|
bool is_yaw{false};
|
|
bool is_roll{false};
|
|
|
|
cv::RotateFlags angle(cv::RotateFlags::ROTATE_90_CLOCKWISE);
|
|
|
|
void changeMode() {
|
|
static int i = 0;
|
|
|
|
i++;
|
|
if (i==5) i=0;
|
|
|
|
switch (i) {
|
|
case 0:
|
|
is_yaw = false;
|
|
is_roll = false;
|
|
break;
|
|
case 1:
|
|
is_yaw = true;
|
|
is_roll = false;
|
|
break;
|
|
case 2:
|
|
is_yaw = false;
|
|
is_roll = true;
|
|
|
|
angle = cv::RotateFlags::ROTATE_90_CLOCKWISE;
|
|
|
|
break;
|
|
case 3:
|
|
is_yaw = false;
|
|
is_roll = true;
|
|
|
|
angle = cv::RotateFlags::ROTATE_180;
|
|
|
|
break;
|
|
case 4:
|
|
is_yaw = false;
|
|
is_roll = true;
|
|
|
|
angle = cv::RotateFlags::ROTATE_90_COUNTERCLOCKWISE;
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char * argv[]) try
|
|
{
|
|
// Declare depth colorizer for pretty visualization of depth data
|
|
rs2::colorizer color_map;
|
|
|
|
// Aligning frames to color size
|
|
rs2::align depthToColorAlignment(RS2_STREAM_COLOR);
|
|
|
|
// Declare threshold filter for work with dots in range
|
|
rs2::threshold_filter threshold;
|
|
float threshold_min = 0.3f;
|
|
float threshold_max = 1.5f;
|
|
|
|
// Keep dots on the depth frame in range
|
|
threshold.set_option(RS2_OPTION_MIN_DISTANCE, threshold_min);
|
|
threshold.set_option(RS2_OPTION_MAX_DISTANCE, threshold_max);
|
|
|
|
// Declare RealSense pipeline, encapsulating the actual device and sensors
|
|
rs2::pipeline pipe;
|
|
// Start streaming with default recommended configuration
|
|
pipe.start();
|
|
|
|
rs2::processing_block procBlock( [&](rs2::frame f, rs2::frame_source& src )
|
|
{
|
|
const int origWidth = f.as<rs2::video_frame>().get_width();
|
|
const int origHeight = f.as<rs2::video_frame>().get_height();
|
|
|
|
cv::Mat image(cv::Size(origWidth, origHeight), CV_16UC1, (void*)f.get_data(), cv::Mat::AUTO_STEP);
|
|
cv::Mat rotated;
|
|
|
|
if ( !is_yaw && !is_roll )
|
|
rotated = image;
|
|
|
|
if ( is_yaw ) {
|
|
int rotWidth(static_cast<int>(threshold_max * 1000));
|
|
|
|
rotated = cv::Mat::zeros(cv::Size(rotWidth, image.size().height), CV_16UC1 );
|
|
|
|
for(int h = 0; h < rotated.size().height; h++) {
|
|
for(int w = 0; w < rotated.size().width; w++) {
|
|
|
|
if ( ( h >= image.size().height ) || ( w >= image.size().width ) )
|
|
continue;
|
|
|
|
unsigned short value = image.at<unsigned short>(h, w);
|
|
|
|
if ( value == 0 )
|
|
continue;
|
|
|
|
rotated.at<unsigned short>( h, value ) = w;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_roll) {
|
|
cv::rotate( image, rotated, angle );
|
|
}
|
|
|
|
auto res = src.allocate_video_frame(f.get_profile(), f, 0, rotated.size().width, rotated.size().height);
|
|
memcpy((void*)res.get_data(), rotated.data, rotated.size().width * rotated.size().height * 2);
|
|
|
|
src.frame_ready(res);
|
|
});
|
|
|
|
rs2::frame_queue frame_queue;
|
|
procBlock.start(frame_queue);
|
|
|
|
while ( true )
|
|
{
|
|
// get set of frames
|
|
rs2::frameset frames = pipe.wait_for_frames(); // Wait for next set of frames from the camera
|
|
|
|
// align images
|
|
frames = depthToColorAlignment.process(frames);
|
|
|
|
// get depth frames
|
|
rs2::frame depthFrame = frames.get_depth_frame();
|
|
|
|
// keep points in range from threshold_min to threshold_max
|
|
depthFrame = threshold.process(depthFrame);
|
|
|
|
// call processing block for handle cloud point
|
|
procBlock.invoke( depthFrame );
|
|
depthFrame = frame_queue.wait_for_frame();
|
|
|
|
// Query frame size (width and height)
|
|
const int w = depthFrame.as<rs2::video_frame>().get_width();
|
|
const int h = depthFrame.as<rs2::video_frame>().get_height();
|
|
|
|
// Create OpenCV matrix of size (w,h) from the colorized depth data
|
|
cv::Mat image(cv::Size(w, h), CV_8UC3, (void*)depthFrame.apply_filter(color_map).get_data());
|
|
|
|
// Rescale image for convenience
|
|
if ( ( image.size().width > 1000 ) || (image.size().height > 1000) )
|
|
resize( image, image, Size(), 0.5, 0.5);
|
|
|
|
// Update the window with new data
|
|
imshow("window_name", image);
|
|
int k = waitKey(1);
|
|
|
|
if ( k == 'q' )
|
|
break;
|
|
|
|
if ( k == 'c' )
|
|
changeMode();
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
catch (const rs2::error & e)
|
|
{
|
|
std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
std::cerr << e.what() << std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
|
|
|