123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- <!DOCTYPE html>
- <html >
- <head>
- <meta charset="utf-8">
- <title>Image Processing Video Example</title>
- <link href="js_example_style.css" rel="stylesheet" type="text/css" />
- <style type="text/css">
- .dg {
- text-align: left;
- }
- .dg .property-name {
- font: 11px Lucida Grande,sans-serif;
- line-height: 27px;
- }
- .dg.main .close-button {
- font: 11px Lucida Grande,sans-serif;
- line-height: 27px;
- }
- .cell-top {
- vertical-align: top;
- }
- </style>
- </head>
- <body>
- <h2>Image Processing Video Example</h2>
- <p>
- Open the controls and try different image processing filters.
- </p>
- <p class="err" id="errorMessage"></p>
- <div id="container">
- <table>
- <tr>
- <td></td>
- <td>
- <div>
- <span>Current Filter: </span><span id="filterName">Pass Through</span>
- </div>
- </td>
- <td>
- <div>Select Filter:</div>
- </td>
- <td></td>
- </tr>
- <tr>
- <td></td>
- <td class="cell-top">
- <canvas id="canvasOutput" width="640" height="480"></canvas>
- </td>
- <td class="cell-top">
- <div id="guiContainer"></div>
- </td>
- <td></td>
- </tr>
- </table>
- <div>
- <video id="videoInput" class="hidden">Your browser does not support the video tag.</video>
- </div>
- </div>
- <script src="https://webrtc.github.io/adapter/adapter-5.0.4.js" type="text/javascript"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js" type="text/javascript"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.4/dat.gui.min.js" type="text/javascript"></script>
- <script src="utils.js" type="text/javascript"></script>
- <script type="text/javascript">
- let utils = new Utils('errorMessage');
- let width = 0;
- let height = 0;
- let resolution = window.innerWidth < 960 ? 'qvga' : 'vga';
- // whether streaming video from the camera.
- let streaming = false;
- let video = document.getElementById('videoInput');
- let vc = null;
- let container = document.getElementById('container');
- let lastFilter = '';
- let src = null;
- let dstC1 = null;
- let dstC3 = null;
- let dstC4 = null;
- function startVideoProcessing() {
- src = new cv.Mat(height, width, cv.CV_8UC4);
- dstC1 = new cv.Mat(height, width, cv.CV_8UC1);
- dstC3 = new cv.Mat(height, width, cv.CV_8UC3);
- dstC4 = new cv.Mat(height, width, cv.CV_8UC4);
- requestAnimationFrame(processVideo);
- }
- function passThrough(src) {
- return src;
- }
- function gray(src) {
- cv.cvtColor(src, dstC1, cv.COLOR_RGBA2GRAY);
- return dstC1;
- }
- function hsv(src) {
- cv.cvtColor(src, dstC3, cv.COLOR_RGBA2RGB);
- cv.cvtColor(dstC3, dstC3, cv.COLOR_RGB2HSV);
- return dstC3;
- }
- function canny(src) {
- cv.cvtColor(src, dstC1, cv.COLOR_RGBA2GRAY);
- cv.Canny(dstC1, dstC1, controls.cannyThreshold1, controls.cannyThreshold2,
- controls.cannyApertureSize, controls.cannyL2Gradient);
- return dstC1;
- }
- function inRange(src) {
- let lowValue = controls.inRangeLow;
- let lowScalar = new cv.Scalar(lowValue, lowValue, lowValue, 255);
- let highValue = controls.inRangeHigh;
- let highScalar = new cv.Scalar(highValue, highValue, highValue, 255);
- let low = new cv.Mat(height, width, src.type(), lowScalar);
- let high = new cv.Mat(height, width, src.type(), highScalar);
- cv.inRange(src, low, high, dstC1);
- low.delete(); high.delete();
- return dstC1;
- }
- function threshold(src) {
- cv.threshold(src, dstC4, controls.thresholdValue, 200, cv.THRESH_BINARY);
- return dstC4;
- }
- function adaptiveThreshold(src) {
- let mat = new cv.Mat(height, width, cv.CV_8U);
- cv.cvtColor(src, mat, cv.COLOR_RGBA2GRAY);
- cv.adaptiveThreshold(mat, dstC1, 200, cv.ADAPTIVE_THRESH_GAUSSIAN_C,
- cv.THRESH_BINARY, Number(controls.adaptiveBlockSize), 2);
- mat.delete();
- return dstC1;
- }
- function gaussianBlur(src) {
- cv.GaussianBlur(src, dstC4,
- {width: controls.gaussianBlurSize, height: controls.gaussianBlurSize},
- 0, 0, cv.BORDER_DEFAULT);
- return dstC4;
- }
- function bilateralFilter(src) {
- let mat = new cv.Mat(height, width, cv.CV_8UC3);
- cv.cvtColor(src, mat, cv.COLOR_RGBA2RGB);
- cv.bilateralFilter(mat, dstC3, controls.bilateralFilterDiameter, controls.bilateralFilterSigma,
- controls.bilateralFilterSigma, cv.BORDER_DEFAULT);
- mat.delete();
- return dstC3;
- }
- function medianBlur(src) {
- cv.medianBlur(src, dstC4, controls.medianBlurSize);
- return dstC4;
- }
- function sobel(src) {
- let mat = new cv.Mat(height, width, cv.CV_8UC1);
- cv.cvtColor(src, mat, cv.COLOR_RGB2GRAY, 0);
- cv.Sobel(mat, dstC1, cv.CV_8U, 1, 0, controls.sobelSize, 1, 0, cv.BORDER_DEFAULT);
- mat.delete();
- return dstC1;
- }
- function scharr(src) {
- let mat = new cv.Mat(height, width, cv.CV_8UC1);
- cv.cvtColor(src, mat, cv.COLOR_RGB2GRAY, 0);
- cv.Scharr(mat, dstC1, cv.CV_8U, 1, 0, 1, 0, cv.BORDER_DEFAULT);
- mat.delete();
- return dstC1;
- }
- function laplacian(src) {
- let mat = new cv.Mat(height, width, cv.CV_8UC1);
- cv.cvtColor(src, mat, cv.COLOR_RGB2GRAY);
- cv.Laplacian(mat, dstC1, cv.CV_8U, controls.laplacianSize, 1, 0, cv.BORDER_DEFAULT);
- mat.delete();
- return dstC1;
- }
- let contoursColor = [];
- for (let i = 0; i < 10000; i++) {
- contoursColor.push([Math.round(Math.random() * 255),
- Math.round(Math.random() * 255),
- Math.round(Math.random() * 255), 0]);
- }
- function contours(src) {
- cv.cvtColor(src, dstC1, cv.COLOR_RGBA2GRAY);
- cv.threshold(dstC1, dstC4, 120, 200, cv.THRESH_BINARY);
- let contours = new cv.MatVector();
- let hierarchy = new cv.Mat();
- cv.findContours(dstC4, contours, hierarchy,
- Number(controls.contoursMode),
- Number(controls.contoursMethod), {x: 0, y: 0});
- dstC3.delete();
- dstC3 = cv.Mat.ones(height, width, cv.CV_8UC3);
- for (let i = 0; i<contours.size(); ++i) {
- let color = contoursColor[i];
- cv.drawContours(dstC3, contours, i, color, 1, cv.LINE_8, hierarchy);
- }
- contours.delete(); hierarchy.delete();
- return dstC3;
- }
- function calcHist(src) {
- cv.cvtColor(src, dstC1, cv.COLOR_RGBA2GRAY);
- let srcVec = new cv.MatVector();
- srcVec.push_back(dstC1);
- let scale = 2;
- let channels = [0];
- let histSize = [src.cols/scale];
- const ranges = [0, 255];
- let hist = new cv.Mat();
- let mask = new cv.Mat();
- let color = new cv.Scalar(0xfb, 0xca, 0x04, 0xff);
- cv.calcHist(srcVec, channels, mask, hist, histSize, ranges);
- let result = cv.minMaxLoc(hist, mask);
- let max = result.maxVal;
- cv.cvtColor(dstC1, dstC4, cv.COLOR_GRAY2RGBA);
- // draw histogram on src
- for (let i = 0; i < histSize[0]; i++) {
- let binVal = hist.data32F[i] * src.rows / max;
- cv.rectangle(dstC4, {x: i * scale, y: src.rows - 1},
- {x: (i + 1) * scale - 1, y: src.rows - binVal/3}, color, cv.FILLED);
- }
- srcVec.delete();
- mask.delete();
- hist.delete();
- return dstC4;
- }
- function equalizeHist(src) {
- cv.cvtColor(src, dstC1, cv.COLOR_RGBA2GRAY, 0);
- cv.equalizeHist(dstC1, dstC1);
- return dstC1;
- }
- let base;
- function backprojection(src) {
- if (lastFilter !== 'backprojection') {
- if (base instanceof cv.Mat) {
- base.delete();
- }
- base = src.clone();
- cv.cvtColor(base, base, cv.COLOR_RGB2HSV, 0);
- }
- cv.cvtColor(src, dstC3, cv.COLOR_RGB2HSV, 0);
- let baseVec = new cv.MatVector();
- let targetVec = new cv.MatVector();
- baseVec.push_back(base); targetVec.push_back(dstC3);
- let mask = new cv.Mat();
- let hist = new cv.Mat();
- let channels = [0];
- let histSize = [50];
- let ranges;
- if (controls.backprojectionRangeLow < controls.backprojectionRangeHigh) {
- ranges = [controls.backprojectionRangeLow, controls.backprojectionRangeHigh];
- } else {
- return src;
- }
- cv.calcHist(baseVec, channels, mask, hist, histSize, ranges);
- cv.normalize(hist, hist, 0, 255, cv.NORM_MINMAX);
- cv.calcBackProject(targetVec, channels, hist, dstC1, ranges, 1);
- baseVec.delete();
- targetVec.delete();
- mask.delete();
- hist.delete();
- return dstC1;
- }
- function erosion(src) {
- let kernelSize = controls.erosionSize;
- let kernel = cv.Mat.ones(kernelSize, kernelSize, cv.CV_8U);
- let color = new cv.Scalar();
- cv.erode(src, dstC4, kernel, {x: -1, y: -1}, 1, Number(controls.erosionBorderType), color);
- kernel.delete();
- return dstC4;
- }
- function dilation(src) {
- let kernelSize = controls.dilationSize;
- let kernel = cv.Mat.ones(kernelSize, kernelSize, cv.CV_8U);
- let color = new cv.Scalar();
- cv.dilate(src, dstC4, kernel, {x: -1, y: -1}, 1, Number(controls.dilationBorderType), color);
- kernel.delete();
- return dstC4;
- }
- function morphology(src) {
- let kernelSize = controls.morphologySize;
- let kernel = cv.getStructuringElement(Number(controls.morphologyShape),
- {width: kernelSize, height: kernelSize});
- let color = new cv.Scalar();
- let op = Number(controls.morphologyOp);
- let image = src;
- if (op === cv.MORPH_GRADIENT || op === cv.MORPH_TOPHAT || op === cv.MORPH_BLACKHAT) {
- cv.cvtColor(src, dstC3, cv.COLOR_RGBA2RGB);
- image = dstC3;
- }
- cv.morphologyEx(image, dstC4, op, kernel, {x: -1, y: -1}, 1,
- Number(controls.morphologyBorderType), color);
- kernel.delete();
- return dstC4;
- }
- function processVideo() {
- if (!streaming) return;
- stats.begin();
- vc.read(src);
- let result;
- switch (controls.filter) {
- case 'passThrough': result = passThrough(src); break;
- case 'gray': result = gray(src); break;
- case 'hsv': result = hsv(src); break;
- case 'canny': result = canny(src); break;
- case 'inRange': result = inRange(src); break;
- case 'threshold': result = threshold(src); break;
- case 'adaptiveThreshold': result = adaptiveThreshold(src); break;
- case 'gaussianBlur': result = gaussianBlur(src); break;
- case 'bilateralFilter': result = bilateralFilter(src); break;
- case 'medianBlur': result = medianBlur(src); break;
- case 'sobel': result = sobel(src); break;
- case 'scharr': result = scharr(src); break;
- case 'laplacian': result = laplacian(src); break;
- case 'contours': result = contours(src); break;
- case 'calcHist': result = calcHist(src); break;
- case 'equalizeHist': result = equalizeHist(src); break;
- case 'backprojection': result = backprojection(src); break;
- case 'erosion': result = erosion(src); break;
- case 'dilation': result = dilation(src); break;
- case 'morphology': result = morphology(src); break;
- default: result = passThrough(src);
- }
- cv.imshow('canvasOutput', result);
- stats.end();
- lastFilter = controls.filter;
- requestAnimationFrame(processVideo);
- }
- let stats = null;
- let filters = {
- 'passThrough': 'Pass Through',
- 'gray': 'Gray',
- 'hsv': 'HSV',
- 'canny': 'Canny Edge Detection',
- 'inRange': 'In Range',
- 'threshold': 'Threshold',
- 'adaptiveThreshold': 'Adaptive Threshold',
- 'gaussianBlur': 'Gaussian Blurring',
- 'medianBlur': 'Median Blurring',
- 'bilateralFilter': 'Bilateral Filtering',
- 'sobel': 'Sobel Derivatives',
- 'scharr': 'Scharr Derivatives',
- 'laplacian': 'Laplacian Derivatives',
- 'contours': 'Contours',
- 'calcHist': 'Calculation',
- 'equalizeHist': 'Equalization',
- 'backprojection': 'Backprojection',
- 'erosion': 'Erosion',
- 'dilation': 'Dilation',
- 'morphology': 'Morphology',
- };
- let filterName = document.getElementById('filterName');
- let controls;
- function initUI() {
- stats = new Stats();
- stats.showPanel(0);
- container.appendChild(stats.domElement);
- stats.domElement.style.position = 'absolute';
- stats.domElement.style.right = '0px';
- stats.domElement.style.top = '0px';
- controls = {
- filter: 'passThrough',
- setFilter: function(filter) {
- this.filter = filter;
- filterName.innerHTML = filters[filter];
- },
- passThrough: function() {
- this.setFilter('passThrough');
- },
- gray: function() {
- this.setFilter('gray');
- },
- hsv: function() {
- this.setFilter('hsv');
- },
- inRange: function() {
- this.setFilter('inRange');
- },
- inRangeLow: 75,
- inRangeHigh: 150,
- threshold: function() {
- this.setFilter('threshold');
- },
- thresholdValue: 100,
- adaptiveThreshold: function() {
- this.setFilter('adaptiveThreshold');
- },
- adaptiveBlockSize: 3,
- gaussianBlur: function() {
- this.setFilter('gaussianBlur');
- },
- gaussianBlurSize: 7,
- medianBlur: function() {
- this.setFilter('medianBlur');
- },
- medianBlurSize: 5,
- bilateralFilter: function() {
- this.setFilter('bilateralFilter');
- },
- bilateralFilterDiameter: 5,
- bilateralFilterSigma: 75,
- sobel: function() {
- this.setFilter('sobel');
- },
- sobelSize: 3,
- scharr: function() {
- this.setFilter('scharr');
- },
- laplacian: function() {
- this.setFilter('laplacian');
- },
- laplacianSize: 3,
- canny: function() {
- this.setFilter('canny');
- },
- cannyThreshold1: 150,
- cannyThreshold2: 300,
- cannyApertureSize: 3,
- cannyL2Gradient: false,
- contours: function() {
- this.setFilter('contours');
- },
- contoursMode: cv.RETR_CCOMP,
- contoursMethod: cv.CHAIN_APPROX_SIMPLE,
- calcHist: function() {
- this.setFilter('calcHist');
- },
- equalizeHist: function() {
- this.setFilter('equalizeHist');
- },
- backprojection: function() {
- this.setFilter('backprojection');
- },
- backprojectionRangeLow: 0,
- backprojectionRangeHigh: 150,
- morphology: function() {
- this.setFilter('morphology');
- },
- morphologyShape: cv.MORPH_RECT,
- morphologyOp: cv.MORPH_ERODE,
- morphologySize: 5,
- morphologyBorderType: cv.BORDER_CONSTANT,
- };
- let gui = new dat.GUI({autoPlace: false});
- let guiContainer = document.getElementById('guiContainer');
- guiContainer.appendChild(gui.domElement);
- let lastFolder = null;
- function closeLastFolder(folder) {
- if (lastFolder != null && lastFolder != folder) {
- lastFolder.close();
- }
- lastFolder = folder;
- }
- gui.add(controls, 'passThrough').name(filters['passThrough']).onChange(function() {
- closeLastFolder(null);
- });
- let colorConversion = gui.addFolder('Color Conversion');
- colorConversion.add(controls, 'gray').name(filters['gray']).onChange(function() {
- closeLastFolder(null);
- });
- colorConversion.add(controls, 'hsv').name(filters['hsv']).onChange(function() {
- closeLastFolder(null);
- });
- let inRange = colorConversion.addFolder(filters['inRange']);
- inRange.domElement.onclick = function() {
- closeLastFolder(inRange);
- controls.inRange();
- };
- inRange.add(controls, 'inRangeLow', 0, 255, 1).name('lower boundary');
- inRange.add(controls, 'inRangeHigh', 0, 255, 1).name('higher boundary');
- // let geometricTransformations = gui.addFolder('Geometric Transformations');
- // TODO
- let thresholding = gui.addFolder('Thresholding');
- let threshold = thresholding.addFolder(filters['threshold']);
- threshold.domElement.onclick = function() {
- closeLastFolder(threshold);
- controls.threshold();
- };
- threshold.add(controls, 'thresholdValue', 0, 200, 1).name('threshold value');
- let adaptiveThreshold = thresholding.addFolder(filters['adaptiveThreshold']);
- adaptiveThreshold.domElement.onclick = function() {
- closeLastFolder(adaptiveThreshold);
- controls.adaptiveThreshold();
- };
- adaptiveThreshold.add(
- controls, 'adaptiveBlockSize', 3, 99, 1).name('block size').onChange(
- function(value) {
- if (value % 2 === 0) controls.adaptiveBlockSize = value + 1;
- });
- let smoothing = gui.addFolder('Smoothing');
- let gaussianBlur = smoothing.addFolder(filters['gaussianBlur']);
- gaussianBlur.domElement.onclick = function() {
- closeLastFolder(gaussianBlur);
- controls.gaussianBlur();
- };
- gaussianBlur.add(
- controls, 'gaussianBlurSize', 7, 99, 1).name('kernel size').onChange(
- function(value) {
- if (value % 2 === 0) controls.gaussianBlurSize = value + 1;
- });
- let medianBlur = smoothing.addFolder(filters['medianBlur']);
- medianBlur.domElement.onclick = function() {
- closeLastFolder(medianBlur);
- controls.medianBlur();
- };
- medianBlur.add(
- controls, 'medianBlurSize', 3, 99, 1).name('kernel size').onChange(
- function(value) {
- if (value % 2 === 0) controls.medianBlurSize = value + 1;
- });
- let bilateralFilter = smoothing.addFolder(filters['bilateralFilter']);
- bilateralFilter.domElement.onclick = function() {
- closeLastFolder(bilateralFilter);
- controls.bilateralFilter();
- };
- bilateralFilter.add(controls, 'bilateralFilterDiameter', 1, 15, 1).name('diameter');
- bilateralFilter.add(controls, 'bilateralFilterSigma', 1, 255, 1).name('sigma');
- let morphology = gui.addFolder('Morphology');
- morphology.domElement.onclick = function() {
- closeLastFolder(morphology);
- controls.morphology();
- };
- morphology.add(
- controls, 'morphologyOp',
- {'MORPH_ERODE': cv.MORPH_ERODE,
- 'MORPH_DILATE': cv.MORPH_DILATE,
- 'MORPH_OPEN ': cv.MORPH_OPEN,
- 'MORPH_CLOSE': cv.MORPH_CLOSE,
- 'MORPH_GRADIENT': cv.MORPH_GRADIENT,
- 'MORPH_TOPHAT': cv.MORPH_TOPHAT,
- 'MORPH_BLACKHAT': cv.MORPH_BLACKHAT}).name('operation');
- morphology.add(
- controls, 'morphologyShape',
- {'MORPH_RECT': cv.MORPH_RECT,
- 'MORPH_CROSS': cv.MORPH_CROSS,
- 'MORPH_ELLIPSE': cv.MORPH_ELLIPSE}).name('shape');
- morphology.add(
- controls, 'morphologySize', 1, 15, 1).name('kernel size').onChange(
- function(value) {
- if (value % 2 === 0) controls.morphologySize = value + 1;
- });
- morphology.add(
- controls, 'morphologyBorderType',
- {'BORDER_CONSTANT': cv.BORDER_CONSTANT,
- 'BORDER_REPLICATE': cv.BORDER_REPLICATE,
- 'BORDER_REFLECT': cv.BORDER_REFLECT,
- 'BORDER_REFLECT_101': cv.BORDER_REFLECT_101}).name('boarder type');
- let gradients = gui.addFolder('Gradients');
- let sobel = gradients.addFolder(filters['sobel']);
- sobel.domElement.onclick = function() {
- closeLastFolder(sobel);
- controls.sobel();
- };
- sobel.add(controls, 'sobelSize', 3, 19, 1).name('kernel size').onChange(function(value) {
- if (value % 2 === 0) controls.sobelSize = value + 1;
- });
- gradients.add(controls, 'scharr').name(filters['scharr']).onChange(function() {
- closeLastFolder(null);
- });
- let laplacian = gradients.addFolder(filters['laplacian']);
- laplacian.domElement.onclick = function() {
- closeLastFolder(laplacian);
- controls.laplacian();
- };
- laplacian.add(
- controls, 'laplacianSize', 1, 19, 1).name('kernel size').onChange(
- function(value) {
- if (value % 2 === 0) controls.laplacianSize = value + 1;
- });
- let canny = gui.addFolder(filters['canny']);
- canny.domElement.onclick = function() {
- closeLastFolder(canny);
- controls.canny();
- };
- canny.add(controls, 'cannyThreshold1', 1, 500, 1).name('threshold1');
- canny.add(controls, 'cannyThreshold2', 1, 500, 1).name('threshold2');
- canny.add(controls, 'cannyApertureSize', 3, 7, 1).name('aperture size').onChange(
- function(value) {
- if (value % 2 === 0) controls.cannyApertureSize = value + 1;
- });
- canny.add(controls, 'cannyL2Gradient').name('l2 gradient');
- let contours = gui.addFolder(filters['contours']);
- contours.domElement.onclick = function() {
- closeLastFolder(contours);
- controls.contours();
- };
- contours.add(
- controls, 'contoursMode',
- {'RETR_EXTERNAL': cv.RETR_EXTERNAL,
- 'RETR_LIST': cv.RETR_LIST,
- 'RETR_CCOMP': cv.RETR_CCOMP,
- 'RETR_TREE': cv.RETR_TREE}).name('mode');
- contours.add(
- controls, 'contoursMethod',
- {'CHAIN_APPROX_NONE': cv.CHAIN_APPROX_NONE,
- 'CHAIN_APPROX_SIMPLE': cv.CHAIN_APPROX_SIMPLE,
- 'CHAIN_APPROX_TC89_L1': cv.CHAIN_APPROX_TC89_L1,
- 'CHAIN_APPROX_TC89_KCOS': cv.CHAIN_APPROX_TC89_KCOS}).name('method');
- let histograms = gui.addFolder('Histograms');
- histograms.add(controls, 'calcHist').name(filters['calcHist']).onChange(function() {
- closeLastFolder(null);
- });
- histograms.add(controls, 'equalizeHist').name(filters['equalizeHist']).onChange(function() {
- closeLastFolder(null);
- });
- let backprojection = histograms.addFolder(filters['backprojection']);
- backprojection.domElement.onclick = function() {
- closeLastFolder(backprojection);
- controls.backprojection();
- };
- backprojection.add(controls, 'backprojectionRangeLow', 0, 255, 1).name('range low');
- backprojection.add(controls, 'backprojectionRangeHigh', 0, 255, 1).name('range high');
- }
- function startCamera() {
- if (!streaming) {
- utils.clearError();
- utils.startCamera(resolution, onVideoStarted, 'videoInput');
- } else {
- utils.stopCamera();
- onVideoStopped();
- }
- }
- function onVideoStarted() {
- height = video.videoHeight;
- width = video.videoWidth;
- video.setAttribute('width', width);
- video.setAttribute('height', height);
- streaming = true;
- vc = new cv.VideoCapture(video);
- startVideoProcessing();
- }
- function stopVideoProcessing() {
- if (src != null && !src.isDeleted()) src.delete();
- if (dstC1 != null && !dstC1.isDeleted()) dstC1.delete();
- if (dstC3 != null && !dstC3.isDeleted()) dstC3.delete();
- if (dstC4 != null && !dstC4.isDeleted()) dstC4.delete();
- }
- function onVideoStopped() {
- if (!streaming) return;
- stopVideoProcessing();
- document.getElementById('canvasOutput').getContext('2d').clearRect(0, 0, width, height);
- streaming = false;
- }
- utils.loadOpenCv(() => {
- initUI();
- startCamera();
- });
- </script>
- </body>
- </html>
|