Ask Your Question

Revision history [back]

Problem with Hamming Matcher

I'm running into issues that lead me to believe that Hamming matcher is not working as expected (or at least, not as I expect). Consider the following code (please run it if you have the appropriate packages installed):

int main( int argc, char** argv ) {

const int rows = 2;
const int cols = 3;
const int bitl = cols * 8;

BruteForceMatcher<Hamming> matcher;
std::vector<DMatch> matches;

Mat mat1 = cv::Mat::zeros(rows, cols, CV_8U);
std::bitset<bitl>* ptr1 = (std::bitset<bitl>*) (mat1.data + (rows - 1) * mat1.step[0]);
Mat mat2 = cv::Mat::zeros(rows, cols, CV_8U);
std::bitset<bitl>* ptr2 = (std::bitset<bitl>*) (mat2.data + (rows - 1) * mat2.step[0]);

ptr1->set(0, 0);
ptr2->set(0, 1);

std::cout << mat1 << std::endl << std::endl;
  std::cout << mat2 << std::endl << std::endl;

  matcher.match(mat1, mat2, matches);

  for (int i = 0; i < (int) matches.size(); i++ ) {
    std::cout << matches[i].distance << std::endl;
  }

  std::cout << std::endl << std::endl;

ptr1->set(0, 1);
ptr2->set(0, 0);

std::cout << mat1 << std::endl << std::endl;
  std::cout << mat2 << std::endl << std::endl;

  matcher.match(mat1, mat2, matches);

  for (int i = 0; i < (int) matches.size(); i++ ) {
    std::cout << matches[i].distance << std::endl;
  }

}

This gives the following output:

    [0, 0, 0;
  0, 0, 0]

[0, 0, 0;
  1, 0, 0]

0
0


[0, 0, 0;
  1, 0, 0]

[0, 0, 0;
  0, 0, 0]

0
1

which is, of course, nonsensical because the Hamming distance should be symmetric. Is there some subtlety in the way the Hamming matcher works that I am missing? Thank you all

click to hide/show revision 2
No.2 Revision

Problem with Hamming Matcher

I'm running into issues that lead me to believe that Hamming matcher is not working as expected (or at least, not as I expect). Consider the following code (please run it if you have the appropriate packages installed):

int main( int argc, char** argv ) {

const int rows = 2;
const int cols = 3;
const int bitl = cols * 8;

BruteForceMatcher<Hamming> matcher;
std::vector<DMatch> matches;

Mat mat1 = cv::Mat::zeros(rows, cols, CV_8U);
std::bitset<bitl>* ptr1 = (std::bitset<bitl>*) (mat1.data + (rows - 1) * mat1.step[0]);
Mat mat2 = cv::Mat::zeros(rows, cols, CV_8U);
std::bitset<bitl>* ptr2 = (std::bitset<bitl>*) (mat2.data + (rows - 1) * mat2.step[0]);

ptr1->set(0, 0);
ptr2->set(0, 1);

std::cout << mat1 << std::endl << std::endl;
  std::cout << mat2 << std::endl << std::endl;

  matcher.match(mat1, mat2, matches);

  for (int i = 0; i < (int) matches.size(); i++ ) {
    std::cout << matches[i].distance << std::endl;
  }

  std::cout << std::endl << std::endl;

ptr1->set(0, 1);
ptr2->set(0, 0);

std::cout << mat1 << std::endl << std::endl;
  std::cout << mat2 << std::endl << std::endl;

  matcher.match(mat1, mat2, matches);

  for (int i = 0; i < (int) matches.size(); i++ ) {
    std::cout << matches[i].distance << std::endl;
  }

}

This gives the following output:

  [0, 0, 0;
  0, 0, 0]

[0, 0, 0;
  1, 0, 0]

0
0


[0, 0, 0;
  1, 0, 0]

[0, 0, 0;
  0, 0, 0]

0
1

which is, of course, nonsensical because the Hamming distance should be symmetric. Is there some subtlety in the way the Hamming matcher works that I am missing? Thank you all


EDIT: The example transferred to current OpenCV 2.4.9-version gives same output

const int rows = 2;
const int cols = 3;
const int bitl = cols * 8;

cv::BFMatcher matcher(cv::NORM_HAMMING);
std::vector<cv::DMatch> matches;

cv::Mat mat1 = cv::Mat::zeros(rows, cols, CV_8U);
cv::Mat mat2 = cv::Mat::zeros(rows, cols, CV_8U);

mat2.at<uchar>(1,0) = 1;
std::cout << mat1 << "\n\n" << mat2 << "\n\n";

matcher.match(mat1, mat2, matches);

for (size_t i = 0; i < matches.size(); i++ ) { 
    std::cout << matches[i].distance << std::endl;
}   

std::cout << std::endl << std::endl;

mat2.at<uchar>(1,0) = 0;
mat1.at<uchar>(1,0) = 1;
std::cout << mat1 << "\n\n" << mat2 << "\n\n";

matcher.match(mat1, mat2, matches);

for (size_t i = 0; i < matches.size(); i++ ) { 
    std::cout << matches[i].distance << std::endl;
}
click to hide/show revision 3
No.3 Revision

Problem with Hamming Matcher

I'm running into issues that lead me to believe that Hamming matcher is not working as expected (or at least, not as I expect). Consider the following code (please run it if you have the appropriate packages installed):

int main( int argc, char** argv ) {

const int rows = 2;
const int cols = 3;
const int bitl = cols * 8;

BruteForceMatcher<Hamming> matcher;
std::vector<DMatch> matches;

Mat mat1 = cv::Mat::zeros(rows, cols, CV_8U);
std::bitset<bitl>* ptr1 = (std::bitset<bitl>*) (mat1.data + (rows - 1) * mat1.step[0]);
Mat mat2 = cv::Mat::zeros(rows, cols, CV_8U);
std::bitset<bitl>* ptr2 = (std::bitset<bitl>*) (mat2.data + (rows - 1) * mat2.step[0]);

ptr1->set(0, 0);
ptr2->set(0, 1);

std::cout << mat1 << std::endl << std::endl;
  std::cout << mat2 << std::endl << std::endl;

  matcher.match(mat1, mat2, matches);

  for (int i = 0; i < (int) matches.size(); i++ ) {
    std::cout << matches[i].distance << std::endl;
  }

  std::cout << std::endl << std::endl;

 ptr1->set(0, 1);
 ptr2->set(0, 0);

 std::cout << mat1 << std::endl << std::endl;
  std::cout << mat2 << std::endl << std::endl;

  matcher.match(mat1, mat2, matches);

  for (int i = 0; i < (int) matches.size(); i++ ) {
    std::cout << matches[i].distance << std::endl;
  }
}

}

This gives the following output:

 [0, 0, 0;
  0, 0, 0]

[0, 0, 0;
 1, 0, 0]

0
0


[0, 0, 0;
 1, 0, 0]

[0, 0, 0;
 0, 0, 0]

0
1

which is, of course, nonsensical because the Hamming distance should be symmetric. Is there some subtlety in the way the Hamming matcher works that I am missing? Thank you all


EDIT: The example transferred to current OpenCV 2.4.9-version gives same output

const int rows = 2;
const int cols = 3;
const int bitl = cols * 8;

cv::BFMatcher matcher(cv::NORM_HAMMING);
std::vector<cv::DMatch> matches;

cv::Mat mat1 = cv::Mat::zeros(rows, cols, CV_8U);
cv::Mat mat2 = cv::Mat::zeros(rows, cols, CV_8U);

mat2.at<uchar>(1,0) = 1;
std::cout << mat1 << "\n\n" << mat2 << "\n\n";

matcher.match(mat1, mat2, matches);

for (size_t i = 0; i < matches.size(); i++ ) { 
    std::cout << matches[i].distance << std::endl;
}   

std::cout << std::endl << std::endl;

mat2.at<uchar>(1,0) = 0;
mat1.at<uchar>(1,0) = 1;
std::cout << mat1 << "\n\n" << mat2 << "\n\n";

matcher.match(mat1, mat2, matches);

for (size_t i = 0; i < matches.size(); i++ ) { 
    std::cout << matches[i].distance << std::endl;
}