brief_camera.html 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <!doctype html>
  2. <html>
  3. <head>
  4. <title>tracking.js - bounding box with camera</title>
  5. <meta charset="utf-8">
  6. <link rel="stylesheet" href="assets/demo.css">
  7. <script src="../build/tracking-min.js"></script>
  8. <script src="../node_modules/dat.gui/build/dat.gui.min.js"></script>
  9. <script src="assets/stats.min.js"></script>
  10. <style>
  11. #boundingBox {
  12. display: none;
  13. position: absolute;
  14. background: white;
  15. border: 1px dashed;
  16. opacity: .5;
  17. z-index: 1;
  18. }
  19. #video {
  20. position: absolute;
  21. top: -1000px;
  22. cursor: crosshair;
  23. }
  24. body {
  25. -webkit-touch-callout: none;
  26. -webkit-user-select: none;
  27. -khtml-user-select: none;
  28. -moz-user-select: none;
  29. -ms-user-select: none;
  30. user-select: none;
  31. }
  32. </style>
  33. </head>
  34. <body>
  35. <div class="demo-title">
  36. <p><a href="http://trackingjs.com" target="_parent">tracking.js</a> - Click and drag to select the area to be tracked</p>
  37. </div>
  38. <div id="boundingBox"></div>
  39. <div class="demo-frame">
  40. <div class="demo-container">
  41. <video id="video" width="393" height="295" preload autoplay loop muted controls></video>
  42. <canvas id="canvas" width="800" height="530"></canvas>
  43. </div>
  44. </div>
  45. <script>
  46. (function() {
  47. // BoundingBoxTracker ======================================================
  48. var BoundingBoxTracker = function() {
  49. BoundingBoxTracker.base(this, 'constructor');
  50. };
  51. tracking.inherits(BoundingBoxTracker, tracking.Tracker);
  52. BoundingBoxTracker.prototype.templateDescriptors_ = null;
  53. BoundingBoxTracker.prototype.templateKeypoints_ = null;
  54. BoundingBoxTracker.prototype.fastThreshold = 60;
  55. BoundingBoxTracker.prototype.blur = 3;
  56. BoundingBoxTracker.prototype.setTemplate = function(pixels, width, height) {
  57. var blur = tracking.Image.blur(pixels, width, height, 3);
  58. var grayscale = tracking.Image.grayscale(blur, width, height);
  59. this.templateKeypoints_ = tracking.Fast.findCorners(grayscale, width, height);
  60. this.templateDescriptors_ = tracking.Brief.getDescriptors(grayscale, width, this.templateKeypoints_);
  61. };
  62. BoundingBoxTracker.prototype.track = function(pixels, width, height) {
  63. var blur = tracking.Image.blur(pixels, width, height, this.blur);
  64. var grayscale = tracking.Image.grayscale(blur, width, height);
  65. var keypoints = tracking.Fast.findCorners(grayscale, width, height, this.fastThreshold);
  66. var descriptors = tracking.Brief.getDescriptors(grayscale, width, keypoints);
  67. this.emit('track', {
  68. data: tracking.Brief.reciprocalMatch(this.templateKeypoints_, this.templateDescriptors_, keypoints, descriptors)
  69. });
  70. };
  71. // Track ===================================================================
  72. var boundingBox = document.getElementById('boundingBox');
  73. var boxLeft = 403;
  74. var video = document.getElementById('video');
  75. var canvas = document.getElementById('canvas');
  76. var canvasRect = canvas.getBoundingClientRect();
  77. var context = canvas.getContext('2d');
  78. var templateImageData;
  79. var capturing = false;
  80. var videoHeight = 295;
  81. var videoWidth = 393;
  82. var tracker = new BoundingBoxTracker();
  83. tracker.on('track', function(event) {
  84. stats.end();
  85. if (capturing) {
  86. return;
  87. }
  88. // Sorts best matches by confidence.
  89. event.data.sort(function(a, b) {
  90. return b.confidence - a.confidence;
  91. });
  92. // Re-draws template on canvas.
  93. context.putImageData(templateImageData, boxLeft, 0);
  94. // Plots lines connecting matches.
  95. for (var i = 0; i < Math.min(10, event.data.length); i++) {
  96. var template = event.data[i].keypoint1;
  97. var frame = event.data[i].keypoint2;
  98. context.beginPath();
  99. context.strokeStyle = 'magenta';
  100. context.moveTo(frame[0], frame[1]);
  101. context.lineTo(boxLeft + template[0], template[1]);
  102. context.stroke();
  103. }
  104. });
  105. var trackerTask = tracking.track(video, tracker, { camera: true });
  106. // Waits for the user to accept the camera.
  107. trackerTask.stop();
  108. // Sync video ============================================================
  109. function requestFrame() {
  110. window.requestAnimationFrame(function() {
  111. context.clearRect(0, 0, canvas.width, canvas.height);
  112. if (video.readyState === video.HAVE_ENOUGH_DATA) {
  113. try {
  114. context.drawImage(video, 0, 0, videoWidth, videoHeight);
  115. } catch (err) {}
  116. }
  117. requestFrame();
  118. });
  119. }
  120. requestFrame();
  121. // Bounding box drag =====================================================
  122. var initialPoint;
  123. var left;
  124. var top;
  125. var width;
  126. var height;
  127. canvas.addEventListener('mousedown', function(event) {
  128. initialPoint = [event.pageX, event.pageY];
  129. capturing = true;
  130. });
  131. canvas.addEventListener('mousemove', function(event) {
  132. if (capturing) {
  133. left = Math.min(initialPoint[0], event.pageX);
  134. top = Math.min(initialPoint[1], event.pageY);
  135. width = Math.max(initialPoint[0], event.pageX) - left;
  136. height = Math.max(initialPoint[1], event.pageY) - top;
  137. boundingBox.style.display = 'block';
  138. boundingBox.style.left = left + 'px';
  139. boundingBox.style.top = top + 'px';
  140. boundingBox.style.width = width + 'px';
  141. boundingBox.style.height = height + 'px';
  142. }
  143. });
  144. document.addEventListener('mouseup', function() {
  145. boundingBox.style.display = 'none';
  146. setTackerTemplate(left, top, width, height);
  147. capturing = false;
  148. });
  149. function setTackerTemplate(left, top, width, height) {
  150. templateImageData = context.getImageData(left - canvasRect.left, top - canvasRect.top, width, height);
  151. canvas.width = boxLeft + width;
  152. context.putImageData(templateImageData, boxLeft, 0);
  153. trackerTask.stop();
  154. tracker.setTemplate(templateImageData.data, width, height);
  155. trackerTask.run();
  156. }
  157. // GUI Controllers
  158. var gui = new dat.GUI();
  159. gui.add(tracker, 'fastThreshold', 20, 100).step(5);
  160. gui.add(tracker, 'blur', 1.1, 5.0).step(0.1);
  161. }());
  162. </script>
  163. </body>
  164. </html>