Published
Edited
Mar 28, 2022
1 star
Insert cell
md`# gpu.js laser detection v2`
Insert cell
GPU = (await require('gpu.js@2.15.2')).GPU
Insert cell
canvas = document.createElement('canvas');
Insert cell
canvas2 = document.createElement('canvas');
Insert cell
gpu = new GPU({ mode: 'gpu', canvas })
Insert cell
function rgb2hsv(r, g, b) {
let rr = 0, gg = 0, bb = 0,
h = 0, s = 0;
let v = Math.max(r, g);
v = Math.max(v, b);
let minv = Math.min(r, g);
minv = Math.min(minv, b);
let diff = v - minv;

function diffc(c, v, diff) {
return (v - c) / 6 / diff + 1 / 2;
}

if (diff == 0) {
h = s = 0;
} else {
s = diff / v;
rr = diffc(r, v, diff);
gg = diffc(g, v, diff);
bb = diffc(b, v, diff);

if (r === v) {
h = bb - gg;
} else if (g === v) {
h = (1 / 3) + rr - bb;
} else if (b === v) {
h = (2 / 3) + gg - rr;
}
if (h < 0) {
h += 1;
} else if (h > 1) {
h -= 1;
}
}
return [Math.round(h * 360), Math.round(s * 100), Math.round(v * 100)];
}
Insert cell
gpu.addFunction(rgb2hsv, { returnType: 'Array(3)' }); // { returnType: 'Array(3)' }
Insert cell
function imageKernel(width, height) {
let kernel = gpu.createKernel(function(image) {
const pixel = image[this.thread.y][this.thread.x];

const hsv = rgb2hsv(pixel[0], pixel[1], pixel[2])

const h = hsv[0];
const s = hsv[1];
const v = hsv[2];

// if (this.thread.x >= 419 && this.thread.x <= 438 &&
// this.thread.y >= 510 && this.thread.y <= 526)
if (this.thread.x >= 309 && this.thread.x <= 328 && this.thread.y >= 335 && this.thread.y <= 355) {
// this.color(1, 1, 0, 1);

// console.log(pixel[0] * 255, pixel[1] * 255, pixel[2] * 255)
// console.log([pixel[0], pixel[1], pixel[2], pixel[3]]);
// console.log(h, s, v);
}

// hue_min=20, hue_max=160,
// sat_min=100, sat_max=255, val_min=200, val_max=256,
if (
// h >= 20 && h <= 160 &&
s >= 0 && s <= 100 &&
v >= 78 && v <= 100 &&
h >= 318
) {
// this.color(pixel[0], pixel[1], pixel[2], pixel[3]);
this.color(0, 1, 0, 1);
// } else if (this.thread.x >= 309 && this.thread.x <= 328 && this.thread.y >= 335 && this.thread.y <= 355) {
// this.color(1, 1, 0, 1);
return 1;
} else {
this.color(pixel[0], pixel[1], pixel[2], pixel[3]);
return 0;
}
})
// .setGraphical(true)
.setOutput([width, height]);
return kernel;
}
Insert cell
function boxKernel(width, height) {
let kernel = gpu.createKernel(function(image) {
})
.setOutput([width, height]);
return kernel;
}
Insert cell
{
let img = document.createElement('img');
let canvas
img.crossOrigin = ""
img.onload = function() {
// Scale down image
// img.height = parseInt(img.height / 2, 10);
// img.width = parseInt(img.width / 2, 10); // Comment out if returning below
console.log(img.width, img.height)
let kernel = imageKernel(img.width, img.height)
// let kernel2 = boxKernel(img.width, img.height)
console.log('running!')
let start = window.performance.now()
let out = kernel(img)
// console.log(out);
console.log('Size', out.length, out[0].length);
// Out is an array of Float32Arrays that is height x width (height first, i.e. Array is `height` in length)
const dots = [];
let minx = img.width;
let miny = img.height;
let maxx = 0;
let maxy = 0;
for (let y = 0; y <= out.length-1; y++) {
const arr = out[y];
for (let x = 0; x <= arr.length-1; x++) {
if (arr[x] == 1) {
if (x < minx) minx = x;
if (x > maxx) maxx = x;
if (y < miny) miny = y;
if (y > maxy) maxy = y;
}
}
}
// Inverse
miny = img.height - miny;
maxy = img.height - maxy;
console.log([minx, miny], [maxx, maxy]);
let boxSize = Math.max(maxx - minx, maxy - miny);
let stop = window.performance.now()
console.log('Took', stop - start);
canvas2.width = img.width;
canvas2.height = img.height;
const ctx = canvas2.getContext("2d");
ctx.drawImage(img, 0, 0);
console.log(canvas);
ctx.beginPath();
const mid = (a, b) => ((b - a) / 2) + a;
ctx.arc(mid(minx, maxx), mid(miny, maxy), boxSize, 0, 2 * Math.PI);
ctx.strokeStyle = 'yellow';
ctx.stroke();
}
// img.src = 'https://i.imgur.com/qb1ywMq.jpg'
// img.src = 'https://i.imgur.com/eLpI3sN.jpg'
// img.src = 'https://i.imgur.com/q4t1tgb.jpg'
// img.src = 'https://i.imgur.com/QKgG5vT.jpg'
img.src = 'https://i.imgur.com/QOyFPcN.jpg'
// return img
}
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