We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http://dev.theomader.com/gaussian-kernel-calculator/ https://en.wikipedia.org/wiki/Gaussian_blur
var GaussianKernelCalculator = { init : function() { var gaussianDistribution = function(x, mu, sigma) { var d = x - mu; var n = 1.0 / (Math.sqrt(2 * Math.PI) * sigma); return Math.exp(-d*d/(2 * sigma * sigma)) * n; }; var sampleInterval = function(f, minInclusive, maxInclusive, sampleCount) { var result = []; var stepSize = (maxInclusive - minInclusive) / (sampleCount-1); for(var s=0; s<sampleCount; ++s) { var x = minInclusive + s * stepSize; var y = f(x); result.push([x, y]); } return result; }; var integrateSimphson = function(samples) { var result = samples[0][1] + samples[samples.length-1][1]; for(var s = 1; s < samples.length-1; ++s) { var sampleWeight = (s % 2 == 0) ? 2.0 : 4.0; result += sampleWeight * samples[s][1]; } var h = (samples[samples.length-1][0] - samples[0][0]) / (samples.length-1); return result * h / 3.0; }; var roundTo = function(num, decimals) { var shift = Math.pow(10, decimals); return Math.round(num * shift) / shift; }; var updateKernel = function(sigma, kernelSize, sampleCount) { var samplesPerBin = Math.ceil(sampleCount / kernelSize); if(samplesPerBin % 2 == 0) // need an even number of intervals for simpson integration => odd number of samples ++samplesPerBin; var weightSum = 0; var kernelLeft = -Math.floor(kernelSize/2); var calcSamplesForRange = function(minInclusive, maxInclusive) { return sampleInterval( function(x) { return gaussianDistribution(x, 0, sigma); }, minInclusive, maxInclusive, samplesPerBin ); } // get samples left and right of kernel support first var outsideSamplesLeft = calcSamplesForRange(-5 * sigma, kernelLeft - 0.5); var outsideSamplesRight = calcSamplesForRange(-kernelLeft+0.5, 5 * sigma); var allSamples = [[outsideSamplesLeft, 0]]; // now sample kernel taps and calculate tap weights for(var tap=0; tap<kernelSize; ++tap) { var left = kernelLeft - 0.5 + tap; var tapSamples = calcSamplesForRange(left, left+1); var tapWeight = integrateSimphson(tapSamples); allSamples.push([tapSamples, tapWeight]); weightSum += tapWeight; } allSamples.push([outsideSamplesRight, 0]); // renormalize kernel and round to 6 decimals for(var i=0; i<allSamples.length; ++i) { allSamples[i][1] = roundTo(allSamples[i][1] / weightSum, 6); } // update kernel weights tables var weightsTable1d = document.getElementById("GaussianKernelCalculator_kernelWeights1d"); var weightsTable2d = document.getElementById("GaussianKernelCalculator_kernelWeights2d"); var tableRow = "<tr>"; for(var i=1; i<allSamples.length-1; ++i) { tableRow += "<td>" + roundTo(allSamples[i][1], 6) + "</td>"; } tableRow += "</tr>" weightsTable1d.innerHTML = tableRow; var tableData = ""; for(var i=1; i<allSamples.length-1; ++i) { tableData += "<tr>"; for(var j=1; j<allSamples.length-1; ++j) { tableData += "<td>" + roundTo(allSamples[i][1] * allSamples[j][1], 6) + "</td>"; } tableData += "</tr>" } weightsTable2d.innerHTML = tableData; // area outside kernel Support var errorField = document.getElementById("GaussianKernelCalculator_approximationError"); errorField.innerHTML = roundTo((1.0 - weightSum) * 100.0, 2) + "%"; // Create and populate the data table. var chartData = new google.visualization.DataTable(); chartData.addColumn('number','Pixel'); chartData.addColumn('number','Continuous Distribution'); chartData.addColumn('number', 'Discrete Kernel'); for(var tap = 0; tap < allSamples.length; ++tap) { var tapSamples = allSamples[tap][0]; var tapWeight = allSamples[tap][1]; for(var s=0; s<tapSamples.length; ++s) { chartData.addRow([tapSamples[s][0], tapSamples[s][1], tapWeight]); } var lastRow = tapSamples[tapSamples.length-1]; chartData.addRow([lastRow[0], lastRow[1], 0]); } // finally draw the chart var chartOptions = { 'vAxis': {title: "Kernel Weight"}, 'hAxis': {title: "Pixel"}, 'seriesType': "area", 'series': {1: {type: "line"}}, }; var chart = new google.visualization.ChartWrapper( { chartType: 'ComboChart', dataTable: chartData, options: { 'vAxis': {title: "Kernel Weight"}, 'hAxis': {title: "Pixel"}, 'seriesType': "area", 'series': {1: {type: "line"}}, }, containerId: 'GaussianKernelCalculator_distributionChart' }); chart.draw(); }; var showKernel = function(show) { document.getElementById("GaussianKernelCalculator_result").style.display = show ? 'block' : 'none'; document.getElementById("GaussianKernelCalculator_inputError").style.display = show ? 'none' : 'block'; }; var updatePage = function() { var sigma = parseFloat(document.getElementById("GaussianKernelCalculator_sigma").value); var kernelSize = parseInt(document.getElementById("GaussianKernelCalculator_kernelSize").value); var sampleCount = 1000.0; showKernel(false); // parameter validation if(sigma<=0 || isNaN(sigma)) { document.getElementById("GaussianKernelCalculator_inputError").innerHTML = "Invalid Sigma: Please enter a positive number greater than zero"; } else if(kernelSize<=0 || isNaN(kernelSize) || kernelSize%2==0 || kernelSize>999) { document.getElementById("GaussianKernelCalculator_inputError").innerHTML = "Invalid Kernel Size: Please enter an odd positive integer smaller than 999"; } else { showKernel(true); updateKernel(sigma, kernelSize, sampleCount); } }; GaussianKernelCalculator.updatePage = updatePage; }, drawPrecomputedKernel : function() { var chartDataJSON= { "containerId":"GaussianKernelCalculator_distributionChart", "dataTable": { "cols":[ {"id":"","label":"Pixel","pattern":"","type":"number","p":{}}, {"id":"","label":"Continuous Distribution","pattern":"","type":"number","p":{}}, {"id":"","label":"Discrete Kernel","pattern":"","type":"number"} ], "rows":[ {"c":[{"v":-5,"f":null},{"v":0.0000014867195147342977,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-4.75,"f":null},{"v":0.000005029507288592445,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-4.5,"f":null},{"v":0.000015983741106905475,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-4.25,"f":null},{"v":0.00004771863654120495,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-4,"f":null},{"v":0.00013383022576488537,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-3.75,"f":null},{"v":0.0003525956823674454,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-3.5,"f":null},{"v":0.0008726826950457602,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-3.25,"f":null},{"v":0.002029048057299768,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-3,"f":null},{"v":0.0044318484119380075,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-2.75,"f":null},{"v":0.009093562501591053,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-2.5,"f":null},{"v":0.01752830049356854,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-2.5,"f":null},{"v":0.01752830049356854,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-2.5,"f":null},{"v":0.01752830049356854,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-2.4,"f":null},{"v":0.0223945302948429,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-2.3,"f":null},{"v":0.028327037741601186,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-2.2,"f":null},{"v":0.035474592846231424,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-2.1,"f":null},{"v":0.04398359598042719,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-2,"f":null},{"v":0.05399096651318806,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-1.9,"f":null},{"v":0.0656158147746766,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-1.7999999999999998,"f":null},{"v":0.07895015830089418,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-1.7,"f":null},{"v":0.09404907737688695,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-1.6,"f":null},{"v":0.11092083467945554,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-1.5,"f":null},{"v":0.12951759566589174,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":-1.5,"f":null},{"v":0.12951759566589174,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-1.5,"f":null},{"v":0.12951759566589174,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-1.4,"f":null},{"v":0.14972746563574488,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-1.3,"f":null},{"v":0.17136859204780736,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-1.2,"f":null},{"v":0.19418605498321295,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-1.1,"f":null},{"v":0.21785217703255053,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-1,"f":null},{"v":0.24197072451914337,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-0.8999999999999999,"f":null},{"v":0.26608524989875487,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-0.7999999999999999,"f":null},{"v":0.2896915527614828,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-0.7,"f":null},{"v":0.31225393336676127,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-0.6,"f":null},{"v":0.33322460289179967,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-0.5,"f":null},{"v":0.3520653267642995,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":-0.5,"f":null},{"v":0.3520653267642995,"f":null},{"v":0,"f":null}]}, {"c":[{"v":-0.5,"f":null},{"v":0.3520653267642995,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":-0.4,"f":null},{"v":0.36827014030332333,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":-0.3,"f":null},{"v":0.38138781546052414,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":-0.19999999999999996,"f":null},{"v":0.39104269397545594,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":-0.09999999999999998,"f":null},{"v":0.3969525474770118,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":0,"f":null},{"v":0.3989422804014327,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":0.10000000000000009,"f":null},{"v":0.3969525474770118,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":0.20000000000000007,"f":null},{"v":0.3910426939754559,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":0.30000000000000004,"f":null},{"v":0.3813878154605241,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":0.4,"f":null},{"v":0.36827014030332333,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":0.5,"f":null},{"v":0.3520653267642995,"f":null},{"v":0.387741,"f":null}]}, {"c":[{"v":0.5,"f":null},{"v":0.3520653267642995,"f":null},{"v":0,"f":null}]}, {"c":[{"v":0.5,"f":null},{"v":0.3520653267642995,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":0.6,"f":null},{"v":0.33322460289179967,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":0.7,"f":null},{"v":0.31225393336676127,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":0.8,"f":null},{"v":0.28969155276148273,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":0.9,"f":null},{"v":0.2660852498987548,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":1,"f":null},{"v":0.24197072451914337,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":1.1,"f":null},{"v":0.21785217703255053,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":1.2000000000000002,"f":null},{"v":0.19418605498321292,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":1.3,"f":null},{"v":0.17136859204780736,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":1.4,"f":null},{"v":0.14972746563574488,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":1.5,"f":null},{"v":0.12951759566589174,"f":null},{"v":0.24477,"f":null}]}, {"c":[{"v":1.5,"f":null},{"v":0.12951759566589174,"f":null},{"v":0,"f":null}]}, {"c":[{"v":1.5,"f":null},{"v":0.12951759566589174,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":1.6,"f":null},{"v":0.11092083467945554,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":1.7,"f":null},{"v":0.09404907737688695,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":1.8,"f":null},{"v":0.07895015830089415,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":1.9,"f":null},{"v":0.0656158147746766,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":2,"f":null},{"v":0.05399096651318806,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":2.1,"f":null},{"v":0.04398359598042719,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":2.2,"f":null},{"v":0.035474592846231424,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":2.3,"f":null},{"v":0.028327037741601186,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":2.4,"f":null},{"v":0.0223945302948429,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":2.5,"f":null},{"v":0.01752830049356854,"f":null},{"v":0.061359,"f":null}]}, {"c":[{"v":2.5,"f":null},{"v":0.01752830049356854,"f":null},{"v":0,"f":null}]}, {"c":[{"v":2.5,"f":null},{"v":0.01752830049356854,"f":null},{"v":0,"f":null}]}, {"c":[{"v":2.75,"f":null},{"v":0.009093562501591053,"f":null},{"v":0,"f":null}]}, {"c":[{"v":3,"f":null},{"v":0.0044318484119380075,"f":null},{"v":0,"f":null}]}, {"c":[{"v":3.25,"f":null},{"v":0.002029048057299768,"f":null},{"v":0,"f":null}]}, {"c":[{"v":3.5,"f":null},{"v":0.0008726826950457602,"f":null},{"v":0,"f":null}]}, {"c":[{"v":3.75,"f":null},{"v":0.0003525956823674454,"f":null},{"v":0,"f":null}]}, {"c":[{"v":4,"f":null},{"v":0.00013383022576488537,"f":null},{"v":0,"f":null}]}, {"c":[{"v":4.25,"f":null},{"v":0.00004771863654120495,"f":null},{"v":0,"f":null}]}, {"c":[{"v":4.5,"f":null},{"v":0.000015983741106905475,"f":null},{"v":0,"f":null}]}, {"c":[{"v":4.75,"f":null},{"v":0.000005029507288592445,"f":null},{"v":0,"f":null}]}, {"c":[{"v":5,"f":null},{"v":0.0000014867195147342977,"f":null},{"v":0,"f":null}]}, {"c":[{"v":5,"f":null},{"v":0.0000014867195147342977,"f":null},{"v":0,"f":null}]} ], "p":null }, "options":{ "vAxis":{"title":"Kernel Weight"}, "hAxis":{"title":"Pixel"}, "seriesType":"area", "series":{"1":{"type":"line"}} }, "state":{}, "isDefaultVisualization":true, "chartType":"ComboChart" }; var chart = new google.visualization.ChartWrapper(chartDataJSON); chart.draw(); } }; google.load('visualization', '1', {packages: ['corechart']}); google.setOnLoadCallback(function() { GaussianKernelCalculator.init(); // draw precalculated kernel to improve page loading times GaussianKernelCalculator.drawPrecomputedKernel(); });
The text was updated successfully, but these errors were encountered:
Son-Guhun
No branches or pull requests
http://dev.theomader.com/gaussian-kernel-calculator/
https://en.wikipedia.org/wiki/Gaussian_blur
The text was updated successfully, but these errors were encountered: