Skip to content

Commit

Permalink
Changes to average_hash...
Browse files Browse the repository at this point in the history
Tests will be broken.

`special_case_fuzzy_ahash()` is an optimization that's no longer used --
this change is unecessary, but preserved for posterity. (I'll delete the
function and tests shortly)
  • Loading branch information
sz3 committed Jun 1, 2023
1 parent e2cab43 commit ec62980
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 26 deletions.
12 changes: 7 additions & 5 deletions src/lib/bit_file/bitmatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ class bitmatrix
unsigned size = img.cols * img.rows;
while (size >= 8)
{
// we're turning 1 uint64_t into 8 uint8_ts
const uint64_t* hax = reinterpret_cast<const uint64_t*>(p);
uint64_t mval = (*hax) & 0x101010101010101ULL;
const uint8_t* cv = reinterpret_cast<const uint8_t*>(&mval);
// TODO: what about endianness???
uint8_t val = cv[0] << 7 | cv[1] << 6 | cv[2] << 5 | cv[3] << 4 | cv[4] << 3 | cv[5] << 2 | cv[6] << 1 | cv[7];
writer << val;
p += 8;
Expand All @@ -39,11 +41,11 @@ class bitmatrix

public:
bitmatrix(const bitbuffer& buff, unsigned width, unsigned height, unsigned xstart=0, unsigned ystart=0)
: _buff(buff)
, _xstart(xstart)
, _ystart(ystart)
, _width(width)
, _height(height)
: _buff(buff)
, _xstart(xstart)
, _ystart(ystart)
, _width(width)
, _height(height)
{
}

Expand Down
47 changes: 26 additions & 21 deletions src/lib/image_hash/average_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,28 @@ namespace image_hash

inline ahash_result special_case_fuzzy_ahash(const cv::Mat& gray, unsigned mode)
{
// if the Mat is already 10x10 and threshold'd to (0, 0xFF), we can do some things...
// assert gray.rows == gray.cols?
// if the Mat is already 7x7 and threshold'd to (0, 0xFF), we can do some things...
intx::uint128 res(0);
int bitpos = 95; // 10*10 - 5
for (int i = 0; i < gray.rows; ++i)
int bitpos = 42; // gray.rows*gray.cols - gray.cols == 7*7 - 7
for (int i = 0; i < gray.rows; ++i, bitpos-=gray.cols)
{
// review -- but I think we're doing this in chunks of 5 because we *can't* do 10
// with our new constraints (max size == 8), we can slighly simplify this I think?
// just always mask by 8...
const uchar* p = gray.ptr<uchar>(i);
for (int j = 0; j < gray.cols; j+=5, bitpos-=5)
{
const uint64_t* hax = reinterpret_cast<const uint64_t*>(p+j);
uint64_t mval = (*hax) & 0x101010101ULL;
const uint8_t* cv = reinterpret_cast<const uint8_t*>(&mval);
uint8_t val = cv[0] << 4 | cv[1] << 3 | cv[2] << 2 | cv[3] << 1 | cv[4];
// TODO:
/*if (bigEndian)
val = cv[7] << 4 | cv[6] << 3 | cv[5] << 2 | cv[4] << 1 | cv[3];*/ // ?

res |= intx::uint128(val) << bitpos;
}
// we're turning 1 uint64_t into <=8 uint8_ts
const uint64_t* hax = reinterpret_cast<const uint64_t*>(p);
uint64_t mval = (*hax) & 0x101010101010101ULL;
const uint8_t* cv = reinterpret_cast<const uint8_t*>(&mval);
// and then reconstructing the uchars into a single uint8_t
uint8_t val = cv[0] << 6 | cv[1] << 5 | cv[2] << 4 | cv[3] << 3 | cv[4] << 2 | cv[5] << 1 | cv[6];
// TODO:
/*if (bigEndian)
val = cv[7] << 4 | cv[6] << 3 | cv[5] << 2 | cv[4] << 1 | cv[3];*/ // ?

res |= intx::uint128(val) << bitpos;
}
return ahash_result(res, mode);
}
Expand All @@ -71,20 +75,20 @@ namespace image_hash
// ... e.g. if we have 8 params, that means it's a 64 bit number being returned.
inline ahash_result fuzzy_ahash(const cv::Mat& img, uchar threshold=0, unsigned mode=ahash_result::ALL)
{
// return 9 uint64_ts, each representing an 8x8 section of the 10x10 img
// return 9 uint64_ts, each representing an 5x5 section of the 7x7 img
cv::Mat gray = img;
if (img.channels() != 1)
cv::cvtColor(gray, gray, cv::COLOR_RGB2GRAY);
if (gray.cols != 10 or gray.rows != 10)
cv::resize(gray, gray, cv::Size(10, 10));
if (gray.cols > 8 or gray.rows > 8)
cv::resize(gray, gray, cv::Size(8, 8));

if (threshold == 0)
threshold = Cell(gray).mean_grayscale();
else if (threshold == 0xFF)
return special_case_fuzzy_ahash(gray, mode);

intx::uint128 res(0);
int bitpos = 99; // 10*10 - 1
int bitpos = gray.cols * gray.rows - 1; // 10*10 - 1
for (int i = 0; i < gray.rows; ++i)
{
const uchar* p = gray.ptr<uchar>(i);
Expand All @@ -96,11 +100,12 @@ namespace image_hash

inline ahash_result fuzzy_ahash(const bitmatrix& img, unsigned mode=ahash_result::ALL)
{
static const int STARTPOS = img.height()*img.width() - img.width(); // 7*7 - 7
intx::uint128 res(0);
int bitpos = 90; // 10*10 - 10
for (int i = 0; i < 10; ++i, bitpos-=10)
int bitpos = STARTPOS;
for (unsigned i = 0; i < img.height(); ++i, bitpos-=static_cast<int>(img.width()))
{
unsigned r = img.get(0, i, 10);
unsigned r = img.get(0, i, img.width());
res |= intx::uint128(r) << bitpos;
}
return ahash_result(res, mode);
Expand Down

0 comments on commit ec62980

Please sign in to comment.