Determining Hausdorff distance - zero values for non overlaped shapes

asked 2018-08-03 10:02:30 -0600

tomass gravatar image

updated 2018-08-03 10:07:20 -0600

berak gravatar image

I use opencv 3.4.2. When I apply computeDistance(contour1, contour2) of createHausdorffDistanceExtractor, I obtain zero values for more than one position out of overlaped shape contours. To show this, consider following benchmark: The square contour (patch or model) which moves vertically over the image with the square contour (the same size and orientation as the patch). It should yield zero Hausdorff distance only once, why is not so ? Let me note that this is only in vertical direction. In the horizontal direction it works perfectly.

C:\fakepath\Capture du 2018-08-03 16-40-28.png C:\fakepath\Capture du 2018-08-03 16-58-56.png

White is original contour and gray is moved patch.

Output:

Hausdorff distance - horizontal direction: 45.000000
Hausdorff distance - vertical direction: 0.000000

it should be instead the same for both i.e. 45. Has somone made the same observation ?

    #include <string>
    #include <stdio.h>

    #include <opencv2/core.hpp>
    #include <opencv2/imgproc.hpp>
    #include <opencv2/highgui.hpp>
    #include <opencv2/shape/shape_distance.hpp>

    std::vector<cv::Point> get_points(cv::Mat& img)
    {
      std::vector<cv::Point> points ;

      CV_Assert(img.depth() == CV_8U);

      for(unsigned i=0; i<img.rows; i++)
        {
          for(unsigned j=0; j<img.cols; j++)
          {
            if(img.at<uchar>(i,j)==255)
              points.push_back(cv::Point(i,j)) ;
          }
        }
      return points;
    }


    int main( int argc, char** argv )
    {
      const unsigned square_dim = 150 ;

      int movePatch = 105 ;

      float distH_h ; // Hausdorff distance horizontal                                                                                                                                                                                                                                
      float distH_v ; // Hausdorff distance vertical                                                                                                                                                                                                                                  

      // horizontally                                                                                                                                                                                                                                                                 
      cv::Mat imageContourH(square_dim,square_dim*3,CV_8UC1,cv::Scalar(0)) ;
      cv::Mat imagePatchH = imageContourH.clone() ;
      cv::rectangle(imageContourH,cv::Point(square_dim,0),cv::Point(2*square_dim-1,square_dim-1),cv::Scalar(255)) ;
      cv::rectangle(imagePatchH,cv::Point(movePatch,0),cv::Point(movePatch+square_dim-1,square_dim-1),cv::Scalar(255)) ;

      // vertically                                                                                                                                                                                                                                                                   
      cv::Mat imageContourV(square_dim*3,square_dim,CV_8UC1,cv::Scalar(0)) ;
      cv::Mat imagePatchV = imageContourV.clone() ;
      cv::rectangle(imageContourV,cv::Point(0,square_dim),cv::Point(square_dim-1,2*square_dim-1),cv::Scalar(255)) ;
      cv::rectangle(imagePatchV,cv::Point(0,movePatch),cv::Point(square_dim-1,movePatch+square_dim-1),cv::Scalar(255)) ;

      // Hausdorff distance from opencv library                                                                                                                                                                                                                                       
      cv::Ptr <cv::HausdorffDistanceExtractor> mysc = cv::createHausdorffDistanceExtractor() ;

      std::vector<cv::Point> contourH_pt = get_points(imageContourH) ;
      std::vector<cv::Point> patchH_pt = get_points(imagePatchH) ;
      distH_h = mysc->computeDistance( contourH_pt, patchH_pt ) ;

      std::vector<cv::Point> contourV_pt = get_points(imageContourV) ;
      std::vector<cv::Point> patchV_pt = get_points(imagePatchV) ;
      distH_v = mysc->computeDistance( contourV_pt, patchV_pt ) ;

      printf("Hausdorff distance - horizontal direction: %f\n",distH_h) ;  
      printf("Hausdorff distance - vertical direction: %f\n",distH_v) ;

      return 0 ;
    }
edit retag flag offensive close merge delete

Comments

For me this sounds like an error. I am not an expert in reading the openCV code but perhaps something is going wrong in the code, beginning from line 101 to 150 here: https://github.com/opencv/opencv/blob... I don't understand the comment in line 142, perhaps you can figure it out or try the computation step by step.

Grillteller gravatar imageGrillteller ( 2018-08-06 04:43:37 -0600 )edit