// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #include "test_precomp.hpp" #include namespace opencv_test { namespace { using namespace cv::img_hash; /** *The expected results of this test case are come from the Phash library, *I use it as golden model */ class CV_BlockMeanHashTest : public cvtest::BaseTest { public: CV_BlockMeanHashTest(); protected: void run(int /* idx */); void testMeanMode0(); void testMeanMode1(); void testHashMode0(); void testHashMode1(); cv::Mat input; cv::Mat hash; Ptr bmh; }; CV_BlockMeanHashTest::CV_BlockMeanHashTest() { input.create(256, 256, CV_8U); for(int row = 0; row != input.rows; ++row) { uchar value = static_cast(row); for(int col = 0; col != input.cols; ++col) { input.at(row, col) = value++; } } bmh = BlockMeanHash::create(BLOCK_MEAN_HASH_MODE_0); } void CV_BlockMeanHashTest::testMeanMode0() { std::vector const &features = bmh->getMean(); double const expectResult[] = {15,31,47,63,79,95,111,127,143,159,175,191,207,223,239,135, 31,47,63,79,95,111,127,143,159,175,191,207,223,239,135,15, 47,63,79,95,111,127,143,159,175,191,207,223,239,135,15,31, 63,79,95,111,127,143,159,175,191,207,223,239,135,15,31,47, 79,95,111,127,143,159,175,191,207,223,239,135,15,31,47,63, 95,111,127,143,159,175,191,207,223,239,135,15,31,47,63,79, 111,127,143,159,175,191,207,223,239,135,15,31,47,63,79,95, 127,143,159,175,191,207,223,239,135,15,31,47,63,79,95,111, 143,159,175,191,207,223,239,135,15,31,47,63,79,95,111,127, 159,175,191,207,223,239,135,15,31,47,63,79,95,111,127,143, 175,191,207,223,239,135,15,31,47,63,79,95,111,127,143,159, 191,207,223,239,135,15,31,47,63,79,95,111,127,143,159,175, 207,223,239,135,15,31,47,63,79,95,111,127,143,159,175,191, 223,239,135,15,31,47,63,79,95,111,127,143,159,175,191,207, 239,135,15,31,47,63,79,95,111,127,143,159,175,191,207,223, 135,15,31,47,63,79,95,111,127,143,159,175,191,207,223,239,}; for(size_t i = 0; i != features.size(); ++i) { ASSERT_NEAR(features[i], expectResult[i], 0.0001); } } void CV_BlockMeanHashTest::testMeanMode1() { std::vector const &features = bmh->getMean(); double const expectResult[] = {15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135, 23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43, 31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15, 39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23, 47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31, 55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39, 63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47, 71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55, 79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63, 87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71, 95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79, 103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87, 111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95, 119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103, 127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111, 135,143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119, 143,151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127, 151,159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135, 159,167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143, 167,175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151, 175,183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159, 183,191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167, 191,199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175, 199,207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183, 207,215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191, 215,223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199, 223,231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207, 231,239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215, 239,219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223, 219,135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231, 135,43,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,}; for(size_t i = 0; i != features.size(); ++i) { ASSERT_NEAR(features[i], expectResult[i], 0.0001); } } void CV_BlockMeanHashTest::testHashMode0() { bool const expectResult[] = {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0, 0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0, 0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0, 0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0, 0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0, 0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1, 1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1, 1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1, 1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1, 1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1, 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1, }; for(int i = 0; i != hash.cols; ++i) { std::bitset<8> const bits = hash.at(0, i); for(size_t j = 0; j != bits.size(); ++j) { EXPECT_EQ(expectResult[i*8+j], bits[j]); } } } void CV_BlockMeanHashTest::testHashMode1() { bool const expectResult[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, }; for(int i = 0; i != hash.cols; ++i) { std::bitset<8> const bits = hash.at(0, i); if(i != hash.cols-1) { for(size_t j = 0; j != bits.size(); ++j) { EXPECT_EQ(expectResult[i*8+j], bits[j]); } } else { //when mode == 1, there will be 961 block mean //that is why we only check one bit at here EXPECT_EQ(expectResult[i*8], bits[0]); } } } void CV_BlockMeanHashTest::run(int) { bmh->compute(input, hash); testMeanMode0(); testHashMode0(); bmh->setMode(BLOCK_MEAN_HASH_MODE_1); bmh->compute(input, hash); testMeanMode1(); testHashMode1(); } TEST(block_mean_hash_test, accuracy) { CV_BlockMeanHashTest test; test.safe_run(); } }} // namespace