UNPKG

image-js

Version:

Image processing and manipulation in JavaScript

86 lines (75 loc) 2.39 kB
import newArray from 'new-array'; import { validateArrayOfChannels } from '../../util/channel'; /** * Try to match the current pictures with another one. If normalize we normalize separately the 2 images. * @memberof Image * @instance * @param {Image} image - Other image * @param {object} [options] * @return {number[]|number} */ export default function getSimilarity(image, options = {}) { let { shift = [0, 0], average, channels, defaultAlpha, normalize, border = [0, 0], } = options; this.checkProcessable('getSimilarity', { bitDepth: [8, 16], }); if (!Array.isArray(border)) { border = [border, border]; } channels = validateArrayOfChannels(this, { channels: channels, defaultAlpha: defaultAlpha, }); if (this.bitDepth !== image.bitDepth) { throw new Error('Both images must have the same bitDepth'); } if (this.channels !== image.channels) { throw new Error('Both images must have the same number of channels'); } if (this.colorModel !== image.colorModel) { throw new Error('Both images must have the same colorModel'); } if (typeof average === 'undefined') { average = true; } // we allow a shift // we need to find the minX, maxX, minY, maxY let minX = Math.max(border[0], -shift[0]); let maxX = Math.min(this.width - border[0], this.width - shift[0]); let minY = Math.max(border[1], -shift[1]); let maxY = Math.min(this.height - border[1], this.height - shift[1]); let results = newArray(channels.length, 0); for (let i = 0; i < channels.length; i++) { let c = channels[i]; let sumThis = normalize ? this.sum[c] : Math.max(this.sum[c], image.sum[c]); let sumImage = normalize ? image.sum[c] : Math.max(this.sum[c], image.sum[c]); if (sumThis !== 0 && sumImage !== 0) { for (let x = minX; x < maxX; x++) { for (let y = minY; y < maxY; y++) { let indexThis = x * this.multiplierX + y * this.multiplierY + c; let indexImage = indexThis + shift[0] * this.multiplierX + shift[1] * this.multiplierY; results[i] += Math.min( this.data[indexThis] / sumThis, image.data[indexImage] / sumImage, ); } } } } if (average) { return results.reduce((sum, x) => sum + x) / results.length; } return results; }