Published
Edited
Dec 11, 2020
Insert cell
Insert cell
Insert cell
Insert cell
// (* S has items to sample, R will contain the result *)
// ReservoirSample(S[1..n], R[1..k])
// // fill the reservoir array
// for i = 1 to k
// R[i] := S[i]
// (* random() generates a uniform (0,1) random number *)
// W := exp(log(random())/k)
// while i <= n
// i := i + floor(log(random())/log(1-W)) + 1
// if i <= n
// (* replace a random item of the reservoir with item i *)
// R[randomInteger(1,k)] := S[i] // random index between 1 and k, inclusive
// W := W * exp(log(random())/k)
Insert cell
video
Insert cell
reservoir = await fillReservoir({ video, k })
Insert cell
Insert cell
function median(values) {
if (!(n = values.length)) return;
if (n < 2) return d3.min(values);
var n,
i = (n - 1) * 0.5,
i0 = Math.floor(i),
value0 = d3.max(d3.quickselect(values, i0).subarray(0, i0 + 1)),
value1 = d3.min(values.subarray(i0 + 1));
return value0 + (value1 - value0) * (i - i0);
}
Insert cell
function canvasMedian(canvases) {
// TODO: optimize - see https://stackoverflow.com/questions/65224990/efficient-way-to-compute-the-median-of-an-array-of-canvas-in-javascript
const width = canvases[0].width;
const height = canvases[0].height;
const imageDatas = canvases.map(
canvas => canvas.getContext('2d').getImageData(0, 0, width, height).data
);
const medianImageData = new ImageData(width, height);
const arr = new Uint8ClampedArray(imageDatas.length);

for (let i = 0; i < medianImageData.data.length; i += 1) {
for (let j = 0; j < imageDatas.length; j += 1) {
arr[j] = imageDatas[j][i];
}
medianImageData.data[i] = median(arr);
}

const medianCanvas = html`<canvas width="${width}" height="${height}"></canvas>`;
medianCanvas.getContext('2d').putImageData(medianImageData, 0, 0);
return medianCanvas;
}
Insert cell
canvasMedian(reservoir)
Insert cell
reservoir[0]
.getContext('2d')
.getImageData(0, 0, video.videoWidth, video.videoHeight).data
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more