init - 初始化项目
This commit is contained in:
700
doc/js_tutorials/js_assets/js_imgproc_camera.html
Normal file
700
doc/js_tutorials/js_assets/js_imgproc_camera.html
Normal file
@@ -0,0 +1,700 @@
|
||||
<!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>
|
||||
Reference in New Issue
Block a user