@thi.ng/tensors
Version:
0D/1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage
61 lines (60 loc) • 1.67 kB
JavaScript
import { cdf } from "./cdf.js";
import { defOpT } from "./defopt.js";
import { ensureShape } from "./errors.js";
import { findIndex } from "./find.js";
import { mulN } from "./muln.js";
import { tensor } from "./tensor.js";
const histogramUint = (src, depth, mask = (1 << depth) - 1, shift = 0) => {
const histType = src.length < 256 ? "u8" : src.length < 65536 ? "u16" : "u32";
const histogram = tensor(histType, [1 << depth]);
if (src.dim > 1) src = src.reshape([src.length]);
const {
offset: oa,
shape: [sa],
stride: [ta],
data: adata
} = src;
for (let i = 0; i < sa; i++)
histogram.data[adata[oa + i * ta] >>> shift & mask]++;
return histogram;
};
const equalizeHistogram = (out, src, depth, numSamples, threshold = 0) => {
!out && (out = src);
ensureShape(out, src.shape);
const norm = mulN(tensor("f64", [src.length]), src, 1 / numSamples);
const $cdf = cdf(null, norm);
const lo = findIndex($cdf, (x) => x > threshold);
if (lo < 0) return out.fill(0);
const {
offset: oc,
shape: [sc],
stride: [tc],
data: cdata
} = $cdf;
const {
offset: oo,
stride: [to],
data: odata
} = out;
const base = cdata[oc + lo * tc];
const scale = (2 ** depth - 1) / (cdata[oc + (sc - 1) * tc] - base);
for (let i = 0; i < sc; i++) {
odata[oo + i * to] = Math.max(0, scale * (cdata[oc + i * tc] - base));
}
return out;
};
const applyLUT = (out, a, lut) => {
!out && (out = a);
ensureShape(out, a.shape);
const {
offset: ol,
stride: [tl],
data: ldata
} = lut;
return defOpT((x) => ldata[ol + x * tl])(out, a);
};
export {
applyLUT,
equalizeHistogram,
histogramUint
};