UNPKG

mind-ar

Version:

web augmented reality framework

111 lines (89 loc) 3.43 kB
import {engine} from '@tensorflow/tfjs'; const FREAK_EXPANSION_FACTOR = 7.0; const LAPLACIAN_THRESHOLD = 3.0; const LAPLACIAN_SQR_THRESHOLD = LAPLACIAN_THRESHOLD * LAPLACIAN_THRESHOLD; const EDGE_THRESHOLD = 4.0; const EDGE_HESSIAN_THRESHOLD = ((EDGE_THRESHOLD+1) * (EDGE_THRESHOLD+1) / EDGE_THRESHOLD); const cache={}; function GetProgram(image){ const imageWidth = image.shape[1]; const imageHeight = image.shape[0]; const kernelKey = 'w' + imageWidth + "h" + imageHeight; if(!cache.hasOwnProperty(kernelKey)){ const kernel = { variableNames: ['image0', 'image1', 'image2'], outputShape: [imageHeight, imageWidth], userCode: ` void main() { ivec2 coords = getOutputCoords(); int y = coords[0]; int x = coords[1]; float value = getImage1(y, x); // Step 1: find local maxima/minima if (value * value < ${LAPLACIAN_SQR_THRESHOLD}.) { setOutput(0.); return; } if (y < ${FREAK_EXPANSION_FACTOR} || y > ${imageHeight - 1 - FREAK_EXPANSION_FACTOR}) { setOutput(0.); return; } if (x < ${FREAK_EXPANSION_FACTOR} || x > ${imageWidth - 1 - FREAK_EXPANSION_FACTOR}) { setOutput(0.); return; } bool isMax = true; bool isMin = true; for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { float value0 = getImage0(y+dy, x+dx); float value1 = getImage1(y+dy, x+dx); float value2 = getImage2(y+dy, x+dx); if (value < value0 || value < value1 || value < value2) { isMax = false; } if (value > value0 || value > value1 || value > value2) { isMin = false; } } } if (!isMax && !isMin) { setOutput(0.); return; } // compute edge score and reject based on threshold float dxx = getImage1(y, x+1) + getImage1(y, x-1) - 2. * getImage1(y, x); float dyy = getImage1(y+1, x) + getImage1(y-1, x) - 2. * getImage1(y, x); float dxy = 0.25 * (getImage1(y-1,x-1) + getImage1(y+1,x+1) - getImage1(y-1,x+1) - getImage1(y+1,x-1)); float det = (dxx * dyy) - (dxy * dxy); if (abs(det) < 0.0001) { // determinant undefined. no solution setOutput(0.); return; } float edgeScore = (dxx + dyy) * (dxx + dyy) / det; if (abs(edgeScore) >= ${EDGE_HESSIAN_THRESHOLD} ) { setOutput(0.); return; } setOutput(getImage1(y,x)); } ` }; cache[kernelKey]=kernel; } return cache[kernelKey]; } export const buildExtremas=(args)=>{ let {image0,image1,image2}=args.inputs; /** @type {MathBackendWebGL} */ const backend = args.backend; const program=GetProgram(image1); image0=engine().runKernel('DownsampleBilinear',{image:image0}); image2=engine().runKernel('UpsampleBilinear',{image:image2,targetImage:image1}); return backend.runWebGLProgram(program,[image0,image1,image2],image1.dtype); } export const buildExtremasConfig = {//: KernelConfig kernelName: "BuildExtremas", backendName: 'webgl', kernelFunc: buildExtremas,// as {} as KernelFunc, };