Ask Your Question

Revision history [back]

Determining Hausdorff distance - zero values for non overlaped shapes

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 ;
}
click to hide/show revision 2
None

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

berak gravatar image

Determining Hausdorff distance - zero values for non overlaped shapes

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.pngC:\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 ;
 }