UNPKG

@ericblade/quagga2

Version:

An advanced barcode-scanner written in JavaScript

1,480 lines (1,410 loc) 384 kB
(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/"; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 69); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { var toPropertyKey = __webpack_require__(62); function _defineProperty(obj, key, value) { key = toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports; /***/ }), /* 1 */ /***/ (function(module, exports) { function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } module.exports = _assertThisInitialized, module.exports.__esModule = true, module.exports["default"] = module.exports; /***/ }), /* 2 */ /***/ (function(module, exports) { function _getPrototypeOf(o) { module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }, module.exports.__esModule = true, module.exports["default"] = module.exports; return _getPrototypeOf(o); } module.exports = _getPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports; /***/ }), /* 3 */ /***/ (function(module, exports) { function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } module.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { var toPropertyKey = __webpack_require__(62); function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports; /***/ }), /* 5 */ /***/ (function(module, exports) { module.exports = require("gl-matrix"); /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { var _typeof = __webpack_require__(13)["default"]; var assertThisInitialized = __webpack_require__(1); function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return assertThisInitialized(self); } module.exports = _possibleConstructorReturn, module.exports.__esModule = true, module.exports["default"] = module.exports; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { var setPrototypeOf = __webpack_require__(41); function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) setPrototypeOf(subClass, superClass); } module.exports = _inherits, module.exports.__esModule = true, module.exports["default"] = module.exports; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { // TODO(Babel 8): Remove this file. var runtime = __webpack_require__(137)(); module.exports = runtime; // Copied from https://github.com/facebook/regenerator/blob/main/packages/runtime/runtime.js#L736= try { regeneratorRuntime = runtime; } catch (accidentalStrictMode) { if (typeof globalThis === "object") { globalThis.regeneratorRuntime = runtime; } else { Function("r", "regeneratorRuntime = r")(runtime); } } /***/ }), /* 9 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* eslint-disable no-param-reassign */ /* harmony default export */ __webpack_exports__["a"] = ({ init: function init(arr, val) { arr.fill(val); }, /** * IN-PLACE Shuffles the content of an array */ shuffle: function shuffle(arr) { // Durstenfeld shuffle algorithm // https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var _ref = [arr[j], arr[i]]; arr[i] = _ref[0]; arr[j] = _ref[1]; } return arr; }, toPointList: function toPointList(arr) { var rows = arr.reduce(function (p, n) { var row = "[".concat(n.join(','), "]"); p.push(row); return p; }, []); return "[".concat(rows.join(',\r\n'), "]"); }, /** * returns the elements which's score is bigger than the threshold */ // eslint-disable-next-line no-unused-vars threshold: function threshold(arr, _threshold, scoreFunc) { var queue = arr.reduce(function (prev, next) { if (scoreFunc.apply(arr, [next]) >= _threshold) { prev.push(next); } return prev; }, []); return queue; }, maxIndex: function maxIndex(arr) { var max = 0; for (var i = 0; i < arr.length; i++) { if (arr[i] > arr[max]) { max = i; } } return max; }, max: function max(arr) { var max = 0; for (var i = 0; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } return max; }, sum: function sum(arr) { var length = arr.length; var sum = 0; while (length--) { sum += arr[length]; } return sum; } }); /***/ }), /* 10 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33); /* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); /* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(0); /* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5); /* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(gl_matrix__WEBPACK_IMPORTED_MODULE_4__); /* harmony import */ var _array_helper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9); /* harmony import */ var _cv_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(12); gl_matrix__WEBPACK_IMPORTED_MODULE_4__["glMatrix"].setMatrixArrayType(Array); function assertNumberPositive(val) { if (val < 0) { throw new Error("expected positive number, received ".concat(val)); } } var ImageWrapper = /*#__PURE__*/function () { // Represents a basic image combining the data and size. In addition, some methods for // manipulation are contained within. function ImageWrapper(size, data) { var ArrayType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Uint8Array; var initialize = arguments.length > 3 ? arguments[3] : undefined; _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1___default()(this, ImageWrapper); _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_3___default()(this, "data", void 0); _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_3___default()(this, "size", void 0); _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_3___default()(this, "indexMapping", void 0); if (!data) { this.data = new ArrayType(size.x * size.y); if (initialize) { _array_helper__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].init(this.data, 0); } } else { this.data = data; } this.size = size; } // tests if a position is within the image, extended out by a border on each side _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default()(ImageWrapper, [{ key: "inImageWithBorder", value: function inImageWithBorder(imgRef) { var border = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; assertNumberPositive(border); return imgRef.x >= 0 && imgRef.y >= 0 && imgRef.x < this.size.x + border * 2 && imgRef.y < this.size.y + border * 2; } // Copy from THIS ImageWrapper to the new imageWrapper parameter, starting at from, stopping at // end of new imageWrapper size. }, { key: "subImageAsCopy", value: function subImageAsCopy(imageWrapper, from) { assertNumberPositive(from.x); assertNumberPositive(from.y); var _imageWrapper$size = imageWrapper.size, sizeX = _imageWrapper$size.x, sizeY = _imageWrapper$size.y; for (var x = 0; x < sizeX; x++) { for (var y = 0; y < sizeY; y++) { // eslint-disable-next-line no-param-reassign imageWrapper.data[y * sizeX + x] = this.data[(from.y + y) * this.size.x + from.x + x]; } } return imageWrapper; // TODO: this function really probably should call into ImageWrapper somewhere to make // sure that all of it's parameters are set properly, something like // ImageWrapper.UpdateFrom() // that might take a provided data and size, and make sure there's no invalid indexMapping // hanging around, and such. } // Retrieve a grayscale value at the given pixel position of the image }, { key: "get", value: function get(x, y) { return this.data[y * this.size.x + x]; } // Retrieve a grayscale value at the given pixel position of the image (safe, whatever that // means) }, { key: "getSafe", value: function getSafe(x, y) { // cache indexMapping because if we're using it once, we'll probably need it a bunch more // too if (!this.indexMapping) { this.indexMapping = { x: [], y: [] }; for (var i = 0; i < this.size.x; i++) { this.indexMapping.x[i] = i; this.indexMapping.x[i + this.size.x] = i; } for (var _i = 0; _i < this.size.y; _i++) { this.indexMapping.y[_i] = _i; this.indexMapping.y[_i + this.size.y] = _i; } } return this.data[this.indexMapping.y[y + this.size.y] * this.size.x + this.indexMapping.x[x + this.size.x]]; } // Sets a given pixel position in the image to the given grayscale value }, { key: "set", value: function set(x, y, value) { this.data[y * this.size.x + x] = value; delete this.indexMapping; return this; } // Sets the border of the image (1 pixel) to zero }, { key: "zeroBorder", value: function zeroBorder() { var _this$size = this.size, width = _this$size.x, height = _this$size.y; for (var i = 0; i < width; i++) { // eslint-disable-next-line no-multi-assign this.data[i] = this.data[(height - 1) * width + i] = 0; } for (var _i2 = 1; _i2 < height - 1; _i2++) { // eslint-disable-next-line no-multi-assign this.data[_i2 * width] = this.data[_i2 * width + (width - 1)] = 0; } delete this.indexMapping; return this; } // TODO: this function is entirely too large for me to reason out right at this moment that i'm handling // all the rest of it, so this is a verbatim copy of the javascript source, with only tweaks // necessary to get it to run, no thought put into it yet. }, { key: "moments", value: function moments(labelCount) { var data = this.data; var x; var y; var height = this.size.y; var width = this.size.x; var val; var ysq; var labelSum = []; var i; var label; var mu11; var mu02; var mu20; var x_; var y_; var tmp; var result = []; var PI = Math.PI; var PI_4 = PI / 4; if (labelCount <= 0) { return result; } for (i = 0; i < labelCount; i++) { labelSum[i] = { m00: 0, m01: 0, m10: 0, m11: 0, m02: 0, m20: 0, theta: 0, rad: 0 }; } for (y = 0; y < height; y++) { ysq = y * y; for (x = 0; x < width; x++) { val = data[y * width + x]; if (val > 0) { label = labelSum[val - 1]; label.m00 += 1; label.m01 += y; label.m10 += x; label.m11 += x * y; label.m02 += ysq; label.m20 += x * x; } } } for (i = 0; i < labelCount; i++) { label = labelSum[i]; // eslint-disable-next-line no-restricted-globals if (!isNaN(label.m00) && label.m00 !== 0) { x_ = label.m10 / label.m00; y_ = label.m01 / label.m00; mu11 = label.m11 / label.m00 - x_ * y_; mu02 = label.m02 / label.m00 - y_ * y_; mu20 = label.m20 / label.m00 - x_ * x_; tmp = (mu02 - mu20) / (2 * mu11); tmp = 0.5 * Math.atan(tmp) + (mu11 >= 0 ? PI_4 : -PI_4) + PI; // eslint-disable-next-line no-mixed-operators label.theta = (tmp * 180 / PI + 90) % 180 - 90; if (label.theta < 0) { label.theta += 180; } label.rad = tmp > PI ? tmp - PI : tmp; label.vec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__["vec2"].clone([Math.cos(tmp), Math.sin(tmp)]); result.push(label); } } return result; } // return a Uint8ClampedArray containing this grayscale image converted to RGBA form }, { key: "getAsRGBA", value: function getAsRGBA() { var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1.0; var ret = new Uint8ClampedArray(4 * this.size.x * this.size.y); for (var y = 0; y < this.size.y; y++) { for (var x = 0; x < this.size.x; x++) { var pixel = y * this.size.x + x; var current = this.get(x, y) * scale; ret[pixel * 4 + 0] = current; ret[pixel * 4 + 1] = current; ret[pixel * 4 + 2] = current; ret[pixel * 4 + 3] = 255; } } return ret; } // Display this ImageWrapper in a given Canvas element at the specified scale }, { key: "show", value: function show(canvas) { var scale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1.0; console.warn('* imagewrapper show getcontext 2d'); var ctx = canvas.getContext('2d'); if (!ctx) { throw new Error('Unable to get canvas context'); } var frame = ctx.getImageData(0, 0, canvas.width, canvas.height); var data = this.getAsRGBA(scale); // eslint-disable-next-line no-param-reassign canvas.width = this.size.x; // eslint-disable-next-line no-param-reassign canvas.height = this.size.y; var newFrame = new ImageData(data, frame.width, frame.height); ctx.putImageData(newFrame, 0, 0); } // Displays a specified SubImage area in a given canvas. This differs drastically from // creating a new SubImage and using it's show() method. Why? I don't have the answer to that // yet. I suspect the HSV/RGB operations involved here are making it significantly different, // but until I can visualize these functions side by side, I'm just going to copy the existing // implementation. }, { key: "overlay", value: function overlay(canvas, inScale, from) { var adjustedScale = inScale < 0 || inScale > 360 ? 360 : inScale; var hsv = [0, 1, 1]; var rgb = [0, 0, 0]; var whiteRgb = [255, 255, 255]; var blackRgb = [0, 0, 0]; var result = []; console.warn('* imagewrapper overlay getcontext 2d'); var ctx = canvas.getContext('2d'); if (!ctx) { throw new Error('Unable to get canvas context'); } var frame = ctx.getImageData(from.x, from.y, this.size.x, this.size.y); var data = frame.data; var length = this.data.length; while (length--) { hsv[0] = this.data[length] * adjustedScale; // eslint-disable-next-line no-nested-ternary result = hsv[0] <= 0 ? whiteRgb : hsv[0] >= 360 ? blackRgb : Object(_cv_utils__WEBPACK_IMPORTED_MODULE_6__["hsv2rgb"])(hsv, rgb); var pos = length * 4; var _result = result; var _result2 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_result, 3); data[pos] = _result2[0]; data[pos + 1] = _result2[1]; data[pos + 2] = _result2[2]; data[pos + 3] = 255; } ctx.putImageData(frame, from.x, from.y); } }]); return ImageWrapper; }(); /* harmony default export */ __webpack_exports__["a"] = (ImageWrapper); /***/ }), /* 11 */ /***/ (function(module, exports) { function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } module.exports = _asyncToGenerator, module.exports.__esModule = true, module.exports["default"] = module.exports; /***/ }), /* 12 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, "imageRef", function() { return /* binding */ imageRef; }); __webpack_require__.d(__webpack_exports__, "computeIntegralImage2", function() { return /* binding */ computeIntegralImage2; }); __webpack_require__.d(__webpack_exports__, "computeIntegralImage", function() { return /* binding */ computeIntegralImage; }); __webpack_require__.d(__webpack_exports__, "thresholdImage", function() { return /* binding */ thresholdImage; }); __webpack_require__.d(__webpack_exports__, "computeHistogram", function() { return /* binding */ computeHistogram; }); __webpack_require__.d(__webpack_exports__, "sharpenLine", function() { return /* binding */ sharpenLine; }); __webpack_require__.d(__webpack_exports__, "determineOtsuThreshold", function() { return /* binding */ determineOtsuThreshold; }); __webpack_require__.d(__webpack_exports__, "otsuThreshold", function() { return /* binding */ otsuThreshold; }); __webpack_require__.d(__webpack_exports__, "computeBinaryImage", function() { return /* binding */ computeBinaryImage; }); __webpack_require__.d(__webpack_exports__, "cluster", function() { return /* binding */ cv_utils_cluster; }); __webpack_require__.d(__webpack_exports__, "Tracer", function() { return /* binding */ Tracer; }); __webpack_require__.d(__webpack_exports__, "DILATE", function() { return /* binding */ DILATE; }); __webpack_require__.d(__webpack_exports__, "ERODE", function() { return /* binding */ ERODE; }); __webpack_require__.d(__webpack_exports__, "dilate", function() { return /* binding */ dilate; }); __webpack_require__.d(__webpack_exports__, "erode", function() { return /* binding */ erode; }); __webpack_require__.d(__webpack_exports__, "subtract", function() { return /* binding */ subtract; }); __webpack_require__.d(__webpack_exports__, "bitwiseOr", function() { return /* binding */ bitwiseOr; }); __webpack_require__.d(__webpack_exports__, "countNonZero", function() { return /* binding */ countNonZero; }); __webpack_require__.d(__webpack_exports__, "topGeneric", function() { return /* binding */ topGeneric; }); __webpack_require__.d(__webpack_exports__, "grayArrayFromImage", function() { return /* binding */ grayArrayFromImage; }); __webpack_require__.d(__webpack_exports__, "grayArrayFromContext", function() { return /* binding */ grayArrayFromContext; }); __webpack_require__.d(__webpack_exports__, "grayAndHalfSampleFromCanvasData", function() { return /* binding */ grayAndHalfSampleFromCanvasData; }); __webpack_require__.d(__webpack_exports__, "computeGray", function() { return /* binding */ computeGray; }); __webpack_require__.d(__webpack_exports__, "loadImageArray", function() { return /* binding */ loadImageArray; }); __webpack_require__.d(__webpack_exports__, "halfSample", function() { return /* binding */ halfSample; }); __webpack_require__.d(__webpack_exports__, "hsv2rgb", function() { return /* binding */ hsv2rgb; }); __webpack_require__.d(__webpack_exports__, "_computeDivisors", function() { return /* binding */ _computeDivisors; }); __webpack_require__.d(__webpack_exports__, "calculatePatchSize", function() { return /* binding */ calculatePatchSize; }); __webpack_require__.d(__webpack_exports__, "_parseCSSDimensionValues", function() { return /* binding */ _parseCSSDimensionValues; }); __webpack_require__.d(__webpack_exports__, "_dimensionsConverters", function() { return /* binding */ _dimensionsConverters; }); __webpack_require__.d(__webpack_exports__, "computeImageArea", function() { return /* binding */ computeImageArea; }); // EXTERNAL MODULE: external "gl-matrix" var external_gl_matrix_ = __webpack_require__(5); // EXTERNAL MODULE: ./src/common/array_helper.ts var array_helper = __webpack_require__(9); // CONCATENATED MODULE: ./src/common/cluster.js // TODO: cluster.js and cv_utils.js are pretty tightly intertwined, making for a complex conversion // into typescript. be warned. :-) external_gl_matrix_["glMatrix"].setMatrixArrayType(Array); /** * Creates a cluster for grouping similar orientations of datapoints */ /* harmony default export */ var cluster = ({ create: function create(point, threshold) { var points = []; var center = { rad: 0, vec: external_gl_matrix_["vec2"].clone([0, 0]) }; var pointMap = {}; function _add(pointToAdd) { pointMap[pointToAdd.id] = pointToAdd; points.push(pointToAdd); } function updateCenter() { var i; var sum = 0; for (i = 0; i < points.length; i++) { sum += points[i].rad; } center.rad = sum / points.length; center.vec = external_gl_matrix_["vec2"].clone([Math.cos(center.rad), Math.sin(center.rad)]); } function init() { _add(point); updateCenter(); } init(); return { add: function add(pointToAdd) { if (!pointMap[pointToAdd.id]) { _add(pointToAdd); updateCenter(); } }, fits: function fits(otherPoint) { // check cosine similarity to center-angle var similarity = Math.abs(external_gl_matrix_["vec2"].dot(otherPoint.point.vec, center.vec)); if (similarity > threshold) { return true; } return false; }, getPoints: function getPoints() { return points; }, getCenter: function getCenter() { return center; } }; }, createPoint: function createPoint(newPoint, id, property) { return { rad: newPoint[property], point: newPoint, id: id }; } }); // CONCATENATED MODULE: ./src/common/cv_utils.js /* eslint-disable no-mixed-operators */ /* eslint-disable no-bitwise */ external_gl_matrix_["glMatrix"].setMatrixArrayType(Array); /** * @param x x-coordinate * @param y y-coordinate * @return ImageReference {x,y} Coordinate */ function imageRef(x, y) { var that = { x: x, y: y, toVec2: function toVec2() { return external_gl_matrix_["vec2"].clone([this.x, this.y]); }, toVec3: function toVec3() { return external_gl_matrix_["vec3"].clone([this.x, this.y, 1]); }, round: function round() { this.x = this.x > 0.0 ? Math.floor(this.x + 0.5) : Math.floor(this.x - 0.5); this.y = this.y > 0.0 ? Math.floor(this.y + 0.5) : Math.floor(this.y - 0.5); return this; } }; return that; } /** * Computes an integral image of a given grayscale image. * @param imageDataContainer {ImageDataContainer} the image to be integrated */ function computeIntegralImage2(imageWrapper, integralWrapper) { var imageData = imageWrapper.data; var width = imageWrapper.size.x; var height = imageWrapper.size.y; var integralImageData = integralWrapper.data; var sum = 0; var posA = 0; var posB = 0; var posC = 0; var posD = 0; var x; var y; // sum up first column posB = width; sum = 0; for (y = 1; y < height; y++) { sum += imageData[posA]; integralImageData[posB] += sum; posA += width; posB += width; } posA = 0; posB = 1; sum = 0; for (x = 1; x < width; x++) { sum += imageData[posA]; integralImageData[posB] += sum; posA++; posB++; } for (y = 1; y < height; y++) { posA = y * width + 1; posB = (y - 1) * width + 1; posC = y * width; posD = (y - 1) * width; for (x = 1; x < width; x++) { integralImageData[posA] += imageData[posA] + integralImageData[posB] + integralImageData[posC] - integralImageData[posD]; posA++; posB++; posC++; posD++; } } } function computeIntegralImage(imageWrapper, integralWrapper) { var imageData = imageWrapper.data; var width = imageWrapper.size.x; var height = imageWrapper.size.y; var integralImageData = integralWrapper.data; var sum = 0; // sum up first row for (var i = 0; i < width; i++) { sum += imageData[i]; integralImageData[i] = sum; } for (var v = 1; v < height; v++) { sum = 0; for (var u = 0; u < width; u++) { sum += imageData[v * width + u]; integralImageData[v * width + u] = sum + integralImageData[(v - 1) * width + u]; } } } function thresholdImage(imageWrapper, threshold, targetWrapper) { if (!targetWrapper) { // eslint-disable-next-line no-param-reassign targetWrapper = imageWrapper; } var imageData = imageWrapper.data; var length = imageData.length; var targetData = targetWrapper.data; while (length--) { targetData[length] = imageData[length] < threshold ? 1 : 0; } } function computeHistogram(imageWrapper, bitsPerPixel) { if (!bitsPerPixel) { // eslint-disable-next-line no-param-reassign bitsPerPixel = 8; } var imageData = imageWrapper.data; var length = imageData.length; var bitShift = 8 - bitsPerPixel; var bucketCnt = 1 << bitsPerPixel; var hist = new Int32Array(bucketCnt); while (length--) { hist[imageData[length] >> bitShift]++; } return hist; } function sharpenLine(line) { var i; var length = line.length; var left = line[0]; var center = line[1]; var right; for (i = 1; i < length - 1; i++) { right = line[i + 1]; // -1 4 -1 kernel // eslint-disable-next-line no-param-reassign line[i - 1] = center * 2 - left - right & 255; left = center; center = right; } return line; } function determineOtsuThreshold(imageWrapper) { var bitsPerPixel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 8; var hist; var bitShift = 8 - bitsPerPixel; function px(init, end) { var sum = 0; for (var i = init; i <= end; i++) { sum += hist[i]; } return sum; } function mx(init, end) { var sum = 0; for (var i = init; i <= end; i++) { sum += i * hist[i]; } return sum; } function determineThreshold() { var vet = [0]; var p1; var p2; var p12; var m1; var m2; var m12; var max = (1 << bitsPerPixel) - 1; hist = computeHistogram(imageWrapper, bitsPerPixel); for (var k = 1; k < max; k++) { p1 = px(0, k); p2 = px(k + 1, max); p12 = p1 * p2; if (p12 === 0) { p12 = 1; } m1 = mx(0, k) * p2; m2 = mx(k + 1, max) * p1; m12 = m1 - m2; vet[k] = m12 * m12 / p12; } return array_helper["a" /* default */].maxIndex(vet); } var threshold = determineThreshold(); return threshold << bitShift; } function otsuThreshold(imageWrapper, targetWrapper) { var threshold = determineOtsuThreshold(imageWrapper); thresholdImage(imageWrapper, threshold, targetWrapper); return threshold; } // local thresholding function computeBinaryImage(imageWrapper, integralWrapper, targetWrapper) { computeIntegralImage(imageWrapper, integralWrapper); if (!targetWrapper) { // eslint-disable-next-line no-param-reassign targetWrapper = imageWrapper; } var imageData = imageWrapper.data; var targetData = targetWrapper.data; var width = imageWrapper.size.x; var height = imageWrapper.size.y; var integralImageData = integralWrapper.data; var sum = 0; var v; var u; var kernel = 3; var A; var B; var C; var D; var avg; var size = (kernel * 2 + 1) * (kernel * 2 + 1); // clear out top & bottom-border for (v = 0; v <= kernel; v++) { for (u = 0; u < width; u++) { targetData[v * width + u] = 0; targetData[(height - 1 - v) * width + u] = 0; } } // clear out left & right border for (v = kernel; v < height - kernel; v++) { for (u = 0; u <= kernel; u++) { targetData[v * width + u] = 0; targetData[v * width + (width - 1 - u)] = 0; } } for (v = kernel + 1; v < height - kernel - 1; v++) { for (u = kernel + 1; u < width - kernel; u++) { A = integralImageData[(v - kernel - 1) * width + (u - kernel - 1)]; B = integralImageData[(v - kernel - 1) * width + (u + kernel)]; C = integralImageData[(v + kernel) * width + (u - kernel - 1)]; D = integralImageData[(v + kernel) * width + (u + kernel)]; sum = D - C - B + A; avg = sum / size; targetData[v * width + u] = imageData[v * width + u] > avg + 5 ? 0 : 1; } } } function cv_utils_cluster(points, threshold, property) { var i; var k; var thisCluster; var point; var clusters = []; if (!property) { // eslint-disable-next-line no-param-reassign property = 'rad'; } function addToCluster(newPoint) { var found = false; for (k = 0; k < clusters.length; k++) { thisCluster = clusters[k]; if (thisCluster.fits(newPoint)) { thisCluster.add(newPoint); found = true; } } return found; } // iterate over each cloud for (i = 0; i < points.length; i++) { point = cluster.createPoint(points[i], i, property); if (!addToCluster(point)) { clusters.push(cluster.create(point, threshold)); } } return clusters; } var Tracer = { trace: function trace(points, vec) { var iteration; var maxIterations = 10; var top = []; var result = []; var centerPos = 0; var currentPos = 0; function trace(idx, forward) { var to; var toIdx; var predictedPos; var thresholdX = 1; var thresholdY = Math.abs(vec[1] / 10); var found = false; function match(pos, predicted) { if (pos.x > predicted.x - thresholdX && pos.x < predicted.x + thresholdX && pos.y > predicted.y - thresholdY && pos.y < predicted.y + thresholdY) { return true; } return false; } // check if the next index is within the vec specifications // if not, check as long as the threshold is met var from = points[idx]; if (forward) { predictedPos = { x: from.x + vec[0], y: from.y + vec[1] }; } else { predictedPos = { x: from.x - vec[0], y: from.y - vec[1] }; } toIdx = forward ? idx + 1 : idx - 1; to = points[toIdx]; // eslint-disable-next-line no-cond-assign while (to && (found = match(to, predictedPos)) !== true && Math.abs(to.y - from.y) < vec[1]) { toIdx = forward ? toIdx + 1 : toIdx - 1; to = points[toIdx]; } return found ? toIdx : null; } for (iteration = 0; iteration < maxIterations; iteration++) { // randomly select point to start with centerPos = Math.floor(Math.random() * points.length); // trace forward top = []; currentPos = centerPos; top.push(points[currentPos]); // eslint-disable-next-line no-cond-assign while ((currentPos = trace(currentPos, true)) !== null) { top.push(points[currentPos]); } if (centerPos > 0) { currentPos = centerPos; // eslint-disable-next-line no-cond-assign while ((currentPos = trace(currentPos, false)) !== null) { top.push(points[currentPos]); } } if (top.length > result.length) { result = top; } } return result; } }; var DILATE = 1; var ERODE = 2; function dilate(inImageWrapper, outImageWrapper) { var v; var u; var inImageData = inImageWrapper.data; var outImageData = outImageWrapper.data; var height = inImageWrapper.size.y; var width = inImageWrapper.size.x; var sum; var yStart1; var yStart2; var xStart1; var xStart2; for (v = 1; v < height - 1; v++) { for (u = 1; u < width - 1; u++) { yStart1 = v - 1; yStart2 = v + 1; xStart1 = u - 1; xStart2 = u + 1; sum = inImageData[yStart1 * width + xStart1] + inImageData[yStart1 * width + xStart2] + inImageData[v * width + u] + inImageData[yStart2 * width + xStart1] + inImageData[yStart2 * width + xStart2]; outImageData[v * width + u] = sum > 0 ? 1 : 0; } } } function erode(inImageWrapper, outImageWrapper) { var v; var u; var inImageData = inImageWrapper.data; var outImageData = outImageWrapper.data; var height = inImageWrapper.size.y; var width = inImageWrapper.size.x; var sum; var yStart1; var yStart2; var xStart1; var xStart2; for (v = 1; v < height - 1; v++) { for (u = 1; u < width - 1; u++) { yStart1 = v - 1; yStart2 = v + 1; xStart1 = u - 1; xStart2 = u + 1; sum = inImageData[yStart1 * width + xStart1] + inImageData[yStart1 * width + xStart2] + inImageData[v * width + u] + inImageData[yStart2 * width + xStart1] + inImageData[yStart2 * width + xStart2]; outImageData[v * width + u] = sum === 5 ? 1 : 0; } } } function subtract(aImageWrapper, bImageWrapper, resultImageWrapper) { if (!resultImageWrapper) { // eslint-disable-next-line no-param-reassign resultImageWrapper = aImageWrapper; } var length = aImageWrapper.data.length; var aImageData = aImageWrapper.data; var bImageData = bImageWrapper.data; var cImageData = resultImageWrapper.data; while (length--) { cImageData[length] = aImageData[length] - bImageData[length]; } } function bitwiseOr(aImageWrapper, bImageWrapper, resultImageWrapper) { if (!resultImageWrapper) { // eslint-disable-next-line no-param-reassign resultImageWrapper = aImageWrapper; } var length = aImageWrapper.data.length; var aImageData = aImageWrapper.data; var bImageData = bImageWrapper.data; var cImageData = resultImageWrapper.data; while (length--) { cImageData[length] = aImageData[length] || bImageData[length]; } } function countNonZero(imageWrapper) { var length = imageWrapper.data.length; var data = imageWrapper.data; var sum = 0; while (length--) { sum += data[length]; } return sum; } function topGeneric(list, top, scoreFunc) { var i; var minIdx = 0; var min = 0; var queue = []; var score; var hit; var pos; for (i = 0; i < top; i++) { queue[i] = { score: 0, item: null }; } for (i = 0; i < list.length; i++) { score = scoreFunc.apply(this, [list[i]]); if (score > min) { hit = queue[minIdx]; hit.score = score; hit.item = list[i]; min = Number.MAX_VALUE; for (pos = 0; pos < top; pos++) { if (queue[pos].score < min) { min = queue[pos].score; minIdx = pos; } } } } return queue; } function grayArrayFromImage(htmlImage, offsetX, ctx, array) { ctx.drawImage(htmlImage, offsetX, 0, htmlImage.width, htmlImage.height); var ctxData = ctx.getImageData(offsetX, 0, htmlImage.width, htmlImage.height).data; computeGray(ctxData, array); } function grayArrayFromContext(ctx, size, offset, array) { var ctxData = ctx.getImageData(offset.x, offset.y, size.x, size.y).data; computeGray(ctxData, array); } function grayAndHalfSampleFromCanvasData(canvasData, size, outArray) { var topRowIdx = 0; var bottomRowIdx = size.x; var endIdx = Math.floor(canvasData.length / 4); var outWidth = size.x / 2; var outImgIdx = 0; var inWidth = size.x; var i; while (bottomRowIdx < endIdx) { for (i = 0; i < outWidth; i++) { // eslint-disable-next-line no-param-reassign outArray[outImgIdx] = (0.299 * canvasData[topRowIdx * 4 + 0] + 0.587 * canvasData[topRowIdx * 4 + 1] + 0.114 * canvasData[topRowIdx * 4 + 2] + (0.299 * canvasData[(topRowIdx + 1) * 4 + 0] + 0.587 * canvasData[(topRowIdx + 1) * 4 + 1] + 0.114 * canvasData[(topRowIdx + 1) * 4 + 2]) + (0.299 * canvasData[bottomRowIdx * 4 + 0] + 0.587 * canvasData[bottomRowIdx * 4 + 1] + 0.114 * canvasData[bottomRowIdx * 4 + 2]) + (0.299 * canvasData[(bottomRowIdx + 1) * 4 + 0] + 0.587 * canvasData[(bottomRowIdx + 1) * 4 + 1] + 0.114 * canvasData[(bottomRowIdx + 1) * 4 + 2])) / 4; outImgIdx++; topRowIdx += 2; bottomRowIdx += 2; } topRowIdx += inWidth; bottomRowIdx += inWidth; } } function computeGray(imageData, outArray, config) { var l = imageData.length / 4 | 0; var singleChannel = config && config.singleChannel === true; if (singleChannel) { for (var i = 0; i < l; i++) { // eslint-disable-next-line no-param-reassign outArray[i] = imageData[i * 4 + 0]; } } else { for (var _i = 0; _i < l; _i++) { // eslint-disable-next-line no-param-reassign outArray[_i] = 0.299 * imageData[_i * 4 + 0] + 0.587 * imageData[_i * 4 + 1] + 0.114 * imageData[_i * 4 + 2]; } } } function loadImageArray(src, callback) { var canvas = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : document && document.createElement('canvas'); var img = new Image(); img.callback = callback; img.onload = function () { // eslint-disable-next-line no-param-reassign canvas.width = this.width; // eslint-disable-next-line no-param-reassign canvas.height = this.height; console.warn('* loadImageArray getContext 2d'); var ctx = canvas.getContext('2d'); ctx.drawImage(this, 0, 0); var array = new Uint8Array(this.width * this.height); ctx.drawImage(this, 0, 0); var _ctx$getImageData = ctx.getImageData(0, 0, this.width, this.height), data = _ctx$getImageData.data; computeGray(data, array); this.callback(array, { x: this.width, y: this.height }, this); }; img.src = src; } /** * @param inImg {ImageWrapper} input image to be sampled * @param outImg {ImageWrapper} to be stored in */ function halfSample(inImgWrapper, outImgWrapper) { var inImg = inImgWrapper.data; var inWidth = inImgWrapper.size.x; var outImg = outImgWrapper.data; var topRowIdx = 0; var bottomRowIdx = inWidth; var endIdx = inImg.length; var outWidth = inWidth / 2; var outImgIdx = 0; while (bottomRowIdx < endIdx) { for (var i = 0; i < outWidth; i++) { outImg[outImgIdx] = Math.floor((inImg[topRowIdx] + inImg[topRowIdx + 1] + inImg[bottomRowIdx] + inImg[bottomRowIdx + 1]) / 4); outImgIdx++; topRowIdx += 2; bottomRowIdx += 2; } topRowIdx += inWidth; bottomRowIdx += inWidth; } } function hsv2rgb(hsv) { var rgb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0, 0, 0]; var h = hsv[0]; var s = hsv[1]; var v = hsv[2]; var c = v * s; var x = c * (1 - Math.abs(h / 60 % 2 - 1)); var m = v - c; var r = 0; var g = 0; var b = 0; if (h < 60) { r = c; g = x; } else if (h < 120) { r = x; g = c; } else if (h < 180) { g = c; b = x; } else if (h < 240) { g = x; b = c; } else if (h < 300) { r = x; b = c; } else if (h < 360) { r = c; b = x; } // eslint-disable-next-line no-param-reassign rgb[0] = (r + m) * 255 | 0; // eslint-disable-next-line no-param-reassign rgb[1] = (g + m) * 255 | 0; // eslint-disable-next-line no-param-reassign rgb[2] = (b + m) * 255 | 0; return rgb; } function _computeDivisors(n) { var largeDivisors = []; var divisors = []; for (var i = 1; i < Math.sqrt(n) + 1; i++) { if (n % i === 0) { divisors.push(i); if (i !== n / i) { largeDivisors.unshift(Math.floor(n / i)); } } } return divisors.concat(largeDivisors); } function _computeIntersection(arr1, arr2) { var i = 0; var j = 0; var result = []; while (i < arr1.length && j < arr2.length) { if (arr1[i] === arr2[j]) { result.push(arr1[i]); i++; j++; } else if (arr1[i] > arr2[j]) { j++; } else { i++; } } return result; } function calculatePatchSize(patchSize, imgSize) { var divisorsX = _computeDivisors(imgSize.x); var divisorsY = _computeDivisors(imgSize.y); var wideSide = Math.max(imgSize.x, imgSize.y); var common = _computeIntersection(divisorsX, divisorsY); var nrOfPatchesList = [8, 10, 15, 20, 32, 60, 80]; var nrOfPatchesMap = { 'x-small': 5, small: 4, medium: 3, large: 2, 'x-large': 1 }; var nrOfPatchesIdx = nrOfPatchesMap[patchSize] || nrOfPatchesMap.medium; var nrOfPatches = nrOfPatchesList[nrOfPatchesIdx]; var desiredPatchSize = Math.floor(wideSide / nrOfPatches); var optimalPatchSize; function findPatchSizeForDivisors(divisors) { var i = 0; var found = divisors[Math.floor(divisors.length / 2)]; while (i < divisors.length - 1 && divisors[i] < desiredPatchSize) { i++; } if (i > 0) { if (Math.abs(divisors[i] - desiredPatchSize) > Math.abs(divisors[i - 1] - desiredPatchSize)) { found = divisors[i - 1]; } else { found = divisors[i]; } } if (desiredPatchSize / found < nrOfPatchesList[nrOfPatchesIdx + 1] / nrOfPatchesList[nrOfPatchesIdx] && desiredPatchSize / found > nrOfPatchesList[nrOfPatchesIdx - 1] / nrOfPatchesList[nrOfPatchesIdx]) { return { x: found, y: found }; } return null; } optimalPatchSize = findPatchSizeForDivisors(common); if (!optimalPatchSize) { optimalPatchSize = findPatchSizeForDivisors(_computeDivisors(wideSide)); if (!optimalPatchSize) { optimalPatchSize = findPatchSizeForDivisors(_computeDivisors(desiredPatchSize * nrOfPatches)); } } return optimalPatchSize; } function _parseCSSDimensionValues(value) { var dimension = { value: parseFloat(value), unit: value.indexOf('%') === value.length - 1 ? '%' : '%' }; return dimension; } var _dimensionsConverters = { top: function top(dimension, context) { return dimension.unit === '%' ? Math.floor(context.height * (dimension.value / 100)) : null; }, right: function right(dimension, context) { return dimension.unit === '%' ? Math.floor(context.width - context.width * (dimension.value / 100)) : null; }, bottom: function bottom(dimension, context) { return dimension.unit === '%' ? Math.floor(context.height - context.height * (dimension.value / 100)) : null; }, left: function left(dimension, context) { return dimension.unit === '%' ? Math.floor(context.width * (dimension.value / 100)) : null; } }; function computeImageArea(inputWidth, inputHeight, area) { var context = { width: inputWidth, height: inputHeight }; var parsedArea = Object.keys(area).reduce(function (result, key) { var value = area[key]; var parsed = _parseCSSDimensionValues(value); var calculated = _dimensionsConverters[key](parsed, context); // eslint-disable-next-line no-param-reassign result[key] = calculated; return result; }, {}); return { sx: parsedArea.left, sy: parsedArea.top, sw: parsedArea.right - parsedArea.left, sh: parsedArea.bottom - parsedArea.top }; } /***/ }), /* 13 */ /***/ (function(module, exports) { function _typeof(o) { "@babel/helpers - typeof"; return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototyp