Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2017
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.94 KB | None | 0 0
  1. #include "opencv2/calib3d.hpp"
  2. #include "opencv2/imgproc.hpp"
  3. #include "opencv2/imgcodecs.hpp"
  4. #include "opencv2/highgui.hpp"
  5. #include "opencv2/core/utility.hpp"
  6. #include "opencv2/ximgproc/disparity_filter.hpp"
  7. #include <iostream>
  8. #include <string>
  9.  
  10. using namespace cv;
  11. using namespace cv::ximgproc;
  12. using namespace std;
  13.  
  14. Rect computeROI(Size2i src_sz, Ptr<StereoMatcher> matcher_instance);
  15.  
  16. const String keys =
  17. "{help h usage ? |                  | print this message                                                }"
  18. "{@left          |../data/aloeL.jpg | left view of the stereopair                                       }"
  19. "{@right         |../data/aloeR.jpg | right view of the stereopair                                      }"
  20. "{GT             |../data/aloeGT.png| optional ground-truth disparity (MPI-Sintel or Middlebury format) }"
  21. "{dst_path       |None              | optional path to save the resulting filtered disparity map        }"
  22. "{dst_raw_path   |None              | optional path to save raw disparity map before filtering          }"
  23. "{algorithm      |bm                | stereo matching method (bm or sgbm)                               }"
  24. "{filter         |wls_conf          | used post-filtering (wls_conf or wls_no_conf)                     }"
  25. "{no-display     |                  | don't display results                                             }"
  26. "{no-downscale   |                  | force stereo matching on full-sized views to improve quality      }"
  27. "{dst_conf_path  |None              | optional path to save the confidence map used in filtering        }"
  28. "{vis_mult       |1.0               | coefficient used to scale disparity map visualizations            }"
  29. "{max_disparity  |160               | parameter of stereo matching                                      }"
  30. "{window_size    |-1                | parameter of stereo matching                                      }"
  31. "{wls_lambda     |8000.0            | parameter of post-filtering                                       }"
  32. "{wls_sigma      |1.5               | parameter of post-filtering                                       }"
  33. ;
  34.  
  35. int main(int argc, char** argv)
  36. {
  37.     CommandLineParser parser(argc, argv, keys);
  38.     parser.about("Disparity Filtering Demo");
  39.     if (parser.has("help"))
  40.     {
  41.         parser.printMessage();
  42.         return 0;
  43.     }
  44.  
  45.     String left_im = parser.get<String>(0);
  46.     String right_im = parser.get<String>(1);
  47.     String GT_path = parser.get<String>("GT");
  48.  
  49.     String dst_path = parser.get<String>("dst_path");
  50.     String dst_raw_path = parser.get<String>("dst_raw_path");
  51.     String dst_conf_path = parser.get<String>("dst_conf_path");
  52.     String algo = parser.get<String>("algorithm");
  53.     String filter = parser.get<String>("filter");
  54.     bool no_display = parser.has("no-display");
  55.     bool no_downscale = parser.has("no-downscale");
  56.     int max_disp = parser.get<int>("max_disparity");
  57.     double lambda = parser.get<double>("wls_lambda");
  58.     double sigma = parser.get<double>("wls_sigma");
  59.     double vis_mult = parser.get<double>("vis_mult");
  60.  
  61.     int wsize;
  62.     if (parser.get<int>("window_size") >= 0) //user provided window_size value
  63.         wsize = parser.get<int>("window_size");
  64.     else
  65.     {
  66.         if (algo == "sgbm")
  67.             wsize = 3; //default window size for SGBM
  68.         else if (!no_downscale && algo == "bm" && filter == "wls_conf")
  69.             wsize = 7; //default window size for BM on downscaled views (downscaling is performed only for wls_conf)
  70.         else
  71.             wsize = 15; //default window size for BM on full-sized views
  72.     }
  73.  
  74.     if (!parser.check())
  75.     {
  76.         parser.printErrors();
  77.         return -1;
  78.     }
  79.  
  80.     //! [load_views]
  81.     Mat left = imread(left_im, IMREAD_COLOR);
  82.     if (left.empty())
  83.     {
  84.         cout << "Cannot read image file: " << left_im;
  85.         return -1;
  86.     }
  87.  
  88.     Mat right = imread(right_im, IMREAD_COLOR);
  89.     if (right.empty())
  90.     {
  91.         cout << "Cannot read image file: " << right_im;
  92.         return -1;
  93.     }
  94.     //! [load_views]
  95.  
  96.     bool noGT;
  97.     Mat GT_disp;
  98.     if (GT_path == "../data/aloeGT.png" && left_im != "../data/aloeL.jpg")
  99.         noGT = true;
  100.     else
  101.     {
  102.         noGT = false;
  103.         if (readGT(GT_path, GT_disp) != 0)
  104.         {
  105.             cout << "Cannot read ground truth image file: " << GT_path << endl;
  106.             return -1;
  107.         }
  108.     }
  109.  
  110.     Mat left_for_matcher, right_for_matcher;
  111.     Mat left_disp, right_disp;
  112.     Mat filtered_disp;
  113.     Mat conf_map = Mat(left.rows, left.cols, CV_8U);
  114.     conf_map = Scalar(255);
  115.     Rect ROI;
  116.     Ptr<DisparityWLSFilter> wls_filter;
  117.     double matching_time, filtering_time;
  118.     if (max_disp <= 0 || max_disp % 16 != 0)
  119.     {
  120.         cout << "Incorrect max_disparity value: it should be positive and divisible by 16";
  121.         return -1;
  122.     }
  123.     if (wsize <= 0 || wsize % 2 != 1)
  124.     {
  125.         cout << "Incorrect window_size value: it should be positive and odd";
  126.         return -1;
  127.     }
  128.     if (filter == "wls_conf") // filtering with confidence (significantly better quality than wls_no_conf)
  129.     {
  130.         if (!no_downscale)
  131.         {
  132.             // downscale the views to speed-up the matching stage, as we will need to compute both left
  133.             // and right disparity maps for confidence map computation
  134.             //! [downscale]
  135.             max_disp /= 2;
  136.             if (max_disp % 16 != 0)
  137.                 max_disp += 16 - (max_disp % 16);
  138.             resize(left, left_for_matcher, Size(), 0.5, 0.5);
  139.             resize(right, right_for_matcher, Size(), 0.5, 0.5);
  140.             //! [downscale]
  141.         }
  142.         else
  143.         {
  144.             left_for_matcher = left.clone();
  145.             right_for_matcher = right.clone();
  146.         }
  147.  
  148.         if (algo == "bm")
  149.         {
  150.             //! [matching]
  151.             Ptr<StereoBM> left_matcher = StereoBM::create(max_disp, wsize);
  152.             wls_filter = createDisparityWLSFilter(left_matcher);
  153.             Ptr<StereoMatcher> right_matcher = createRightMatcher(left_matcher);
  154.  
  155.             cvtColor(left_for_matcher, left_for_matcher, COLOR_BGR2GRAY);
  156.             cvtColor(right_for_matcher, right_for_matcher, COLOR_BGR2GRAY);
  157.  
  158.             matching_time = (double)getTickCount();
  159.             left_matcher->compute(left_for_matcher, right_for_matcher, left_disp);
  160.             right_matcher->compute(right_for_matcher, left_for_matcher, right_disp);
  161.             matching_time = ((double)getTickCount() - matching_time) / getTickFrequency();
  162.             //! [matching]
  163.         }
  164.         else if (algo == "sgbm")
  165.         {
  166.             Ptr<StereoSGBM> left_matcher = StereoSGBM::create(0, max_disp, wsize);
  167.             left_matcher->setP1(24 * wsize*wsize);
  168.             left_matcher->setP2(96 * wsize*wsize);
  169.             left_matcher->setPreFilterCap(63);
  170.             left_matcher->setMode(StereoSGBM::MODE_SGBM_3WAY);
  171.             wls_filter = createDisparityWLSFilter(left_matcher);
  172.             Ptr<StereoMatcher> right_matcher = createRightMatcher(left_matcher);
  173.  
  174.             matching_time = (double)getTickCount();
  175.             left_matcher->compute(left_for_matcher, right_for_matcher, left_disp);
  176.             right_matcher->compute(right_for_matcher, left_for_matcher, right_disp);
  177.             matching_time = ((double)getTickCount() - matching_time) / getTickFrequency();
  178.         }
  179.         else
  180.         {
  181.             cout << "Unsupported algorithm";
  182.             return -1;
  183.         }
  184.  
  185.         //! [filtering]
  186.         wls_filter->setLambda(lambda);
  187.         wls_filter->setSigmaColor(sigma);
  188.         filtering_time = (double)getTickCount();
  189.         wls_filter->filter(left_disp, left, filtered_disp, right_disp);
  190.         filtering_time = ((double)getTickCount() - filtering_time) / getTickFrequency();
  191.         //! [filtering]
  192.         conf_map = wls_filter->getConfidenceMap();
  193.  
  194.         // Get the ROI that was used in the last filter call:
  195.         ROI = wls_filter->getROI();
  196.         if (!no_downscale)
  197.         {
  198.             // upscale raw disparity and ROI back for a proper comparison:
  199.             resize(left_disp, left_disp, Size(), 2.0, 2.0);
  200.             left_disp = left_disp*2.0;
  201.             ROI = Rect(ROI.x * 2, ROI.y * 2, ROI.width * 2, ROI.height * 2);
  202.         }
  203.     }
  204.     else if (filter == "wls_no_conf")
  205.     {
  206.         /* There is no convenience function for the case of filtering with no confidence, so we
  207.         will need to set the ROI and matcher parameters manually */
  208.  
  209.         left_for_matcher = left.clone();
  210.         right_for_matcher = right.clone();
  211.  
  212.         if (algo == "bm")
  213.         {
  214.             Ptr<StereoBM> matcher = StereoBM::create(max_disp, wsize);
  215.             matcher->setTextureThreshold(0);
  216.             matcher->setUniquenessRatio(0);
  217.             cvtColor(left_for_matcher, left_for_matcher, COLOR_BGR2GRAY);
  218.             cvtColor(right_for_matcher, right_for_matcher, COLOR_BGR2GRAY);
  219.             ROI = computeROI(left_for_matcher.size(), matcher);
  220.             wls_filter = createDisparityWLSFilterGeneric(false);
  221.             wls_filter->setDepthDiscontinuityRadius((int)ceil(0.33*wsize));
  222.  
  223.             matching_time = (double)getTickCount();
  224.             matcher->compute(left_for_matcher, right_for_matcher, left_disp);
  225.             matching_time = ((double)getTickCount() - matching_time) / getTickFrequency();
  226.         }
  227.         else if (algo == "sgbm")
  228.         {
  229.             Ptr<StereoSGBM> matcher = StereoSGBM::create(0, max_disp, wsize);
  230.             matcher->setUniquenessRatio(0);
  231.             matcher->setDisp12MaxDiff(1000000);
  232.             matcher->setSpeckleWindowSize(0);
  233.             matcher->setP1(24 * wsize*wsize);
  234.             matcher->setP2(96 * wsize*wsize);
  235.             matcher->setMode(StereoSGBM::MODE_SGBM_3WAY);
  236.             ROI = computeROI(left_for_matcher.size(), matcher);
  237.             wls_filter = createDisparityWLSFilterGeneric(false);
  238.             wls_filter->setDepthDiscontinuityRadius((int)ceil(0.5*wsize));
  239.  
  240.             matching_time = (double)getTickCount();
  241.             matcher->compute(left_for_matcher, right_for_matcher, left_disp);
  242.             matching_time = ((double)getTickCount() - matching_time) / getTickFrequency();
  243.         }
  244.         else
  245.         {
  246.             cout << "Unsupported algorithm";
  247.             return -1;
  248.         }
  249.  
  250.         wls_filter->setLambda(lambda);
  251.         wls_filter->setSigmaColor(sigma);
  252.         filtering_time = (double)getTickCount();
  253.         wls_filter->filter(left_disp, left, filtered_disp, Mat(), ROI);
  254.         filtering_time = ((double)getTickCount() - filtering_time) / getTickFrequency();
  255.     }
  256.     else
  257.     {
  258.         cout << "Unsupported filter";
  259.         return -1;
  260.     }
  261.  
  262.     cout.precision(2);
  263.     cout << "Matching time:  " << matching_time << "s" << endl;
  264.     cout << "Filtering time: " << filtering_time << "s" << endl;
  265.     cout << endl;
  266.  
  267.     double MSE_before, percent_bad_before, MSE_after, percent_bad_after;
  268.     if (!noGT)
  269.     {
  270.         MSE_before = computeMSE(GT_disp, left_disp, ROI);
  271.         percent_bad_before = computeBadPixelPercent(GT_disp, left_disp, ROI);
  272.         MSE_after = computeMSE(GT_disp, filtered_disp, ROI);
  273.         percent_bad_after = computeBadPixelPercent(GT_disp, filtered_disp, ROI);
  274.  
  275.         cout.precision(5);
  276.         cout << "MSE before filtering: " << MSE_before << endl;
  277.         cout << "MSE after filtering:  " << MSE_after << endl;
  278.         cout << endl;
  279.         cout.precision(3);
  280.         cout << "Percent of bad pixels before filtering: " << percent_bad_before << endl;
  281.         cout << "Percent of bad pixels after filtering:  " << percent_bad_after << endl;
  282.     }
  283.  
  284.     if (dst_path != "None")
  285.     {
  286.         Mat filtered_disp_vis;
  287.         getDisparityVis(filtered_disp, filtered_disp_vis, vis_mult);
  288.         imwrite(dst_path, filtered_disp_vis);
  289.     }
  290.     if (dst_raw_path != "None")
  291.     {
  292.         Mat raw_disp_vis;
  293.         getDisparityVis(left_disp, raw_disp_vis, vis_mult);
  294.         imwrite(dst_raw_path, raw_disp_vis);
  295.     }
  296.     if (dst_conf_path != "None")
  297.     {
  298.         imwrite(dst_conf_path, conf_map);
  299.     }
  300.  
  301.     if (!no_display)
  302.     {
  303.         namedWindow("left", WINDOW_AUTOSIZE);
  304.         imshow("left", left);
  305.         namedWindow("right", WINDOW_AUTOSIZE);
  306.         imshow("right", right);
  307.  
  308.         if (!noGT)
  309.         {
  310.             Mat GT_disp_vis;
  311.             getDisparityVis(GT_disp, GT_disp_vis, vis_mult);
  312.             namedWindow("ground-truth disparity", WINDOW_AUTOSIZE);
  313.             imshow("ground-truth disparity", GT_disp_vis);
  314.         }
  315.  
  316.         Mat raw_disp_vis;
  317.         getDisparityVis(left_disp, raw_disp_vis, vis_mult);
  318.         namedWindow("raw disparity", WINDOW_AUTOSIZE);
  319.         imshow("raw disparity", raw_disp_vis);
  320.         Mat filtered_disp_vis;
  321.         getDisparityVis(filtered_disp, filtered_disp_vis, vis_mult);
  322.         namedWindow("filtered disparity", WINDOW_AUTOSIZE);
  323.         imshow("filtered disparity", filtered_disp_vis);
  324.         double average[3];
  325.         double total[3], count[3];
  326.         int marginLeft = 0.16*filtered_disp_vis.cols;
  327.         int width = filtered_disp_vis.cols - marginLeft;
  328.         for (int i = 0; i < filtered_disp_vis.rows; ++i) {
  329.             for (int j = marginLeft; j < filtered_disp_vis.cols; ++j) {
  330.                 int parte = (j - marginLeft) * 3 / filtered_disp_vis.cols;
  331.                 average[parte] += filtered_disp_vis.at<int>(i,j);
  332.                 ++count[parte];
  333.                 total[parte] += filtered_disp_vis.at<int>(i, j) > 120;
  334.             }
  335.         }
  336.         for (int i = 0; i < 3; ++i) {
  337.             average[i] /= max(1.0, total[i]);
  338.             count[i] /= total[i];
  339.         }
  340.         if (count[1] > 0.2) {
  341.             cout << "Obstaculo al medio" << endl;
  342.             if (count[0] > 0.2 && count[2] > 0.2) {
  343.                 cout << "Parar" << endl;
  344.             }
  345.             else if (count[0] < 0.2 && count[2] > 0.2) {
  346.                 cout << "Izquierda" << endl;
  347.             }
  348.             else if (count[0] > 0.2 && count[2]< 0.2) {
  349.                 cout << "Derecha" << endl;
  350.             }
  351.             else {
  352.                 if (average[0] < average[2]) cout << "Izquierda";
  353.                 else cout << "Derecha";
  354.             }
  355.         }
  356.         else {
  357.             cout << "Seguir" << endl;
  358.         }
  359.         waitKey();
  360.     }
  361.  
  362.     return 0;
  363. }
  364.  
  365. Rect computeROI(Size2i src_sz, Ptr<StereoMatcher> matcher_instance)
  366. {
  367.     int min_disparity = matcher_instance->getMinDisparity();
  368.     int num_disparities = matcher_instance->getNumDisparities();
  369.     int block_size = matcher_instance->getBlockSize();
  370.  
  371.     int bs2 = block_size / 2;
  372.     int minD = min_disparity, maxD = min_disparity + num_disparities - 1;
  373.  
  374.     int xmin = maxD + bs2;
  375.     int xmax = src_sz.width + minD - bs2;
  376.     int ymin = bs2;
  377.     int ymax = src_sz.height - bs2;
  378.  
  379.     Rect r(xmin, ymin, xmax - xmin, ymax - ymin);
  380.     return r;
  381. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement