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 ;
}