基于深度摄像头的障碍物检测(realsense+opencv)

一个基于深度摄像头的障碍物检测

代码的核心思路是首先通过二值化,将一米之外的安全距离置零不考虑,然后通过开运算去除掉一些噪点(这个后来发现不一定有必要),在求出所有障碍物的凸包,这个时候要计算面积,当面积小于一定的阈值的时候不予考虑,最终输出障碍物的凸包坐标。

//find_obstacle函数是获取深度图障碍物的函数,返回值是每个障碍物凸包的坐标,参数一depth是realsense返回的深度图(ushort型),
//参数二thresh和参数三max_thresh,是二值化的参数,参数四是凸包的最小有效面积,小于这个面积的障碍物可以视为噪点。
//函数首先筛选掉距离大于安全距离的点,然后进行阀值化和开运算减少一下噪点,用findContours得到轮廓图,最后用convexHull得到每个障碍物的凸包,最后返回坐标

//mask_depth函数是对深度图二值化,第一个参数image是原图,第二个参数th是目标图,第三个参数throld是最大距离,单位是mm,大于这个距离
//即为安全,不用考虑。

[cpp] view plain copy print ?
  1. #include   
  2. #include   
  3. #include   
  4. #include "RSWrapper.h"  
  5. #include "opencv2/imgproc/imgproc.hpp"  
  6.   
  7. using namespace std;  
  8. using namespace cv;  
  9. void mask_depth(Mat &image,Mat& th,int throld=1000)  
  10. {  
  11. int nr = image.rows; // number of rows   
  12. int nc = image.cols; // number of columns   
  13. for (int i = 0; i{  
  14.   
  15. for (int j = 0; j
  16. if (image.at(i, j)>throld)  {
  17. th.at(i, j) = 0;  
  18. }
  19. }  
  20. }  
  21.   
  22. }  
  23. vector > find_obstacle(Mat &depth, int thresh = 20, int max_thresh = 255, int area = 500)  
  24. {  
  25. Mat dep;  
  26. depth.copyTo(dep);  
  27. mask_depth(depth, dep, 1000);  
  28. dep.convertTo(dep, CV_8UC1, 1.0 / 16);  
  29. //imshow("color", color);  
  30. imshow("depth", dep);  
  31. Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));//核的大小可适当调整  
  32. Mat out;  
  33. //进行开操作  
  34. morphologyEx(dep, out, MORPH_OPEN, element);  
  35. //dilate(dhc, out, element);  
  36.   
  37. //显示效果图  
  38. imshow("opencv", out);  
  39. Mat src_copy = dep.clone();  
  40. Mat threshold_output;  
  41. vector > contours;  
  42. vector hierarchy;  
  43. RNG rng(12345);  
  44. /// 对图像进行二值化  
  45. threshold(dep, threshold_output, thresh, 255, CV_THRESH_BINARY);  
  46. //mask_depth(src, threshold_output);  
  47. /// 寻找轮廓  
  48. findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));  
  49.   
  50. /// 对每个轮廓计算其凸包  
  51. vector >hull(contours.size());  
  52. vector > result;  
  53. for (int i = 0; i < contours.size(); i++)  {  
  54. convexHull(Mat(contours[i]), hull[i], false);  
  55. }  
  56.   
  57. /// 绘出轮廓及其凸包  
  58. Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);  
  59. for (int i = 0; i< contours.size(); i++)  {  
  60. if (contourArea(contours[i]) < area)//面积小于area的凸包,可忽略  
  61. continue;  

  62. result.push_back(hull[i]);  
  63. Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));  
  64. drawContours(drawing, contours, i, color, 1, 8, vector(), 0, Point());  
  65. drawContours(drawing, hull, i, color, 1, 8, vector(), 0, Point());  
  66. }  
  67. imshow("contours", drawing);  
  68. return result;  
  69. }  
  70. int main(int argc, char* argv[])  
  71. {  
  72. Mat dhc;  
  73. Mat dep;  
  74. int idxImageRes = 1, idxFrameRate = 30;  
  75. RSWrapper depthCam(idxImageRes, idxImageRes, idxFrameRate, idxFrameRate);  
  76. if (!depthCam.init())   {  
  77. std::cerr << "Init. RealSense Failure!" << std::endl;  
  78. return -1;  
  79. }  
  80.   
  81. while (true)   {  
  82. //Get RGB-D Images  
  83. cv::Mat color, depth;  
  84. bool ret = depthCam.capture(color, depth);  
  85. if (!ret) {  
  86. std::cerr << "Get realsense camera data failure!" << std::endl;  
  87. break;  
  88. }  
  89. vector > result;  
  90. result = find_obstacle(depth, 20, 255, 500);  
  91.   
  92. if (cvWaitKey(1) == 27)  
  93. break;  
  94. }  
  95.   
  96. depthCam.release();  

你可能感兴趣的:(CV,深度相机,深度摄像头,机器人避障,C++)