@thi.ng/tensors
Version:
0D/1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage
118 lines (117 loc) • 2.3 kB
JavaScript
import { identity } from "@thi.ng/api/fn";
import { constant, tensor } from "./tensor.js";
const SOBEL1 = tensor([-1, 0, 1]);
const SOBEL2 = tensor([
[-1, -2, -1],
[0, 0, 0],
[1, 2, 1]
]);
const SOBEL3 = tensor([
[
[-1, -2, -1],
[-2, -4, -2],
[-1, -2, -1]
],
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
],
[
[1, 2, 1],
[2, 4, 2],
[1, 2, 1]
]
]);
const EDGE2 = (r) => {
r |= 0;
const w = 2 * r + 1;
const data = new Array(w * w).fill(-1);
data[data.length >> 1] = w * w - 1;
return tensor("num", [w, w], { data, copy: false });
};
const SHARPEN2_3x3 = tensor([
[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]
]);
const BOX_BLUR2 = (r) => {
r = 2 * r + 1;
return constant([r, r], 1 / (r * r), "num");
};
const GAUSSIAN_BLUR2 = (r) => {
r |= 0;
const sigma = -1 / (2 * (Math.SQRT2 * r / 3) ** 2);
const res = [];
let sum = 0;
for (let y = -r; y <= r; y++) {
for (let x = -r; x <= r; x++) {
const g = Math.exp((x * x + y * y) * sigma);
res.push(g);
sum += g;
}
}
const size = r * 2 + 1;
return tensor("num", [size, size], {
data: res.map((x) => x / sum),
copy: false
});
};
const { max, min } = Math;
const MAX2_POOL = (w, h = w) => {
return {
shape: [w, h],
init: () => -Infinity,
reduce: (acc, val) => max(acc, val),
complete: identity
};
};
const MIN2_POOL = (w, h = w) => {
return {
shape: [w, h],
init: () => Infinity,
reduce: (acc, val) => min(acc, val),
complete: identity
};
};
const MAXIMA2 = (r) => {
r |= 0;
const w = 2 * r + 1;
return {
shape: [w, w],
init: () => [-Infinity, 0],
reduce: (acc, val, i, j) => {
if (i === r && j === r) acc[1] = val;
else acc[0] = max(acc[0], val);
return acc;
},
complete: (acc) => acc[1] > acc[0] ? 1 : 0
};
};
const MINIMA2 = (r) => {
r |= 0;
const w = 2 * r + 1;
return {
shape: [w, w],
init: () => [Infinity, 0],
reduce: (acc, val, i, j) => {
if (i === r && j === r) acc[1] = val;
else acc[0] = min(acc[0], val);
return acc;
},
complete: (acc) => acc[1] < acc[0] ? 1 : 0
};
};
export {
BOX_BLUR2,
EDGE2,
GAUSSIAN_BLUR2,
MAX2_POOL,
MAXIMA2,
MIN2_POOL,
MINIMA2,
SHARPEN2_3x3,
SOBEL1,
SOBEL2,
SOBEL3
};