average_hash.cpp 2.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
// 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 "precomp.hpp"

using namespace cv;
using namespace std;
using namespace img_hash;

namespace {

13
class AverageHashImpl CV_FINAL : public ImgHashBase::ImgHashImpl
14 15 16 17 18 19 20 21
{
private:
    cv::Mat bitsImg;
    cv::Mat grayImg;
    cv::Mat resizeImg;

public:

22
    virtual void compute(cv::InputArray inputArr, cv::OutputArray outputArr) CV_OVERRIDE
23 24 25 26 27 28
    {
        cv::Mat const input = inputArr.getMat();
        CV_Assert(input.type() == CV_8UC4 ||
                  input.type() == CV_8UC3 ||
                  input.type() == CV_8U);

29
        cv::resize(input, resizeImg, cv::Size(8,8), 0, 0, INTER_LINEAR_EXACT);
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
        if(input.type() == CV_8UC3)
        {
            cv::cvtColor(resizeImg, grayImg, CV_BGR2GRAY);
        }
        else if(input.type() == CV_8UC4)
        {
            cv::cvtColor(resizeImg, grayImg, CV_BGRA2GRAY);
        }
        else
        {
            grayImg = resizeImg;
        }

        uchar const imgMean = static_cast<uchar>(cvRound(cv::mean(grayImg)[0]));
        cv::compare(grayImg, imgMean, bitsImg, CMP_GT);
        bitsImg /= 255;
        outputArr.create(1, 8, CV_8U);
        cv::Mat hash = outputArr.getMat();
        uchar *hash_ptr = hash.ptr<uchar>(0);
        uchar const *bits_ptr = bitsImg.ptr<uchar>(0);
        std::bitset<8> bits;
        for(size_t i = 0, j = 0; i != bitsImg.total(); ++j)
        {
            for(size_t k = 0; k != 8; ++k)
            {
                //avoid warning C4800, casting do not work
                bits[k] = bits_ptr[i++] != 0;
            }
            hash_ptr[j] = static_cast<uchar>(bits.to_ulong());
        }
    }

62
    virtual double compare(cv::InputArray hashOne, cv::InputArray hashTwo) const CV_OVERRIDE
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
    {
        return norm(hashOne, hashTwo, NORM_HAMMING);
    }
};

} // namespace::

//==================================================================================================

namespace cv { namespace img_hash {

Ptr<AverageHash> AverageHash::create()
{
    Ptr<AverageHash> res(new AverageHash());
    res->pImpl = makePtr<AverageHashImpl>();
    return res;
}

void averageHash(cv::InputArray inputArr, cv::OutputArray outputArr)
{
    AverageHashImpl().compute(inputArr, outputArr);
}

}} // cv::img_hash::