Spaces:
Running
Running
File size: 2,159 Bytes
9fa1f67 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | import sharp from 'sharp'
const SAMPLE_SIZE = 32
const initSQRT = (N) => {
const c = new Array(N)
for (let i = 1; i < N; i++) {
c[i] = 1
}
c[0] = 1 / Math.sqrt(2.0)
return c
}
const SQRT = initSQRT(SAMPLE_SIZE)
const initCOS = (N) => {
const cosines = new Array(N)
for (let k = 0; k < N; k++) {
cosines[k] = new Array(N)
for (let n = 0; n < N; n++) {
cosines[k][n] = Math.cos(((2 * k + 1) / (2.0 * N)) * n * Math.PI)
}
}
return cosines
}
const COS = initCOS(SAMPLE_SIZE)
const applyDCT = (f, size) => {
var N = size
var F = new Array(N)
for (var u = 0; u < N; u++) {
F[u] = new Array(N)
for (var v = 0; v < N; v++) {
var sum = 0
for (var i = 0; i < N; i++) {
for (var j = 0; j < N; j++) {
sum += COS[i][u] * COS[j][v] * f[i][j]
}
}
sum *= (SQRT[u] * SQRT[v]) / 4
F[u][v] = sum
}
}
return F
}
const LOW_SIZE = 8
export const phash = async (image, options) => {
const data = await sharp(image, options)
.greyscale()
.resize(SAMPLE_SIZE, SAMPLE_SIZE, { fit: 'fill' })
.rotate()
.raw()
.toBuffer()
// copy signal
const s = new Array(SAMPLE_SIZE)
for (let x = 0; x < SAMPLE_SIZE; x++) {
s[x] = new Array(SAMPLE_SIZE)
for (let y = 0; y < SAMPLE_SIZE; y++) {
s[x][y] = data[SAMPLE_SIZE * y + x]
}
}
// apply 2D DCT II
const dct = applyDCT(s, SAMPLE_SIZE)
// get AVG on high frequencies
let totalSum = 0
for (let x = 0; x < LOW_SIZE; x++) {
for (let y = 0; y < LOW_SIZE; y++) {
totalSum += dct[x + 1][y + 1]
}
}
const avg = totalSum / (LOW_SIZE * LOW_SIZE)
// compute hash
let fingerprint = []
for (let x = 0; x < LOW_SIZE; x++) {
for (let y = 0; y < LOW_SIZE; y++) {
fingerprint.push(dct[x + 1][y + 1] > avg ? 1 : 0)
}
}
return parseInt(fingerprint.join(''), 2).toString(16)
}
export const distance = (a, b) => {
let count = 0
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
count++
}
}
return count
}
|