├── LICENSE ├── README.md └── demo ├── miniprogram ├── app.js ├── app.json ├── app.wxss ├── pages │ └── index │ │ ├── wasm.js │ │ ├── wasm.json │ │ ├── wasm.wxml │ │ └── wasm.wxss ├── project.config.json └── utils │ └── wasm.js └── server ├── README.md ├── haarcascade_eye.xml ├── haarcascade_frontalface_default.xml ├── lena.png ├── opencv.js ├── opencv.wasm ├── opencv.zip ├── opencv_js.js ├── package.json ├── qunit-1.20.0.css ├── qunit-2.0.1.js ├── run_puppeteer.js ├── test_calib3d.js ├── test_features2d.js ├── test_imgproc.js ├── test_mat.js ├── test_objdetect.js ├── test_photo.js ├── test_utils.js ├── test_video.js ├── tests.html └── tests.js /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, 昱霖君 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # opencv.js-wechat 2 | WeChat Mini-program lib for opencv.js 3 | 4 | opencv.js版本为4.3.0 5 | 6 | 通过webAssembly执行 7 | 8 | ## 示例 9 | 10 | ### 小程序 11 | 12 | 将demo\miniprogram里的项目导入到开发者工具,点击预览,手机上打开调试后,先点击"获取wasm",约5-10秒初始化完成。 13 | 14 | 1.点击"灰度lena",查看是否正常显示灰色的Lena图片。 15 | 16 | 2.点击"捕获相机",约5-10秒加载完成后,查看是否正常追踪面部(红框)以及眼睛(蓝框)。 17 | 18 | ### 服务端 19 | 20 | 在demo\server里执行"npx http-server ./",在浏览器中打开"http://localhost:8080/tests.html",查看是否通过测试。 21 | 22 | ## API 23 | 24 | ### wasm 25 | 26 | ``` 27 | wasm.init({ 28 | url:"http://www.aiotforest.com/opencv.zip", // wasm或zip文件网址 29 | type:"zip", // 格式:wasm,zip(仅压缩了wasm的压缩包) 30 | useCache:true, // 是否使用缓存(开启缓存会将wasm存入用户本地文件,节省下次请求流量) 31 | self:this, // 传入全局环境 32 | success: function (Module) {// Module为opencv对象 33 | } 34 | }) 35 | ``` 36 | 37 | ### opencv 38 | 39 | 具体请访问[opencv.js docs](https://docs.opencv.org/4.3.0/d5/d10/tutorial_js_root.html) 40 | 41 | server中编译的wasm配置包含以下参数: 42 | ``` 43 | core = {'': ['absdiff', 'add', 'addWeighted', 'bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', 'cartToPolar',\ 44 | 'compare', 'convertScaleAbs', 'copyMakeBorder', 'countNonZero', 'determinant', 'dft', 'divide', 'eigen', \ 45 | 'exp', 'flip', 'getOptimalDFTSize','gemm', 'hconcat', 'inRange', 'invert', 'kmeans', 'log', 'magnitude', \ 46 | 'max', 'mean', 'meanStdDev', 'merge', 'min', 'minMaxLoc', 'mixChannels', 'multiply', 'norm', 'normalize', \ 47 | 'perspectiveTransform', 'polarToCart', 'pow', 'randn', 'randu', 'reduce', 'repeat', 'rotate', 'setIdentity', 'setRNGSeed', \ 48 | 'solve', 'solvePoly', 'split', 'sqrt', 'subtract', 'trace', 'transform', 'transpose', 'vconcat'], 49 | 'Algorithm': []} 50 | 51 | imgproc = {'': ['Canny', 'GaussianBlur', 'Laplacian', 'HoughLines', 'HoughLinesP', 'HoughCircles', 'Scharr','Sobel', \ 52 | 'adaptiveThreshold','approxPolyDP','arcLength','bilateralFilter','blur','boundingRect','boxFilter',\ 53 | 'calcBackProject','calcHist','circle','compareHist','connectedComponents','connectedComponentsWithStats', \ 54 | 'contourArea', 'convexHull', 'convexityDefects', 'cornerHarris','cornerMinEigenVal','createCLAHE', \ 55 | 'createLineSegmentDetector','cvtColor','demosaicing','dilate', 'distanceTransform','distanceTransformWithLabels', \ 56 | 'drawContours','ellipse','ellipse2Poly','equalizeHist','erode', 'filter2D', 'findContours','fitEllipse', \ 57 | 'fitLine', 'floodFill','getAffineTransform', 'getPerspectiveTransform', 'getRotationMatrix2D', 'getStructuringElement', \ 58 | 'goodFeaturesToTrack','grabCut','initUndistortRectifyMap', 'integral','integral2', 'isContourConvex', 'line', \ 59 | 'matchShapes', 'matchTemplate','medianBlur', 'minAreaRect', 'minEnclosingCircle', 'moments', 'morphologyEx', \ 60 | 'pointPolygonTest', 'putText','pyrDown','pyrUp','rectangle','remap', 'resize','sepFilter2D','threshold', \ 61 | 'undistort','warpAffine','warpPerspective','warpPolar','watershed', \ 62 | 'fillPoly', 'fillConvexPoly'], 63 | 'CLAHE': ['apply', 'collectGarbage', 'getClipLimit', 'getTilesGridSize', 'setClipLimit', 'setTilesGridSize']} 64 | 65 | objdetect = {'': ['groupRectangles'], 66 | 'HOGDescriptor': ['load', 'HOGDescriptor', 'getDefaultPeopleDetector', 'getDaimlerPeopleDetector', 'setSVMDetector', 'detectMultiScale'], 67 | 'CascadeClassifier': ['load', 'detectMultiScale2', 'CascadeClassifier', 'detectMultiScale3', 'empty', 'detectMultiScale']} 68 | 69 | video = {'': ['CamShift', 'calcOpticalFlowFarneback', 'calcOpticalFlowPyrLK', 'createBackgroundSubtractorMOG2', \ 70 | 'findTransformECC', 'meanShift'], 71 | 'BackgroundSubtractorMOG2': ['BackgroundSubtractorMOG2', 'apply'], 72 | 'BackgroundSubtractor': ['apply', 'getBackgroundImage']} 73 | 74 | dnn = {'dnn_Net': ['setInput', 'forward'], 75 | '': ['readNetFromCaffe', 'readNetFromTensorflow', 'readNetFromTorch', 'readNetFromDarknet', 76 | 'readNetFromONNX', 'readNet', 'blobFromImage']} 77 | 78 | features2d = {'Feature2D': ['detect', 'compute', 'detectAndCompute', 'descriptorSize', 'descriptorType', 'defaultNorm', 'empty', 'getDefaultName'], 79 | 'BRISK': ['create', 'getDefaultName'], 80 | 'ORB': ['create', 'setMaxFeatures', 'setScaleFactor', 'setNLevels', 'setEdgeThreshold', 'setFirstLevel', 'setWTA_K', 'setScoreType', 'setPatchSize', 'getFastThreshold', 'getDefaultName'], 81 | 'MSER': ['create', 'detectRegions', 'setDelta', 'getDelta', 'setMinArea', 'getMinArea', 'setMaxArea', 'getMaxArea', 'setPass2Only', 'getPass2Only', 'getDefaultName'], 82 | 'FastFeatureDetector': ['create', 'setThreshold', 'getThreshold', 'setNonmaxSuppression', 'getNonmaxSuppression', 'setType', 'getType', 'getDefaultName'], 83 | 'AgastFeatureDetector': ['create', 'setThreshold', 'getThreshold', 'setNonmaxSuppression', 'getNonmaxSuppression', 'setType', 'getType', 'getDefaultName'], 84 | 'GFTTDetector': ['create', 'setMaxFeatures', 'getMaxFeatures', 'setQualityLevel', 'getQualityLevel', 'setMinDistance', 'getMinDistance', 'setBlockSize', 'getBlockSize', 'setHarrisDetector', 'getHarrisDetector', 'setK', 'getK', 'getDefaultName'], 85 | # 'SimpleBlobDetector': ['create'], 86 | 'KAZE': ['create', 'setExtended', 'getExtended', 'setUpright', 'getUpright', 'setThreshold', 'getThreshold', 'setNOctaves', 'getNOctaves', 'setNOctaveLayers', 'getNOctaveLayers', 'setDiffusivity', 'getDiffusivity', 'getDefaultName'], 87 | 'AKAZE': ['create', 'setDescriptorType', 'getDescriptorType', 'setDescriptorSize', 'getDescriptorSize', 'setDescriptorChannels', 'getDescriptorChannels', 'setThreshold', 'getThreshold', 'setNOctaves', 'getNOctaves', 'setNOctaveLayers', 'getNOctaveLayers', 'setDiffusivity', 'getDiffusivity', 'getDefaultName'], 88 | 'DescriptorMatcher': ['add', 'clear', 'empty', 'isMaskSupported', 'train', 'match', 'knnMatch', 'radiusMatch', 'clone', 'create'], 89 | 'BFMatcher': ['isMaskSupported', 'create'], 90 | '': ['drawKeypoints', 'drawMatches', 'drawMatchesKnn']} 91 | 92 | photo = {'': ['createAlignMTB', 'createCalibrateDebevec', 'createCalibrateRobertson', \ 93 | 'createMergeDebevec', 'createMergeMertens', 'createMergeRobertson', \ 94 | 'createTonemapDrago', 'createTonemapMantiuk', 'createTonemapReinhard', 'inpaint'], 95 | 'CalibrateCRF': ['process'], 96 | 'AlignMTB' : ['calculateShift', 'shiftMat', 'computeBitmaps', 'getMaxBits', 'setMaxBits', \ 97 | 'getExcludeRange', 'setExcludeRange', 'getCut', 'setCut'], 98 | 'CalibrateDebevec' : ['getLambda', 'setLambda', 'getSamples', 'setSamples', 'getRandom', 'setRandom'], 99 | 'CalibrateRobertson' : ['getMaxIter', 'setMaxIter', 'getThreshold', 'setThreshold', 'getRadiance'], 100 | 'MergeExposures' : ['process'], 101 | 'MergeDebevec' : ['process'], 102 | 'MergeMertens' : ['process', 'getContrastWeight', 'setContrastWeight', 'getSaturationWeight', \ 103 | 'setSaturationWeight', 'getExposureWeight', 'setExposureWeight'], 104 | 'MergeRobertson' : ['process'], 105 | 'Tonemap' : ['process' , 'getGamma', 'setGamma'], 106 | 'TonemapDrago' : ['getSaturation', 'setSaturation', 'getBias', 'setBias', \ 107 | 'getSigmaColor', 'setSigmaColor', 'getSigmaSpace','setSigmaSpace'], 108 | 'TonemapMantiuk' : ['getScale', 'setScale', 'getSaturation', 'setSaturation'], 109 | 'TonemapReinhard' : ['getIntensity', 'setIntensity', 'getLightAdaptation', 'setLightAdaptation', \ 110 | 'getColorAdaptation', 'setColorAdaptation'] 111 | } 112 | 113 | aruco = {'': ['detectMarkers', 'drawDetectedMarkers', 'drawAxis', 'estimatePoseSingleMarkers', 'estimatePoseBoard', 'estimatePoseCharucoBoard', 'interpolateCornersCharuco', 'drawDetectedCornersCharuco'], 114 | 'aruco_Dictionary': ['get', 'drawMarker'], 115 | 'aruco_Board': ['create'], 116 | 'aruco_GridBoard': ['create', 'draw'], 117 | 'aruco_CharucoBoard': ['create', 'draw'], 118 | } 119 | 120 | calib3d = {'': ['findHomography', 'calibrateCameraExtended', 'drawFrameAxes', 'estimateAffine2D', 'getDefaultNewCameraMatrix', 'initUndistortRectifyMap', 'Rodrigues']} 121 | 122 | 123 | white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d, photo, aruco, calib3d]) 124 | 125 | ``` 126 | -------------------------------------------------------------------------------- /demo/miniprogram/app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | }, 5 | globalData: { 6 | } 7 | }) -------------------------------------------------------------------------------- /demo/miniprogram/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/wasm" 4 | ], 5 | "window": { 6 | "backgroundTextStyle": "light", 7 | "navigationBarBackgroundColor": "#fff", 8 | "navigationBarTitleText": "WeChat", 9 | "navigationBarTextStyle": "black" 10 | }, 11 | "style": "v2", 12 | "sitemapLocation": "sitemap.json" 13 | } -------------------------------------------------------------------------------- /demo/miniprogram/app.wxss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leo9960/opencv.js-wechat/b36f0651329bde44707e65900ae27d1251f55e4b/demo/miniprogram/app.wxss -------------------------------------------------------------------------------- /demo/miniprogram/pages/index/wasm.js: -------------------------------------------------------------------------------- 1 | var wasm = require("../../utils/wasm"); 2 | var cv; 3 | var listener; 4 | Page({ 5 | 6 | data: { 7 | 8 | }, 9 | getwasm: function () { 10 | wasm.init({ 11 | url:"http://www.aiotforest.com/opencv.zip", 12 | type:"zip", //格式:wasm,zip 13 | useCache:true, //是否使用缓存 14 | self:this, 15 | success: function (Module) { 16 | cv=Module; 17 | console.log(cv); 18 | } 19 | }) 20 | }, 21 | getgray: function () { 22 | cv.imread("http://www.aiotforest.com/lena.png",function(mat){ 23 | let src = mat; 24 | let dstx = new cv.Mat(); 25 | cv.cvtColor(src, src, cv.COLOR_RGB2GRAY, 0); 26 | cv.imshow(src); 27 | src.delete(); 28 | dstx.delete(); 29 | }); 30 | }, 31 | getcamera:function(){ 32 | var self=this; 33 | if(!this.facexmlflag){ 34 | this.facexmlflag=true; 35 | wx.downloadFile({ 36 | url: 'http://www.aiotforest.com/haarcascade_frontalface_default.xml', 37 | filePath:cv.USER_DATA_PATH+"/haarcascade_frontalface_default.xml", 38 | success:function(){ 39 | self.faceflag=true; 40 | } 41 | }) 42 | } 43 | if(!this.eyesxmlflag){ 44 | this.eyesxmlflag=true; 45 | wx.downloadFile({ 46 | url: 'http://www.aiotforest.com/haarcascade_eye.xml', 47 | filePath:cv.USER_DATA_PATH+"/haarcascade_eye.xml", 48 | success:function(){ 49 | self.eyesflag=true; 50 | } 51 | }) 52 | } 53 | if(this.faceflag&&this.eyesflag){ 54 | cv.FS_createDataFile("/", "haarcascade_frontalface_default.xml", new Uint8Array(cv.FSM.readFileSync(cv.USER_DATA_PATH+"haarcascade_frontalface_default.xml")), true, false, undefined); 55 | self.faceCascade = new cv.CascadeClassifier(); 56 | self.faceCascade.load("/haarcascade_frontalface_default.xml"); 57 | 58 | cv.FS_createDataFile("/", "haarcascade_eye.xml", new Uint8Array(cv.FSM.readFileSync(cv.USER_DATA_PATH+"haarcascade_eye.xml")), true, false, undefined); 59 | self.eyesCascade = new cv.CascadeClassifier(); 60 | self.eyesCascade.load("/haarcascade_eye.xml"); 61 | 62 | const context = wx.createCameraContext() 63 | listener = context.onCameraFrame((frame) => { 64 | self.cameraData=frame; 65 | }) 66 | listener.start(); 67 | self.detectloop(); 68 | }else{ 69 | setTimeout(this.getcamera,100); 70 | } 71 | }, 72 | facexmlflag:false, 73 | eyesxmlflag:false, 74 | faceflag:false, 75 | eyesflag:false, 76 | cameraData:undefined, 77 | detectloop:function(){ 78 | var self=this; 79 | if(typeof self.cameraData=="object"){ 80 | self.detectFace(self.cameraData); 81 | setTimeout(self.detectloop,0); 82 | }else{ 83 | setTimeout(self.detectloop,100); 84 | } 85 | }, 86 | detectFace:function(frame){ 87 | var self=this; 88 | var src = cv.matFromImageData({ 89 | data:new Uint8ClampedArray(frame.data), 90 | width:frame.width, 91 | height:frame.height 92 | }); 93 | var gray = new cv.Mat(); 94 | cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0); 95 | var faces = new cv.RectVector(); 96 | let eyes = new cv.RectVector(); 97 | var faceCascade = self.faceCascade; 98 | faceCascade.detectMultiScale(gray, faces, 1.1, 5, 0); 99 | for (var i = 0; i < faces.size(); ++i) { 100 | var roiGray = gray.roi(faces.get(i)); 101 | var roiSrc = src.roi(faces.get(i)); 102 | var point1 = new cv.Point(faces.get(i).x, faces.get(i).y); 103 | var point2 = new cv.Point(faces.get(i).x + faces.get(i).width, 104 | faces.get(i).y + faces.get(i).height); 105 | cv.rectangle(src, point1, point2, [255, 0, 0, 255]); 106 | 107 | var eyesCascade = self.eyesCascade; 108 | eyesCascade.detectMultiScale(roiGray, eyes); 109 | for (let j = 0; j < eyes.size(); ++j) { 110 | let point1 = new cv.Point(eyes.get(j).x, eyes.get(j).y); 111 | let point2 = new cv.Point(eyes.get(j).x + eyes.get(j).width, 112 | eyes.get(j).y + eyes.get(j).height); 113 | cv.rectangle(roiSrc, point1, point2, [0, 0, 255, 255]); 114 | } 115 | 116 | roiGray.delete(); 117 | roiSrc.delete(); 118 | } 119 | cv.imshow(src); 120 | src.delete(); 121 | gray.delete(); 122 | faces.delete(); 123 | }, 124 | stop:function(){ 125 | listener.stop(); 126 | }, 127 | /** 128 | * 生命周期函数--监听页面加载 129 | */ 130 | onLoad: function (options) { 131 | 132 | }, 133 | 134 | /** 135 | * 生命周期函数--监听页面初次渲染完成 136 | */ 137 | onReady: function () {}, 138 | 139 | /** 140 | * 生命周期函数--监听页面显示 141 | */ 142 | onShow: function () { 143 | 144 | }, 145 | 146 | /** 147 | * 生命周期函数--监听页面隐藏 148 | */ 149 | onHide: function () { 150 | 151 | }, 152 | 153 | /** 154 | * 生命周期函数--监听页面卸载 155 | */ 156 | onUnload: function () { 157 | 158 | }, 159 | 160 | /** 161 | * 页面相关事件处理函数--监听用户下拉动作 162 | */ 163 | onPullDownRefresh: function () { 164 | 165 | }, 166 | 167 | /** 168 | * 页面上拉触底事件的处理函数 169 | */ 170 | onReachBottom: function () { 171 | 172 | }, 173 | 174 | /** 175 | * 用户点击右上角分享 176 | */ 177 | onShareAppMessage: function () { 178 | 179 | } 180 | }) -------------------------------------------------------------------------------- /demo/miniprogram/pages/index/wasm.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /demo/miniprogram/pages/index/wasm.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /demo/miniprogram/pages/index/wasm.wxss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leo9960/opencv.js-wechat/b36f0651329bde44707e65900ae27d1251f55e4b/demo/miniprogram/pages/index/wasm.wxss -------------------------------------------------------------------------------- /demo/miniprogram/project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "setting": { 7 | "urlCheck": false, 8 | "es6": false, 9 | "postcss": true, 10 | "minified": true, 11 | "newFeature": true, 12 | "coverView": true, 13 | "autoAudits": false, 14 | "showShadowRootInWxmlPanel": true, 15 | "scopeDataCheck": false, 16 | "checkInvalidKey": true, 17 | "checkSiteMap": true, 18 | "uploadWithSourceMap": true, 19 | "babelSetting": { 20 | "ignore": [], 21 | "disablePlugins": [], 22 | "outputPath": "" 23 | } 24 | }, 25 | "compileType": "miniprogram", 26 | "libVersion": "2.11.1", 27 | "appid": "", 28 | "projectname": "opencv_wasm", 29 | "debugOptions": { 30 | "hidedInDevtools": [] 31 | }, 32 | "isGameTourist": false, 33 | "simulatorType": "wechat", 34 | "simulatorPluginLibVersion": {}, 35 | "condition": { 36 | "search": { 37 | "current": -1, 38 | "list": [] 39 | }, 40 | "conversation": { 41 | "current": -1, 42 | "list": [] 43 | }, 44 | "game": { 45 | "currentL": -1, 46 | "list": [] 47 | }, 48 | "miniprogram": { 49 | "current": -1, 50 | "list": [] 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /demo/server/README.md: -------------------------------------------------------------------------------- 1 | # Server 2 | 3 | npx http-server ./ 4 | 5 | ``` 6 | http://localhost:8080/tests.html 7 | ``` -------------------------------------------------------------------------------- /demo/server/lena.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leo9960/opencv.js-wechat/b36f0651329bde44707e65900ae27d1251f55e4b/demo/server/lena.png -------------------------------------------------------------------------------- /demo/server/opencv.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leo9960/opencv.js-wechat/b36f0651329bde44707e65900ae27d1251f55e4b/demo/server/opencv.wasm -------------------------------------------------------------------------------- /demo/server/opencv.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leo9960/opencv.js-wechat/b36f0651329bde44707e65900ae27d1251f55e4b/demo/server/opencv.zip -------------------------------------------------------------------------------- /demo/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "opencv_js_tests", 3 | "description": "Tests for opencv js bindings", 4 | "version": "1.0.1", 5 | "dependencies": { 6 | "ansi-colors": "^4.1.1", 7 | "minimist": "^1.2.0", 8 | "node-qunit": "latest" 9 | }, 10 | "devDependencies": { 11 | "eslint": "latest", 12 | "eslint-config-google": "latest" 13 | }, 14 | "scripts": { 15 | "test": "node tests.js" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/opencv/opencv.git" 20 | }, 21 | "keywords": [], 22 | "author": "", 23 | "license": "BSD-3-Clause", 24 | "bugs": { 25 | "url": "https://github.com/opencv/opencv/issues" 26 | }, 27 | "homepage": "https://github.com/opencv/opencv" 28 | } 29 | -------------------------------------------------------------------------------- /demo/server/qunit-1.20.0.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * QUnit 1.20.0 3 | * http://qunitjs.com/ 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license 7 | * http://jquery.org/license 8 | * 9 | * Date: 2015-10-27T17:53Z 10 | */ 11 | 12 | /** Font Family and Sizes */ 13 | 14 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult { 15 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 16 | } 17 | 18 | #qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 19 | #qunit-tests { font-size: smaller; } 20 | 21 | 22 | /** Resets */ 23 | 24 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { 25 | margin: 0; 26 | padding: 0; 27 | } 28 | 29 | 30 | /** Header */ 31 | 32 | #qunit-header { 33 | padding: 0.5em 0 0.5em 1em; 34 | 35 | color: #8699A4; 36 | background-color: #0D3349; 37 | 38 | font-size: 1.5em; 39 | line-height: 1em; 40 | font-weight: 400; 41 | 42 | border-radius: 5px 5px 0 0; 43 | } 44 | 45 | #qunit-header a { 46 | text-decoration: none; 47 | color: #C2CCD1; 48 | } 49 | 50 | #qunit-header a:hover, 51 | #qunit-header a:focus { 52 | color: #FFF; 53 | } 54 | 55 | #qunit-testrunner-toolbar label { 56 | display: inline-block; 57 | padding: 0 0.5em 0 0.1em; 58 | } 59 | 60 | #qunit-banner { 61 | height: 5px; 62 | } 63 | 64 | #qunit-testrunner-toolbar { 65 | padding: 0.5em 1em 0.5em 1em; 66 | color: #5E740B; 67 | background-color: #EEE; 68 | overflow: hidden; 69 | } 70 | 71 | #qunit-filteredTest { 72 | padding: 0.5em 1em 0.5em 1em; 73 | background-color: #F4FF77; 74 | color: #366097; 75 | } 76 | 77 | #qunit-userAgent { 78 | padding: 0.5em 1em 0.5em 1em; 79 | background-color: #2B81AF; 80 | color: #FFF; 81 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 82 | } 83 | 84 | #qunit-modulefilter-container { 85 | float: right; 86 | padding: 0.2em; 87 | } 88 | 89 | .qunit-url-config { 90 | display: inline-block; 91 | padding: 0.1em; 92 | } 93 | 94 | .qunit-filter { 95 | display: block; 96 | float: right; 97 | margin-left: 1em; 98 | } 99 | 100 | /** Tests: Pass/Fail */ 101 | 102 | #qunit-tests { 103 | list-style-position: inside; 104 | } 105 | 106 | #qunit-tests li { 107 | padding: 0.4em 1em 0.4em 1em; 108 | border-bottom: 1px solid #FFF; 109 | list-style-position: inside; 110 | } 111 | 112 | #qunit-tests > li { 113 | display: none; 114 | } 115 | 116 | #qunit-tests li.running, 117 | #qunit-tests li.pass, 118 | #qunit-tests li.fail, 119 | #qunit-tests li.skipped { 120 | display: list-item; 121 | } 122 | 123 | #qunit-tests.hidepass li.running, 124 | #qunit-tests.hidepass li.pass { 125 | visibility: hidden; 126 | position: absolute; 127 | width: 0; 128 | height: 0; 129 | padding: 0; 130 | border: 0; 131 | margin: 0; 132 | } 133 | 134 | #qunit-tests li strong { 135 | cursor: pointer; 136 | } 137 | 138 | #qunit-tests li.skipped strong { 139 | cursor: default; 140 | } 141 | 142 | #qunit-tests li a { 143 | padding: 0.5em; 144 | color: #C2CCD1; 145 | text-decoration: none; 146 | } 147 | 148 | #qunit-tests li p a { 149 | padding: 0.25em; 150 | color: #6B6464; 151 | } 152 | #qunit-tests li a:hover, 153 | #qunit-tests li a:focus { 154 | color: #000; 155 | } 156 | 157 | #qunit-tests li .runtime { 158 | float: right; 159 | font-size: smaller; 160 | } 161 | 162 | .qunit-assert-list { 163 | margin-top: 0.5em; 164 | padding: 0.5em; 165 | 166 | background-color: #FFF; 167 | 168 | border-radius: 5px; 169 | } 170 | 171 | .qunit-source { 172 | margin: 0.6em 0 0.3em; 173 | } 174 | 175 | .qunit-collapsed { 176 | display: none; 177 | } 178 | 179 | #qunit-tests table { 180 | border-collapse: collapse; 181 | margin-top: 0.2em; 182 | } 183 | 184 | #qunit-tests th { 185 | text-align: right; 186 | vertical-align: top; 187 | padding: 0 0.5em 0 0; 188 | } 189 | 190 | #qunit-tests td { 191 | vertical-align: top; 192 | } 193 | 194 | #qunit-tests pre { 195 | margin: 0; 196 | white-space: pre-wrap; 197 | word-wrap: break-word; 198 | } 199 | 200 | #qunit-tests del { 201 | background-color: #E0F2BE; 202 | color: #374E0C; 203 | text-decoration: none; 204 | } 205 | 206 | #qunit-tests ins { 207 | background-color: #FFCACA; 208 | color: #500; 209 | text-decoration: none; 210 | } 211 | 212 | /*** Test Counts */ 213 | 214 | #qunit-tests b.counts { color: #000; } 215 | #qunit-tests b.passed { color: #5E740B; } 216 | #qunit-tests b.failed { color: #710909; } 217 | 218 | #qunit-tests li li { 219 | padding: 5px; 220 | background-color: #FFF; 221 | border-bottom: none; 222 | list-style-position: inside; 223 | } 224 | 225 | /*** Passing Styles */ 226 | 227 | #qunit-tests li li.pass { 228 | color: #3C510C; 229 | background-color: #FFF; 230 | border-left: 10px solid #C6E746; 231 | } 232 | 233 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } 234 | #qunit-tests .pass .test-name { color: #366097; } 235 | 236 | #qunit-tests .pass .test-actual, 237 | #qunit-tests .pass .test-expected { color: #999; } 238 | 239 | #qunit-banner.qunit-pass { background-color: #C6E746; } 240 | 241 | /*** Failing Styles */ 242 | 243 | #qunit-tests li li.fail { 244 | color: #710909; 245 | background-color: #FFF; 246 | border-left: 10px solid #EE5757; 247 | white-space: pre; 248 | } 249 | 250 | #qunit-tests > li:last-child { 251 | border-radius: 0 0 5px 5px; 252 | } 253 | 254 | #qunit-tests .fail { color: #000; background-color: #EE5757; } 255 | #qunit-tests .fail .test-name, 256 | #qunit-tests .fail .module-name { color: #000; } 257 | 258 | #qunit-tests .fail .test-actual { color: #EE5757; } 259 | #qunit-tests .fail .test-expected { color: #008000; } 260 | 261 | #qunit-banner.qunit-fail { background-color: #EE5757; } 262 | 263 | /*** Skipped tests */ 264 | 265 | #qunit-tests .skipped { 266 | background-color: #EBECE9; 267 | } 268 | 269 | #qunit-tests .qunit-skipped-label { 270 | background-color: #F4FF77; 271 | display: inline-block; 272 | font-style: normal; 273 | color: #366097; 274 | line-height: 1.8em; 275 | padding: 0 0.5em; 276 | margin: -0.4em 0.4em -0.4em 0; 277 | } 278 | 279 | /** Result */ 280 | 281 | #qunit-testresult { 282 | padding: 0.5em 1em 0.5em 1em; 283 | 284 | color: #2B81AF; 285 | background-color: #D2E0E6; 286 | 287 | border-bottom: 1px solid #FFF; 288 | } 289 | #qunit-testresult .module-name { 290 | font-weight: 700; 291 | } 292 | 293 | /** Fixture */ 294 | 295 | #qunit-fixture { 296 | position: absolute; 297 | top: -10000px; 298 | left: -10000px; 299 | width: 1000px; 300 | height: 1000px; 301 | } 302 | -------------------------------------------------------------------------------- /demo/server/run_puppeteer.js: -------------------------------------------------------------------------------- 1 | try { 2 | require('puppeteer') 3 | } catch (e) { 4 | console.error( 5 | "\nFATAL ERROR:" + 6 | "\n Package 'puppeteer' is not available." + 7 | "\n Run 'npm install --no-save puppeteer' before running this script" + 8 | "\n * You may use PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 environment variable to avoid automatic Chromium downloading" + 9 | "\n (specify own Chromium/Chrome version through PUPPETEER_EXECUTABLE_PATH=`which google-chrome` environment variable)" + 10 | "\n"); 11 | process.exit(1); 12 | } 13 | const puppeteer = require('puppeteer') 14 | const colors = require("ansi-colors") 15 | const path = require("path"); 16 | const fs = require("fs"); 17 | const http = require("http"); 18 | 19 | run_main(require('minimist')(process.argv.slice(2))); 20 | 21 | async function run_main(o = {}) { 22 | try { 23 | await main(o); 24 | console.magenta("FATAL: Unexpected exit!"); 25 | process.exit(1); 26 | } catch (e) { 27 | console.error(colors.magenta("FATAL: Unexpected exception!")); 28 | console.error(e); 29 | process.exit(1); 30 | } 31 | } 32 | 33 | async function main(o = {}) { 34 | o = Object.assign({}, { 35 | buildFolder: __dirname, 36 | port: 8080, 37 | debug: false, 38 | noHeadless: false, 39 | serverPrefix: `http://localhost`, 40 | noExit: false, 41 | screenshot: undefined, 42 | help: false, 43 | noTryCatch: false, 44 | maxBlockDuration: 30000 45 | }, o) 46 | if (typeof o.screenshot == 'string' && o.screenshot == 'false') { 47 | console.log(colors.red('ERROR: misused screenshot option, use --no-screenshot instead')); 48 | } 49 | if (o.noExit) { 50 | o.maxBlockDuration = 999999999 51 | } 52 | o.debug && console.log('Current Options', o); 53 | if (o.help) { 54 | printHelpAndExit(); 55 | } 56 | const serverAddress = `${o.serverPrefix}:${o.port}` 57 | const url = `${serverAddress}/tests.html${o.noTryCatch ? '?notrycatch=1' : ''}`; 58 | if (!fs.existsSync(o.buildFolder)) { 59 | console.error(`Expected folder "${o.buildFolder}" to exists. Aborting`); 60 | } 61 | o.debug && debug('Server Listening at ' + url); 62 | const server = await staticServer(o.buildFolder, o.port, m => debug, m => error); 63 | o.debug && debug(`Browser launching ${!o.noHeadless ? 'headless' : 'not headless'}`); 64 | const browser = await puppeteer.launch({ headless: !o.noHeadless }); 65 | const page = await browser.newPage(); 66 | page.on('console', e => { 67 | locationMsg = formatMessage(`${e.location().url}:${e.location().lineNumber}:${e.location().columnNumber}`); 68 | if (e.type() === 'error') { 69 | console.log(colors.red(formatMessage('' + e.text(), `-- ERROR:${locationMsg}: `, ))); 70 | } 71 | else if (o.debug) { 72 | o.debug && console.log(colors.grey(formatMessage('' + e.text(), `-- ${locationMsg}: `))); 73 | } 74 | }); 75 | o.debug && debug(`Opening page address ${url}`); 76 | await page.goto(url); 77 | await page.waitForFunction(() => (document.querySelector(`#qunit-testresult`) && document.querySelector(`#qunit-testresult`).textContent || '').trim().toLowerCase().startsWith('tests completed')); 78 | const text = await getText(`#qunit-testresult`); 79 | if (!text) { 80 | return await fail(`An error occurred extracting test results. Check the build folder ${o.buildFolder} is correct and has build with tests enabled.`); 81 | } 82 | o.debug && debug(colors.blackBright("* UserAgent: " + await getText('#qunit-userAgent'))); 83 | const testFailed = !text.includes(' 0 failed'); 84 | if (testFailed && !o.debug) { 85 | process.stdout.write(colors.grey("* Use '--debug' parameter to see details of failed tests.\n")); 86 | } 87 | if (o.screenshot || (o.screenshot === undefined && testFailed)) { 88 | await page.screenshot({ path: 'screenshot.png', fullPage: 'true' }); 89 | process.stdout.write(colors.grey(`* Screenshot taken: ${o.buildFolder}/screenshot.png\n`)); 90 | } 91 | if (testFailed) { 92 | const report = await failReport(); 93 | process.stdout.write(` 94 | ${colors.red.bold.underline('Failed tests ! :(')} 95 | 96 | ${colors.redBright(colors.symbols.cross + ' ' + report.join(`\n${colors.symbols.cross} `))} 97 | 98 | ${colors.redBright(`=== Summary ===\n${text}`)} 99 | `); 100 | } 101 | else { 102 | process.stdout.write(colors.green(` 103 | ${colors.symbols.check} No Errors :) 104 | 105 | === Summary ===\n${text} 106 | `)); 107 | } 108 | if (o.noExit) { 109 | while (true) { 110 | await new Promise(r => setTimeout(r, 5000)); 111 | } 112 | } 113 | await server && server.close(); 114 | await browser.close(); 115 | process.exit(testFailed ? 1 : 0); 116 | 117 | async function getText(s) { 118 | return await page.evaluate((s) => (document.querySelector(s) && document.querySelector(s).innerText) || ''.trim(), s); 119 | } 120 | async function failReport() { 121 | const failures = await page.evaluate(() => Array.from(document.querySelectorAll('#qunit-tests .fail')).filter(e => e.querySelector('.module-name')).map(e => ({ 122 | moduleName: e.querySelector('.module-name') && e.querySelector('.module-name').textContent, 123 | testName: e.querySelector('.test-name') && e.querySelector('.test-name').textContent, 124 | expected: e.querySelector('.test-expected pre') && e.querySelector('.test-expected pre').textContent, 125 | actual: e.querySelector('.test-actual pre') && e.querySelector('.test-actual pre').textContent, 126 | code: e.querySelector('.test-source') && e.querySelector('.test-source').textContent.replace("Source: at ", ""), 127 | }))); 128 | return failures.map(f => `${f.moduleName}: ${f.testName} (${formatMessage(f.code)})`); 129 | } 130 | async function fail(s) { 131 | await failReport(); 132 | process.stdout.write(colors.red(s) + '\n'); 133 | if (o.screenshot || o.screenshot === undefined) { 134 | await page.screenshot({ path: 'screenshot.png', fullPage: 'true' }); 135 | process.stdout.write(colors.grey(`* Screenshot taken: ${o.buildFolder}/screenshot.png\n`)); 136 | } 137 | process.exit(1); 138 | } 139 | async function debug(s) { 140 | process.stdout.write(s + '\n'); 141 | } 142 | async function error(s) { 143 | process.stdout.write(s + '\n'); 144 | } 145 | function formatMessage(message, prefix) { 146 | prefix = prefix || ''; 147 | return prefix + ('' + message).split('\n').map(l => l.replace(serverAddress, o.buildFolder)).join('\n' + prefix); 148 | } 149 | } 150 | 151 | 152 | function printHelpAndExit() { 153 | console.log(` 154 | Usage: 155 | 156 | # First, remember to build opencv.js with tests enabled: 157 | ${colors.blueBright(`python ./platforms/js/build_js.py build_js --build_test`)} 158 | 159 | # Install the tool locally (needed only once) and run it 160 | ${colors.blueBright(`cd build_js/bin`)} 161 | ${colors.blueBright(`npm install`)} 162 | ${colors.blueBright(`node run_puppeteer`)} 163 | 164 | By default will run a headless browser silently printing a small report in the terminal. 165 | But it could used to debug the tests in the browser, take screenshots, global tool or 166 | targeting external servers exposing the tests. 167 | 168 | TIP: you could install the tool globally (npm install --global build_js/bin) to execute it from any local folder. 169 | 170 | # Options 171 | 172 | * port?: number. Default 8080 173 | * buildFolder?: string. Default __dirname (this folder) 174 | * debug?: boolean. Default false 175 | * noHeadless?: boolean. Default false 176 | * serverPrefix?: string . Default http://localhost 177 | * help?: boolean 178 | * screenshot?: boolean . Make screenshot on failure by default. Use --no-screenshot to disable screenshots completely. 179 | * noExit?: boolean default false. If true it will keep running the server - together with noHeadless you can debug in the browser. 180 | * noTryCatch?: boolean will disable Qunit tryCatch - so exceptions are dump to stdout rather than in the browser. 181 | * maxBlockDuration: QUnit timeout. If noExit is given then is infinity. 182 | `); 183 | process.exit(0); 184 | } 185 | 186 | async function staticServer(basePath, port, onFound, onNotFound) { 187 | return new Promise(async (resolve) => { 188 | const server = http.createServer((req, res) => { 189 | var url = resolveUrl(req.url); 190 | onFound && onFound(url); 191 | var stream = fs.createReadStream(path.join(basePath, url || '')); 192 | stream.on('error', function () { 193 | onNotFound && onNotFound(url); 194 | res.writeHead(404); 195 | res.end(); 196 | }); 197 | stream.pipe(res); 198 | }).listen(port); 199 | server.on('listening', () => { 200 | resolve(server); 201 | }); 202 | }); 203 | function resolveUrl(url = '') { 204 | var i = url.indexOf('?'); 205 | if (i != -1) { 206 | url = url.substr(0, i); 207 | } 208 | i = url.indexOf('#'); 209 | if (i != -1) { 210 | url = url.substr(0, i); 211 | } 212 | return url; 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /demo/server/test_calib3d.js: -------------------------------------------------------------------------------- 1 | // This file is part of OpenCV project. 2 | // It is subject to the license terms in the LICENSE file found in the top-level directory 3 | // of this distribution and at http://opencv.org/license.html. 4 | 5 | if (typeof module !== 'undefined' && module.exports) { 6 | // The environment is Node.js 7 | var cv = require('./opencv.js'); // eslint-disable-line no-var 8 | } 9 | 10 | QUnit.module('Camera Calibration and 3D Reconstruction', {}); 11 | 12 | QUnit.test('constants', function(assert) { 13 | assert.strictEqual(typeof cv.LMEDS, 'number'); 14 | assert.strictEqual(typeof cv.RANSAC, 'number'); 15 | assert.strictEqual(typeof cv.RHO, 'number'); 16 | }); 17 | 18 | QUnit.test('findHomography', function(assert) { 19 | let srcPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [ 20 | 56, 21 | 65, 22 | 368, 23 | 52, 24 | 28, 25 | 387, 26 | 389, 27 | 390, 28 | ]); 29 | let dstPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [ 30 | 0, 31 | 0, 32 | 300, 33 | 0, 34 | 0, 35 | 300, 36 | 300, 37 | 300, 38 | ]); 39 | 40 | const mat = cv.findHomography(srcPoints, dstPoints); 41 | 42 | assert.ok(mat instanceof cv.Mat); 43 | }); 44 | 45 | QUnit.test('Rodrigues', function(assert) { 46 | // Converts a rotation matrix to a rotation vector and vice versa 47 | // data64F is the output array 48 | const rvec0 = cv.matFromArray(1, 3, cv.CV_64F, [1,1,1]); 49 | let rMat0 = new cv.Mat(); 50 | let rvec1 = new cv.Mat(); 51 | 52 | // Args: input Mat, output Mat. The function mutates the output Mat, so the function does not return anything. 53 | // cv.Rodrigues (InputArray=src, OutputArray=dst, jacobian=0) 54 | // https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#void%20Rodrigues(InputArray%20src,%20OutputArray%20dst,%20OutputArray%20jacobian) 55 | // vec to Mat, starting number is 3 long and each element is 1. 56 | cv.Rodrigues(rvec0, rMat0); 57 | 58 | assert.ok(rMat0.data64F.length == 9); 59 | assert.ok(0.23 > rMat0.data64F[0] > 0.22); 60 | 61 | // convert Mat to Vec, should be same as what we started with, 3 long and each item should be a 1. 62 | cv.Rodrigues(rMat0, rvec1); 63 | 64 | assert.ok(rvec1.data64F.length == 3); 65 | assert.ok(1.01 > rvec1.data64F[0] > 0.9); 66 | // Answer should be around 1: 0.9999999999999999 67 | }); 68 | 69 | QUnit.test('estimateAffine2D', function(assert) { 70 | const inputs = cv.matFromArray(4, 1, cv.CV_32FC2, [ 71 | 1, 1, 72 | 80, 0, 73 | 0, 80, 74 | 80, 80 75 | ]); 76 | const outputs = cv.matFromArray(4, 1, cv.CV_32FC2, [ 77 | 21, 51, 78 | 70, 77, 79 | 40, 40, 80 | 10, 70 81 | ]); 82 | const M = cv.estimateAffine2D(inputs, outputs); 83 | assert.ok(M instanceof cv.Mat); 84 | assert.deepEqual(Array.from(M.data), [ 85 | 23, 55, 97, 126, 87, 139, 227, 63, 0, 0, 86 | 0, 0, 0, 0, 232, 191, 71, 246, 12, 68, 87 | 165, 35, 53, 64, 99, 56, 27, 66, 14, 254, 88 | 212, 63, 103, 102, 102, 102, 102, 102, 182, 191, 89 | 195, 252, 174, 22, 55, 97, 73, 64 90 | ]); 91 | }); 92 | -------------------------------------------------------------------------------- /demo/server/test_features2d.js: -------------------------------------------------------------------------------- 1 | // This file is part of OpenCV project. 2 | // It is subject to the license terms in the LICENSE file found in the top-level directory 3 | // of this distribution and at http://opencv.org/license.html. 4 | 5 | if (typeof module !== 'undefined' && module.exports) { 6 | // The environment is Node.js 7 | var cv = require('./opencv.js'); // eslint-disable-line no-var 8 | } 9 | 10 | function generateTestFrame(width, height) { 11 | let w = width || 200; 12 | let h = height || 200; 13 | let img = new cv.Mat(h, w, cv.CV_8UC1, new cv.Scalar(0, 0, 0, 0)); 14 | let s = new cv.Scalar(255, 255, 255, 255); 15 | let s128 = new cv.Scalar(128, 128, 128, 128); 16 | let rect = new cv.Rect(w / 4, h / 4, w / 2, h / 2); 17 | img.roi(rect).setTo(s); 18 | img.roi(new cv.Rect(w / 2 - w / 8, h / 2 - h / 8, w / 4, h / 4)).setTo(s128); 19 | cv.rectangle(img, new cv.Point(w / 8, h / 8), new cv.Point(w - w / 8, h - h / 8), s, 5); 20 | cv.rectangle(img, new cv.Point(w / 5, h / 5), new cv.Point(w - w / 5, h - h / 5), s128, 3); 21 | cv.line(img, new cv.Point(-w, 0), new cv.Point(w / 2, h / 2), s128, 5); 22 | cv.line(img, new cv.Point(2*w, 0), new cv.Point(w / 2, h / 2), s, 5); 23 | return img; 24 | } 25 | 26 | QUnit.module('Features2D', {}); 27 | QUnit.test('Detectors', function(assert) { 28 | let image = generateTestFrame(); 29 | 30 | let kp = new cv.KeyPointVector(); 31 | 32 | let orb = new cv.ORB(); 33 | orb.detect(image, kp); 34 | assert.equal(kp.size(), 67, 'ORB'); 35 | 36 | let mser = new cv.MSER(); 37 | mser.detect(image, kp); 38 | assert.equal(kp.size(), 7, 'MSER'); 39 | 40 | let brisk = new cv.BRISK(); 41 | brisk.detect(image, kp); 42 | assert.equal(kp.size(), 191, 'BRISK'); 43 | 44 | let ffd = new cv.FastFeatureDetector(); 45 | ffd.detect(image, kp); 46 | assert.equal(kp.size(), 12, 'FastFeatureDetector'); 47 | 48 | let afd = new cv.AgastFeatureDetector(); 49 | afd.detect(image, kp); 50 | assert.equal(kp.size(), 67, 'AgastFeatureDetector'); 51 | 52 | let gftt = new cv.GFTTDetector(); 53 | gftt.detect(image, kp); 54 | assert.equal(kp.size(), 168, 'GFTTDetector'); 55 | 56 | let kaze = new cv.KAZE(); 57 | kaze.detect(image, kp); 58 | assert.equal(kp.size(), 159, 'KAZE'); 59 | 60 | let akaze = new cv.AKAZE(); 61 | akaze.detect(image, kp); 62 | assert.equal(kp.size(), 53, 'AKAZE'); 63 | }); 64 | 65 | QUnit.test('BFMatcher', function(assert) { 66 | // Generate key points. 67 | let image = generateTestFrame(); 68 | 69 | let kp = new cv.KeyPointVector(); 70 | let descriptors = new cv.Mat(); 71 | let orb = new cv.ORB(); 72 | orb.detectAndCompute(image, new cv.Mat(), kp, descriptors); 73 | 74 | assert.equal(kp.size(), 67); 75 | 76 | // Run a matcher. 77 | let dm = new cv.DMatchVector(); 78 | let matcher = new cv.BFMatcher(); 79 | matcher.match(descriptors, descriptors, dm); 80 | 81 | assert.equal(dm.size(), 67); 82 | }); 83 | 84 | QUnit.test('Drawing', function(assert) { 85 | // Generate key points. 86 | let image = generateTestFrame(); 87 | 88 | let kp = new cv.KeyPointVector(); 89 | let descriptors = new cv.Mat(); 90 | let orb = new cv.ORB(); 91 | orb.detectAndCompute(image, new cv.Mat(), kp, descriptors); 92 | assert.equal(kp.size(), 67); 93 | 94 | let dst = new cv.Mat(); 95 | cv.drawKeypoints(image, kp, dst); 96 | assert.equal(dst.rows, image.rows); 97 | assert.equal(dst.cols, image.cols); 98 | 99 | // Run a matcher. 100 | let dm = new cv.DMatchVector(); 101 | let matcher = new cv.BFMatcher(); 102 | matcher.match(descriptors, descriptors, dm); 103 | assert.equal(dm.size(), 67); 104 | 105 | cv.drawMatches(image, kp, image, kp, dm, dst); 106 | assert.equal(dst.rows, image.rows); 107 | assert.equal(dst.cols, 2 * image.cols); 108 | 109 | dm = new cv.DMatchVectorVector(); 110 | matcher.knnMatch(descriptors, descriptors, dm, 2); 111 | assert.equal(dm.size(), 67); 112 | cv.drawMatchesKnn(image, kp, image, kp, dm, dst); 113 | assert.equal(dst.rows, image.rows); 114 | assert.equal(dst.cols, 2 * image.cols); 115 | }); 116 | -------------------------------------------------------------------------------- /demo/server/test_imgproc.js: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 | // 5 | // By downloading, copying, installing or using the software you agree to this license. 6 | // If you do not agree to this license, do not download, install, 7 | // copy or use the software. 8 | // 9 | // 10 | // License Agreement 11 | // For Open Source Computer Vision Library 12 | // 13 | // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 14 | // Third party copyrights are property of their respective owners. 15 | // 16 | // Redistribution and use in source and binary forms, with or without modification, 17 | // are permitted provided that the following conditions are met: 18 | // 19 | // * Redistribution's of source code must retain the above copyright notice, 20 | // this list of conditions and the following disclaimer. 21 | // 22 | // * Redistribution's in binary form must reproduce the above copyright notice, 23 | // this list of conditions and the following disclaimer in the documentation 24 | // and/or other materials provided with the distribution. 25 | // 26 | // * The name of the copyright holders may not be used to endorse or promote products 27 | // derived from this software without specific prior written permission. 28 | // 29 | // This software is provided by the copyright holders and contributors "as is" and 30 | // any express or implied warranties, including, but not limited to, the implied 31 | // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 | // In no event shall the Intel Corporation or contributors be liable for any direct, 33 | // indirect, incidental, special, exemplary, or consequential damages 34 | // (including, but not limited to, procurement of substitute goods or services; 35 | // loss of use, data, or profits; or business interruption) however caused 36 | // and on any theory of liability, whether in contract, strict liability, 37 | // or tort (including negligence or otherwise) arising in any way out of 38 | // the use of this software, even if advised of the possibility of such damage. 39 | // 40 | // 41 | 42 | // ////////////////////////////////////////////////////////////////////////////////////// 43 | // Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu 44 | // 45 | // LICENSE AGREEMENT 46 | // Copyright (c) 2015 The Regents of the University of California (Regents) 47 | // 48 | // Redistribution and use in source and binary forms, with or without 49 | // modification, are permitted provided that the following conditions are met: 50 | // 1. Redistributions of source code must retain the above copyright 51 | // notice, this list of conditions and the following disclaimer. 52 | // 2. Redistributions in binary form must reproduce the above copyright 53 | // notice, this list of conditions and the following disclaimer in the 54 | // documentation and/or other materials provided with the distribution. 55 | // 3. Neither the name of the University nor the 56 | // names of its contributors may be used to endorse or promote products 57 | // derived from this software without specific prior written permission. 58 | // 59 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY 60 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 61 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 62 | // DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY 63 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 64 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 65 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 66 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 67 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 68 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69 | // 70 | 71 | if (typeof module !== 'undefined' && module.exports) { 72 | // The environment is Node.js 73 | var cv = require('./opencv.js'); // eslint-disable-line no-var 74 | } 75 | 76 | QUnit.module('Image Processing', {}); 77 | 78 | QUnit.test('test_imgProc', function(assert) { 79 | // calcHist 80 | { 81 | let vec1 = new cv.Mat.ones(new cv.Size(20, 20), cv.CV_8UC1); // eslint-disable-line new-cap 82 | let source = new cv.MatVector(); 83 | source.push_back(vec1); 84 | let channels = [0]; 85 | let histSize = [256]; 86 | let ranges =[0, 256]; 87 | 88 | let hist = new cv.Mat(); 89 | let mask = new cv.Mat(); 90 | let binSize = cv._malloc(4); 91 | let binView = new Int32Array(cv.HEAP8.buffer, binSize); 92 | binView[0] = 10; 93 | cv.calcHist(source, channels, mask, hist, histSize, ranges, false); 94 | 95 | // hist should contains a N X 1 array. 96 | let size = hist.size(); 97 | assert.equal(size.height, 256); 98 | assert.equal(size.width, 1); 99 | 100 | // default parameters 101 | cv.calcHist(source, channels, mask, hist, histSize, ranges); 102 | size = hist.size(); 103 | assert.equal(size.height, 256); 104 | assert.equal(size.width, 1); 105 | 106 | // Do we need to verify data in histogram? 107 | // let dataView = hist.data; 108 | 109 | // Free resource 110 | cv._free(binSize); 111 | mask.delete(); 112 | hist.delete(); 113 | } 114 | 115 | // cvtColor 116 | { 117 | let source = new cv.Mat(10, 10, cv.CV_8UC3); 118 | let dest = new cv.Mat(); 119 | 120 | cv.cvtColor(source, dest, cv.COLOR_BGR2GRAY, 0); 121 | assert.equal(dest.channels(), 1); 122 | 123 | cv.cvtColor(source, dest, cv.COLOR_BGR2GRAY); 124 | assert.equal(dest.channels(), 1); 125 | 126 | cv.cvtColor(source, dest, cv.COLOR_BGR2BGRA, 0); 127 | assert.equal(dest.channels(), 4); 128 | 129 | cv.cvtColor(source, dest, cv.COLOR_BGR2BGRA); 130 | assert.equal(dest.channels(), 4); 131 | 132 | dest.delete(); 133 | source.delete(); 134 | } 135 | // equalizeHist 136 | { 137 | let source = new cv.Mat(10, 10, cv.CV_8UC1); 138 | let dest = new cv.Mat(); 139 | 140 | cv.equalizeHist(source, dest); 141 | 142 | // eualizeHist changes the content of a image, but does not alter meta data 143 | // of it. 144 | assert.equal(source.channels(), dest.channels()); 145 | assert.equal(source.type(), dest.type()); 146 | 147 | dest.delete(); 148 | source.delete(); 149 | } 150 | 151 | // floodFill 152 | { 153 | let center = new cv.Point(5, 5); 154 | let rect = new cv.Rect(0, 0, 0, 0); 155 | let img = new cv.Mat.zeros(10, 10, cv.CV_8UC1); 156 | let color = new cv.Scalar (255); 157 | cv.circle(img, center, 3, color, 1); 158 | 159 | let edge = new cv.Mat(); 160 | cv.Canny(img, edge, 100, 255); 161 | cv.copyMakeBorder(edge, edge, 1, 1, 1, 1, cv.BORDER_REPLICATE); 162 | 163 | let expected_img_data = new Uint8Array([ 164 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166 | 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 167 | 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 168 | 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 169 | 0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 170 | 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 171 | 0, 0, 0, 255, 255, 0, 255, 255, 0, 0, 172 | 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 173 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 174 | 175 | let img_elem = 10*10*1; 176 | let expected_img_data_ptr = cv._malloc(img_elem); 177 | let expected_img_data_heap = new Uint8Array(cv.HEAPU8.buffer, 178 | expected_img_data_ptr, 179 | img_elem); 180 | expected_img_data_heap.set(new Uint8Array(expected_img_data.buffer)); 181 | 182 | let expected_img = new cv.Mat( 10, 10, cv.CV_8UC1, expected_img_data_ptr, 0); 183 | 184 | let expected_rect = new cv.Rect(3,3,3,3); 185 | 186 | let compare_result = new cv.Mat(10, 10, cv.CV_8UC1); 187 | 188 | cv.floodFill(img, edge, center, color, rect); 189 | 190 | cv.compare (img, expected_img, compare_result, cv.CMP_EQ); 191 | 192 | // expect every pixels are the same. 193 | assert.equal (cv.countNonZero(compare_result), img.total()); 194 | assert.equal (rect.x, expected_rect.x); 195 | assert.equal (rect.y, expected_rect.y); 196 | assert.equal (rect.width, expected_rect.width); 197 | assert.equal (rect.height, expected_rect.height); 198 | 199 | img.delete(); 200 | edge.delete(); 201 | expected_img.delete(); 202 | compare_result.delete(); 203 | } 204 | 205 | // fillPoly 206 | { 207 | let img_width = 6; 208 | let img_height = 6; 209 | 210 | let img = new cv.Mat.zeros(img_height, img_width, cv.CV_8UC1); 211 | 212 | let npts = 4; 213 | let square_point_data = new Uint8Array([ 214 | 1, 1, 215 | 4, 1, 216 | 4, 4, 217 | 1, 4]); 218 | let square_points = cv.matFromArray(npts, 1, cv.CV_32SC2, square_point_data); 219 | let pts = new cv.MatVector(); 220 | pts.push_back (square_points); 221 | let color = new cv.Scalar (255); 222 | 223 | let expected_img_data = new Uint8Array([ 224 | 0, 0, 0, 0, 0, 0, 225 | 0, 255, 255, 255, 255, 0, 226 | 0, 255, 255, 255, 255, 0, 227 | 0, 255, 255, 255, 255, 0, 228 | 0, 255, 255, 255, 255, 0, 229 | 0, 0, 0, 0, 0, 0]); 230 | let expected_img = cv.matFromArray(img_height, img_width, cv.CV_8UC1, expected_img_data); 231 | 232 | cv.fillPoly(img, pts, color); 233 | 234 | let compare_result = new cv.Mat(img_height, img_width, cv.CV_8UC1); 235 | 236 | cv.compare (img, expected_img, compare_result, cv.CMP_EQ); 237 | 238 | // expect every pixels are the same. 239 | assert.equal (cv.countNonZero(compare_result), img.total()); 240 | 241 | img.delete(); 242 | square_points.delete(); 243 | pts.delete(); 244 | expected_img.delete(); 245 | compare_result.delete(); 246 | } 247 | 248 | // fillConvexPoly 249 | { 250 | let img_width = 6; 251 | let img_height = 6; 252 | 253 | let img = new cv.Mat.zeros(img_height, img_width, cv.CV_8UC1); 254 | 255 | let npts = 4; 256 | let square_point_data = new Uint8Array([ 257 | 1, 1, 258 | 4, 1, 259 | 4, 4, 260 | 1, 4]); 261 | let square_points = cv.matFromArray(npts, 1, cv.CV_32SC2, square_point_data); 262 | let color = new cv.Scalar (255); 263 | 264 | let expected_img_data = new Uint8Array([ 265 | 0, 0, 0, 0, 0, 0, 266 | 0, 255, 255, 255, 255, 0, 267 | 0, 255, 255, 255, 255, 0, 268 | 0, 255, 255, 255, 255, 0, 269 | 0, 255, 255, 255, 255, 0, 270 | 0, 0, 0, 0, 0, 0]); 271 | let expected_img = cv.matFromArray(img_height, img_width, cv.CV_8UC1, expected_img_data); 272 | 273 | cv.fillConvexPoly(img, square_points, color); 274 | 275 | let compare_result = new cv.Mat(img_height, img_width, cv.CV_8UC1); 276 | 277 | cv.compare (img, expected_img, compare_result, cv.CMP_EQ); 278 | 279 | // expect every pixels are the same. 280 | assert.equal (cv.countNonZero(compare_result), img.total()); 281 | 282 | img.delete(); 283 | square_points.delete(); 284 | expected_img.delete(); 285 | compare_result.delete(); 286 | } 287 | }); 288 | 289 | QUnit.test('test_segmentation', function(assert) { 290 | const THRESHOLD = 127.0; 291 | const THRESHOLD_MAX = 210.0; 292 | 293 | // threshold 294 | { 295 | let source = new cv.Mat(1, 5, cv.CV_8UC1); 296 | let sourceView = source.data; 297 | sourceView[0] = 0; // < threshold 298 | sourceView[1] = 100; // < threshold 299 | sourceView[2] = 200; // > threshold 300 | 301 | let dest = new cv.Mat(); 302 | 303 | cv.threshold(source, dest, THRESHOLD, THRESHOLD_MAX, cv.THRESH_BINARY); 304 | 305 | let destView = dest.data; 306 | assert.equal(destView[0], 0); 307 | assert.equal(destView[1], 0); 308 | assert.equal(destView[2], THRESHOLD_MAX); 309 | } 310 | 311 | // adaptiveThreshold 312 | { 313 | let source = cv.Mat.zeros(1, 5, cv.CV_8UC1); 314 | let sourceView = source.data; 315 | sourceView[0] = 50; 316 | sourceView[1] = 150; 317 | sourceView[2] = 200; 318 | 319 | let dest = new cv.Mat(); 320 | const C = 0; 321 | const blockSize = 3; 322 | cv.adaptiveThreshold(source, dest, THRESHOLD_MAX, 323 | cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, blockSize, C); 324 | 325 | let destView = dest.data; 326 | assert.equal(destView[0], 0); 327 | assert.equal(destView[1], THRESHOLD_MAX); 328 | assert.equal(destView[2], THRESHOLD_MAX); 329 | } 330 | }); 331 | 332 | QUnit.test('test_shape', function(assert) { 333 | // moments 334 | { 335 | let points = new cv.Mat(1, 4, cv.CV_32SC2); 336 | let data32S = points.data32S; 337 | data32S[0]=50; 338 | data32S[1]=56; 339 | data32S[2]=53; 340 | data32S[3]=53; 341 | data32S[4]=46; 342 | data32S[5]=54; 343 | data32S[6]=49; 344 | data32S[7]=51; 345 | 346 | let m = cv.moments(points, false); 347 | let area = cv.contourArea(points, false); 348 | 349 | assert.equal(m.m00, 0); 350 | assert.equal(m.m01, 0); 351 | assert.equal(m.m10, 0); 352 | assert.equal(area, 0); 353 | 354 | // default parameters 355 | m = cv.moments(points); 356 | area = cv.contourArea(points); 357 | assert.equal(m.m00, 0); 358 | assert.equal(m.m01, 0); 359 | assert.equal(m.m10, 0); 360 | assert.equal(area, 0); 361 | 362 | points.delete(); 363 | } 364 | }); 365 | 366 | QUnit.test('test_min_enclosing', function(assert) { 367 | { 368 | let points = new cv.Mat(4, 1, cv.CV_32FC2); 369 | 370 | points.data32F[0] = 0; 371 | points.data32F[1] = 0; 372 | points.data32F[2] = 1; 373 | points.data32F[3] = 0; 374 | points.data32F[4] = 1; 375 | points.data32F[5] = 1; 376 | points.data32F[6] = 0; 377 | points.data32F[7] = 1; 378 | 379 | let circle = cv.minEnclosingCircle(points); 380 | 381 | assert.deepEqual(circle.center, {x: 0.5, y: 0.5}); 382 | assert.ok(Math.abs(circle.radius - Math.sqrt(2) / 2) < 0.001); 383 | 384 | points.delete(); 385 | } 386 | }); 387 | 388 | QUnit.test('test_filter', function(assert) { 389 | // blur 390 | { 391 | let mat1 = cv.Mat.ones(5, 5, cv.CV_8UC3); 392 | let mat2 = new cv.Mat(); 393 | 394 | cv.blur(mat1, mat2, {height: 3, width: 3}, {x: -1, y: -1}, cv.BORDER_DEFAULT); 395 | 396 | // Verify result. 397 | let size = mat2.size(); 398 | assert.equal(mat2.channels(), 3); 399 | assert.equal(size.height, 5); 400 | assert.equal(size.width, 5); 401 | 402 | cv.blur(mat1, mat2, {height: 3, width: 3}, {x: -1, y: -1}); 403 | 404 | // Verify result. 405 | size = mat2.size(); 406 | assert.equal(mat2.channels(), 3); 407 | assert.equal(size.height, 5); 408 | assert.equal(size.width, 5); 409 | 410 | cv.blur(mat1, mat2, {height: 3, width: 3}); 411 | 412 | // Verify result. 413 | size = mat2.size(); 414 | assert.equal(mat2.channels(), 3); 415 | assert.equal(size.height, 5); 416 | assert.equal(size.width, 5); 417 | 418 | mat1.delete(); 419 | mat2.delete(); 420 | } 421 | 422 | // GaussianBlur 423 | { 424 | let mat1 = cv.Mat.ones(7, 7, cv.CV_8UC1); 425 | let mat2 = new cv.Mat(); 426 | 427 | cv.GaussianBlur(mat1, mat2, new cv.Size(3, 3), 0, 0, // eslint-disable-line new-cap 428 | cv.BORDER_DEFAULT); 429 | 430 | // Verify result. 431 | let size = mat2.size(); 432 | assert.equal(mat2.channels(), 1); 433 | assert.equal(size.height, 7); 434 | assert.equal(size.width, 7); 435 | } 436 | 437 | // medianBlur 438 | { 439 | let mat1 = cv.Mat.ones(9, 9, cv.CV_8UC3); 440 | let mat2 = new cv.Mat(); 441 | 442 | cv.medianBlur(mat1, mat2, 3); 443 | 444 | // Verify result. 445 | let size = mat2.size(); 446 | assert.equal(mat2.channels(), 3); 447 | assert.equal(size.height, 9); 448 | assert.equal(size.width, 9); 449 | } 450 | 451 | // Transpose 452 | { 453 | let mat1 = cv.Mat.eye(9, 9, cv.CV_8UC3); 454 | let mat2 = new cv.Mat(); 455 | 456 | cv.transpose(mat1, mat2); 457 | 458 | // Verify result. 459 | let size = mat2.size(); 460 | assert.equal(mat2.channels(), 3); 461 | assert.equal(size.height, 9); 462 | assert.equal(size.width, 9); 463 | } 464 | 465 | // bilateralFilter 466 | { 467 | let mat1 = cv.Mat.ones(11, 11, cv.CV_8UC3); 468 | let mat2 = new cv.Mat(); 469 | 470 | cv.bilateralFilter(mat1, mat2, 3, 6, 1.5, cv.BORDER_DEFAULT); 471 | 472 | // Verify result. 473 | let size = mat2.size(); 474 | assert.equal(mat2.channels(), 3); 475 | assert.equal(size.height, 11); 476 | assert.equal(size.width, 11); 477 | 478 | // default parameters 479 | cv.bilateralFilter(mat1, mat2, 3, 6, 1.5); 480 | // Verify result. 481 | size = mat2.size(); 482 | assert.equal(mat2.channels(), 3); 483 | assert.equal(size.height, 11); 484 | assert.equal(size.width, 11); 485 | 486 | mat1.delete(); 487 | mat2.delete(); 488 | } 489 | 490 | // Watershed 491 | { 492 | let mat = cv.Mat.ones(11, 11, cv.CV_8UC3); 493 | let out = new cv.Mat(11, 11, cv.CV_32SC1); 494 | 495 | cv.watershed(mat, out); 496 | 497 | // Verify result. 498 | let size = out.size(); 499 | assert.equal(out.channels(), 1); 500 | assert.equal(size.height, 11); 501 | assert.equal(size.width, 11); 502 | assert.equal(out.elemSize1(), 4); 503 | 504 | mat.delete(); 505 | out.delete(); 506 | } 507 | 508 | // Concat 509 | { 510 | let mat = cv.Mat.ones({height: 10, width: 5}, cv.CV_8UC3); 511 | let mat2 = cv.Mat.eye({height: 10, width: 5}, cv.CV_8UC3); 512 | let mat3 = cv.Mat.eye({height: 10, width: 5}, cv.CV_8UC3); 513 | 514 | 515 | let out = new cv.Mat(); 516 | let input = new cv.MatVector(); 517 | input.push_back(mat); 518 | input.push_back(mat2); 519 | input.push_back(mat3); 520 | 521 | cv.vconcat(input, out); 522 | 523 | // Verify result. 524 | let size = out.size(); 525 | assert.equal(out.channels(), 3); 526 | assert.equal(size.height, 30); 527 | assert.equal(size.width, 5); 528 | assert.equal(out.elemSize1(), 1); 529 | 530 | cv.hconcat(input, out); 531 | 532 | // Verify result. 533 | size = out.size(); 534 | assert.equal(out.channels(), 3); 535 | assert.equal(size.height, 10); 536 | assert.equal(size.width, 15); 537 | assert.equal(out.elemSize1(), 1); 538 | 539 | input.delete(); 540 | out.delete(); 541 | } 542 | 543 | 544 | // distanceTransform letiants 545 | { 546 | let mat = cv.Mat.ones(11, 11, cv.CV_8UC1); 547 | let out = new cv.Mat(11, 11, cv.CV_32FC1); 548 | let labels = new cv.Mat(11, 11, cv.CV_32FC1); 549 | const maskSize = 3; 550 | cv.distanceTransform(mat, out, cv.DIST_L2, maskSize, cv.CV_32F); 551 | 552 | // Verify result. 553 | let size = out.size(); 554 | assert.equal(out.channels(), 1); 555 | assert.equal(size.height, 11); 556 | assert.equal(size.width, 11); 557 | assert.equal(out.elemSize1(), 4); 558 | 559 | 560 | cv.distanceTransformWithLabels(mat, out, labels, cv.DIST_L2, maskSize, 561 | cv.DIST_LABEL_CCOMP); 562 | 563 | // Verify result. 564 | size = out.size(); 565 | assert.equal(out.channels(), 1); 566 | assert.equal(size.height, 11); 567 | assert.equal(size.width, 11); 568 | assert.equal(out.elemSize1(), 4); 569 | 570 | size = labels.size(); 571 | assert.equal(labels.channels(), 1); 572 | assert.equal(size.height, 11); 573 | assert.equal(size.width, 11); 574 | assert.equal(labels.elemSize1(), 4); 575 | 576 | mat.delete(); 577 | out.delete(); 578 | labels.delete(); 579 | } 580 | 581 | // Min, Max 582 | { 583 | let data1 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9]); 584 | let data2 = new Uint8Array([0, 4, 0, 8, 0, 12, 0, 16, 0]); 585 | 586 | let expectedMin = new Uint8Array([0, 2, 0, 4, 0, 6, 0, 8, 0]); 587 | let expectedMax = new Uint8Array([1, 4, 3, 8, 5, 12, 7, 16, 9]); 588 | 589 | let dataPtr = cv._malloc(3*3*1); 590 | let dataPtr2 = cv._malloc(3*3*1); 591 | 592 | let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 3*3*1); 593 | dataHeap.set(new Uint8Array(data1.buffer)); 594 | 595 | let dataHeap2 = new Uint8Array(cv.HEAPU8.buffer, dataPtr2, 3*3*1); 596 | dataHeap2.set(new Uint8Array(data2.buffer)); 597 | 598 | 599 | let mat1 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr, 0); 600 | let mat2 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr2, 0); 601 | 602 | let mat3 = new cv.Mat(); 603 | 604 | cv.min(mat1, mat2, mat3); 605 | // Verify result. 606 | let size = mat2.size(); 607 | assert.equal(mat2.channels(), 1); 608 | assert.equal(size.height, 3); 609 | assert.equal(size.width, 3); 610 | 611 | assert.deepEqual(mat3.data, expectedMin); 612 | 613 | 614 | cv.max(mat1, mat2, mat3); 615 | // Verify result. 616 | size = mat2.size(); 617 | assert.equal(mat2.channels(), 1); 618 | assert.equal(size.height, 3); 619 | assert.equal(size.width, 3); 620 | 621 | assert.deepEqual(mat3.data, expectedMax); 622 | 623 | cv._free(dataPtr); 624 | cv._free(dataPtr2); 625 | } 626 | 627 | // Bitwise operations 628 | { 629 | let data1 = new Uint8Array([0, 1, 2, 4, 8, 16, 32, 64, 128]); 630 | let data2 = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255]); 631 | 632 | let expectedAnd = new Uint8Array([0, 1, 2, 4, 8, 16, 32, 64, 128]); 633 | let expectedOr = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255]); 634 | let expectedXor = new Uint8Array([255, 254, 253, 251, 247, 239, 223, 191, 127]); 635 | 636 | let expectedNot = new Uint8Array([255, 254, 253, 251, 247, 239, 223, 191, 127]); 637 | 638 | let dataPtr = cv._malloc(3*3*1); 639 | let dataPtr2 = cv._malloc(3*3*1); 640 | 641 | let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 3*3*1); 642 | dataHeap.set(new Uint8Array(data1.buffer)); 643 | 644 | let dataHeap2 = new Uint8Array(cv.HEAPU8.buffer, dataPtr2, 3*3*1); 645 | dataHeap2.set(new Uint8Array(data2.buffer)); 646 | 647 | 648 | let mat1 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr, 0); 649 | let mat2 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr2, 0); 650 | 651 | let mat3 = new cv.Mat(); 652 | let none = new cv.Mat(); 653 | 654 | cv.bitwise_not(mat1, mat3, none); 655 | // Verify result. 656 | let size = mat3.size(); 657 | assert.equal(mat3.channels(), 1); 658 | assert.equal(size.height, 3); 659 | assert.equal(size.width, 3); 660 | 661 | assert.deepEqual(mat3.data, expectedNot); 662 | 663 | cv.bitwise_and(mat1, mat2, mat3, none); 664 | // Verify result. 665 | size = mat3.size(); 666 | assert.equal(mat3.channels(), 1); 667 | assert.equal(size.height, 3); 668 | assert.equal(size.width, 3); 669 | 670 | assert.deepEqual(mat3.data, expectedAnd); 671 | 672 | 673 | cv.bitwise_or(mat1, mat2, mat3, none); 674 | // Verify result. 675 | size = mat3.size(); 676 | assert.equal(mat3.channels(), 1); 677 | assert.equal(size.height, 3); 678 | assert.equal(size.width, 3); 679 | 680 | assert.deepEqual(mat3.data, expectedOr); 681 | 682 | cv.bitwise_xor(mat1, mat2, mat3, none); 683 | // Verify result. 684 | size = mat3.size(); 685 | assert.equal(mat3.channels(), 1); 686 | assert.equal(size.height, 3); 687 | assert.equal(size.width, 3); 688 | 689 | assert.deepEqual(mat3.data, expectedXor); 690 | 691 | cv._free(dataPtr); 692 | cv._free(dataPtr2); 693 | } 694 | 695 | // Arithmetic operations 696 | { 697 | let data1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8]); 698 | let data2 = new Uint8Array([0, 2, 4, 6, 8, 10, 12, 14, 16]); 699 | let data3 = new Uint8Array([0, 1, 0, 1, 0, 1, 0, 1, 0]); 700 | 701 | // |data1 - data2| 702 | let expectedAbsDiff = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8]); 703 | let expectedAdd = new Uint8Array([0, 3, 6, 9, 12, 15, 18, 21, 24]); 704 | 705 | const alpha = 4; 706 | const beta = -1; 707 | const gamma = 3; 708 | // 4*data1 - data2 + 3 709 | let expectedWeightedAdd = new Uint8Array([3, 5, 7, 9, 11, 13, 15, 17, 19]); 710 | 711 | let dataPtr = cv._malloc(3*3*1); 712 | let dataPtr2 = cv._malloc(3*3*1); 713 | let dataPtr3 = cv._malloc(3*3*1); 714 | 715 | let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 3*3*1); 716 | dataHeap.set(new Uint8Array(data1.buffer)); 717 | let dataHeap2 = new Uint8Array(cv.HEAPU8.buffer, dataPtr2, 3*3*1); 718 | dataHeap2.set(new Uint8Array(data2.buffer)); 719 | let dataHeap3 = new Uint8Array(cv.HEAPU8.buffer, dataPtr3, 3*3*1); 720 | dataHeap3.set(new Uint8Array(data3.buffer)); 721 | 722 | let mat1 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr, 0); 723 | let mat2 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr2, 0); 724 | let mat3 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr3, 0); 725 | 726 | let dst = new cv.Mat(); 727 | let none = new cv.Mat(); 728 | 729 | cv.absdiff(mat1, mat2, dst); 730 | // Verify result. 731 | let size = dst.size(); 732 | assert.equal(dst.channels(), 1); 733 | assert.equal(size.height, 3); 734 | assert.equal(size.width, 3); 735 | 736 | assert.deepEqual(dst.data, expectedAbsDiff); 737 | 738 | cv.add(mat1, mat2, dst, none, -1); 739 | // Verify result. 740 | size = dst.size(); 741 | assert.equal(dst.channels(), 1); 742 | assert.equal(size.height, 3); 743 | assert.equal(size.width, 3); 744 | 745 | assert.deepEqual(dst.data, expectedAdd); 746 | 747 | cv.addWeighted(mat1, alpha, mat2, beta, gamma, dst, -1); 748 | // Verify result. 749 | size = dst.size(); 750 | assert.equal(dst.channels(), 1); 751 | assert.equal(size.height, 3); 752 | assert.equal(size.width, 3); 753 | 754 | assert.deepEqual(dst.data, expectedWeightedAdd); 755 | 756 | // default parameter 757 | cv.addWeighted(mat1, alpha, mat2, beta, gamma, dst); 758 | // Verify result. 759 | size = dst.size(); 760 | assert.equal(dst.channels(), 1); 761 | assert.equal(size.height, 3); 762 | assert.equal(size.width, 3); 763 | 764 | assert.deepEqual(dst.data, expectedWeightedAdd); 765 | 766 | mat1.delete(); 767 | mat2.delete(); 768 | mat3.delete(); 769 | dst.delete(); 770 | none.delete(); 771 | } 772 | 773 | // Integral letiants 774 | { 775 | let mat = cv.Mat.eye({height: 100, width: 100}, cv.CV_8UC3); 776 | let sum = new cv.Mat(); 777 | let sqSum = new cv.Mat(); 778 | let title = new cv.Mat(); 779 | 780 | cv.integral(mat, sum, -1); 781 | 782 | // Verify result. 783 | let size = sum.size(); 784 | assert.equal(sum.channels(), 3); 785 | assert.equal(size.height, 100+1); 786 | assert.equal(size.width, 100+1); 787 | 788 | cv.integral2(mat, sum, sqSum, -1, -1); 789 | // Verify result. 790 | size = sum.size(); 791 | assert.equal(sum.channels(), 3); 792 | assert.equal(size.height, 100+1); 793 | assert.equal(size.width, 100+1); 794 | 795 | size = sqSum.size(); 796 | assert.equal(sqSum.channels(), 3); 797 | assert.equal(size.height, 100+1); 798 | assert.equal(size.width, 100+1); 799 | 800 | mat.delete(); 801 | sum.delete(); 802 | sqSum.delete(); 803 | title.delete(); 804 | } 805 | 806 | // Mean, meanSTDev 807 | { 808 | let mat = cv.Mat.eye({height: 100, width: 100}, cv.CV_8UC3); 809 | let sum = new cv.Mat(); 810 | let sqSum = new cv.Mat(); 811 | let title = new cv.Mat(); 812 | 813 | cv.integral(mat, sum, -1); 814 | 815 | // Verify result. 816 | let size = sum.size(); 817 | assert.equal(sum.channels(), 3); 818 | assert.equal(size.height, 100+1); 819 | assert.equal(size.width, 100+1); 820 | 821 | cv.integral2(mat, sum, sqSum, -1, -1); 822 | // Verify result. 823 | size = sum.size(); 824 | assert.equal(sum.channels(), 3); 825 | assert.equal(size.height, 100+1); 826 | assert.equal(size.width, 100+1); 827 | 828 | size = sqSum.size(); 829 | assert.equal(sqSum.channels(), 3); 830 | assert.equal(size.height, 100+1); 831 | assert.equal(size.width, 100+1); 832 | 833 | mat.delete(); 834 | sum.delete(); 835 | sqSum.delete(); 836 | title.delete(); 837 | } 838 | 839 | // Invert 840 | { 841 | let inv1 = new cv.Mat(); 842 | let inv2 = new cv.Mat(); 843 | let inv3 = new cv.Mat(); 844 | let inv4 = new cv.Mat(); 845 | 846 | 847 | let data1 = new Float32Array([1, 0, 0, 848 | 0, 1, 0, 849 | 0, 0, 1]); 850 | let data2 = new Float32Array([0, 0, 0, 851 | 0, 5, 0, 852 | 0, 0, 0]); 853 | let data3 = new Float32Array([1, 1, 1, 0, 854 | 0, 3, 1, 2, 855 | 2, 3, 1, 0, 856 | 1, 0, 2, 1]); 857 | let data4 = new Float32Array([1, 4, 5, 858 | 4, 2, 2, 859 | 5, 2, 2]); 860 | 861 | let expected1 = new Float32Array([1, 0, 0, 862 | 0, 1, 0, 863 | 0, 0, 1]); 864 | // Inverse does not exist! 865 | let expected3 = new Float32Array([-3, -1/2, 3/2, 1, 866 | 1, 1/4, -1/4, -1/2, 867 | 3, 1/4, -5/4, -1/2, 868 | -3, 0, 1, 1]); 869 | let expected4 = new Float32Array([0, -1, 1, 870 | -1, 23/2, -9, 871 | 1, -9, 7]); 872 | 873 | let dataPtr1 = cv._malloc(3*3*4); 874 | let dataPtr2 = cv._malloc(3*3*4); 875 | let dataPtr3 = cv._malloc(4*4*4); 876 | let dataPtr4 = cv._malloc(3*3*4); 877 | 878 | let dataHeap = new Float32Array(cv.HEAP32.buffer, dataPtr1, 3*3); 879 | dataHeap.set(new Float32Array(data1.buffer)); 880 | let dataHeap2 = new Float32Array(cv.HEAP32.buffer, dataPtr2, 3*3); 881 | dataHeap2.set(new Float32Array(data2.buffer)); 882 | let dataHeap3 = new Float32Array(cv.HEAP32.buffer, dataPtr3, 4*4); 883 | dataHeap3.set(new Float32Array(data3.buffer)); 884 | let dataHeap4 = new Float32Array(cv.HEAP32.buffer, dataPtr4, 3*3); 885 | dataHeap4.set(new Float32Array(data4.buffer)); 886 | 887 | let mat1 = new cv.Mat(3, 3, cv.CV_32FC1, dataPtr1, 0); 888 | let mat2 = new cv.Mat(3, 3, cv.CV_32FC1, dataPtr2, 0); 889 | let mat3 = new cv.Mat(4, 4, cv.CV_32FC1, dataPtr3, 0); 890 | let mat4 = new cv.Mat(3, 3, cv.CV_32FC1, dataPtr4, 0); 891 | 892 | QUnit.assert.deepEqualWithTolerance = function( value, expected, tolerance ) { 893 | for (let i = 0; i < value.length; i= i+1) { 894 | this.pushResult( { 895 | result: Math.abs(value[i]-expected[i]) < tolerance, 896 | actual: value[i], 897 | expected: expected[i], 898 | } ); 899 | } 900 | }; 901 | 902 | cv.invert(mat1, inv1, 0); 903 | // Verify result. 904 | let size = inv1.size(); 905 | assert.equal(inv1.channels(), 1); 906 | assert.equal(size.height, 3); 907 | assert.equal(size.width, 3); 908 | assert.deepEqualWithTolerance(inv1.data32F, expected1, 0.0001); 909 | 910 | 911 | cv.invert(mat2, inv2, 0); 912 | // Verify result. 913 | assert.deepEqualWithTolerance(inv3.data32F, expected3, 0.0001); 914 | 915 | cv.invert(mat3, inv3, 0); 916 | // Verify result. 917 | size = inv3.size(); 918 | assert.equal(inv3.channels(), 1); 919 | assert.equal(size.height, 4); 920 | assert.equal(size.width, 4); 921 | assert.deepEqualWithTolerance(inv3.data32F, expected3, 0.0001); 922 | 923 | cv.invert(mat3, inv3, 1); 924 | // Verify result. 925 | assert.deepEqualWithTolerance(inv3.data32F, expected3, 0.0001); 926 | 927 | cv.invert(mat4, inv4, 2); 928 | // Verify result. 929 | assert.deepEqualWithTolerance(inv4.data32F, expected4, 0.0001); 930 | 931 | cv.invert(mat4, inv4, 3); 932 | // Verify result. 933 | assert.deepEqualWithTolerance(inv4.data32F, expected4, 0.0001); 934 | 935 | mat1.delete(); 936 | mat2.delete(); 937 | mat3.delete(); 938 | mat4.delete(); 939 | inv1.delete(); 940 | inv2.delete(); 941 | inv3.delete(); 942 | inv4.delete(); 943 | } 944 | //Rotate 945 | { 946 | let dst = new cv.Mat(); 947 | let src = cv.matFromArray(3, 2, cv.CV_8U, [1,2,3,4,5,6]); 948 | 949 | cv.rotate(src, dst, cv.ROTATE_90_CLOCKWISE); 950 | 951 | size = dst.size(); 952 | assert.equal(size.height, 2, "ROTATE_HEIGHT"); 953 | assert.equal(size.width, 3, "ROTATE_WIGTH"); 954 | 955 | let expected = new Uint8Array([5,3,1,6,4,2]); 956 | 957 | assert.deepEqual(dst.data, expected); 958 | 959 | dst.delete(); 960 | src.delete(); 961 | } 962 | }); 963 | 964 | QUnit.test('warpPolar', function(assert) { 965 | const lines = new cv.Mat(255, 255, cv.CV_8U, new cv.Scalar(0)); 966 | for (let r = 0; r < lines.rows; r++) { 967 | lines.row(r).setTo(new cv.Scalar(r)); 968 | } 969 | cv.warpPolar(lines, lines, { width: 5, height: 5 }, new cv.Point(2, 2), 3, 970 | cv.INTER_CUBIC | cv.WARP_FILL_OUTLIERS | cv.WARP_INVERSE_MAP); 971 | assert.ok(lines instanceof cv.Mat); 972 | assert.deepEqual(Array.from(lines.data), [ 973 | 159, 172, 191, 210, 223, 974 | 146, 159, 191, 223, 236, 975 | 128, 128, 0, 0, 0, 976 | 109, 96, 64, 32, 19, 977 | 96, 83, 64, 45, 32 978 | ]); 979 | }); 980 | -------------------------------------------------------------------------------- /demo/server/test_mat.js: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 | // 5 | // By downloading, copying, installing or using the software you agree to this license. 6 | // If you do not agree to this license, do not download, install, 7 | // copy or use the software. 8 | // 9 | // 10 | // License Agreement 11 | // For Open Source Computer Vision Library 12 | // 13 | // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 14 | // Third party copyrights are property of their respective owners. 15 | // 16 | // Redistribution and use in source and binary forms, with or without modification, 17 | // are permitted provided that the following conditions are met: 18 | // 19 | // * Redistribution's of source code must retain the above copyright notice, 20 | // this list of conditions and the following disclaimer. 21 | // 22 | // * Redistribution's in binary form must reproduce the above copyright notice, 23 | // this list of conditions and the following disclaimer in the documentation 24 | // and/or other materials provided with the distribution. 25 | // 26 | // * The name of the copyright holders may not be used to endorse or promote products 27 | // derived from this software without specific prior written permission. 28 | // 29 | // This software is provided by the copyright holders and contributors "as is" and 30 | // any express or implied warranties, including, but not limited to, the implied 31 | // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 | // In no event shall the Intel Corporation or contributors be liable for any direct, 33 | // indirect, incidental, special, exemplary, or consequential damages 34 | // (including, but not limited to, procurement of substitute goods or services; 35 | // loss of use, data, or profits; or business interruption) however caused 36 | // and on any theory of liability, whether in contract, strict liability, 37 | // or tort (including negligence or otherwise) arising in any way out of 38 | // the use of this software, even if advised of the possibility of such damage. 39 | // 40 | // 41 | 42 | // ////////////////////////////////////////////////////////////////////////////////////// 43 | // Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu 44 | // 45 | // LICENSE AGREEMENT 46 | // Copyright (c) 2015 The Regents of the University of California (Regents) 47 | // 48 | // Redistribution and use in source and binary forms, with or without 49 | // modification, are permitted provided that the following conditions are met: 50 | // 1. Redistributions of source code must retain the above copyright 51 | // notice, this list of conditions and the following disclaimer. 52 | // 2. Redistributions in binary form must reproduce the above copyright 53 | // notice, this list of conditions and the following disclaimer in the 54 | // documentation and/or other materials provided with the distribution. 55 | // 3. Neither the name of the University nor the 56 | // names of its contributors may be used to endorse or promote products 57 | // derived from this software without specific prior written permission. 58 | // 59 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY 60 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 61 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 62 | // DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY 63 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 64 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 65 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 66 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 67 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 68 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69 | // 70 | 71 | if (typeof module !== 'undefined' && module.exports) { 72 | // The environment is Node.js 73 | var cv = require('./opencv.js'); // eslint-disable-line no-var 74 | } 75 | 76 | QUnit.module('Core', {}); 77 | 78 | QUnit.test('test_mat_creation', function(assert) { 79 | // Mat constructors. 80 | // Mat::Mat(int rows, int cols, int type) 81 | { 82 | let mat = new cv.Mat(10, 20, cv.CV_8UC3); 83 | 84 | assert.equal(mat.type(), cv.CV_8UC3); 85 | assert.equal(mat.depth(), cv.CV_8U); 86 | assert.equal(mat.channels(), 3); 87 | assert.ok(mat.empty() === false); 88 | 89 | let size = mat.size(); 90 | assert.equal(size.height, 10); 91 | assert.equal(size.width, 20); 92 | 93 | mat.delete(); 94 | } 95 | 96 | // Mat::Mat(const Mat &) 97 | { 98 | // Copy from another Mat 99 | let mat1 = new cv.Mat(10, 20, cv.CV_8UC3); 100 | let mat2 = new cv.Mat(mat1); 101 | 102 | assert.equal(mat2.type(), mat1.type()); 103 | assert.equal(mat2.depth(), mat1.depth()); 104 | assert.equal(mat2.channels(), mat1.channels()); 105 | assert.equal(mat2.empty(), mat1.empty()); 106 | 107 | let size1 = mat1.size; 108 | let size2 = mat2.size(); 109 | assert.ok(size1[0] === size2[0]); 110 | assert.ok(size1[1] === size2[1]); 111 | 112 | mat1.delete(); 113 | mat2.delete(); 114 | } 115 | 116 | // Mat::Mat(int rows, int cols, int type, void *data, size_t step=AUTO_STEP) 117 | { 118 | // 10 * 10 and one channel 119 | let data = cv._malloc(10 * 10 * 1); 120 | let mat = new cv.Mat(10, 10, cv.CV_8UC1, data, 0); 121 | 122 | assert.equal(mat.type(), cv.CV_8UC1); 123 | assert.equal(mat.depth(), cv.CV_8U); 124 | assert.equal(mat.channels(), 1); 125 | assert.ok(mat.empty() === false); 126 | 127 | let size = mat.size(); 128 | assert.ok(size.height === 10); 129 | assert.ok(size.width === 10); 130 | 131 | mat.delete(); 132 | } 133 | 134 | // Mat::Mat(int rows, int cols, int type, const Scalar& scalar) 135 | { 136 | // 2 * 2 8UC4 mat 137 | let mat = new cv.Mat(2, 2, cv.CV_8UC4, [0, 1, 2, 3]); 138 | 139 | for (let r = 0; r < mat.rows; r++) { 140 | for (let c = 0; c < mat.cols; c++) { 141 | let element = mat.ptr(r, c); 142 | assert.equal(element[0], 0); 143 | assert.equal(element[1], 1); 144 | assert.equal(element[2], 2); 145 | assert.equal(element[3], 3); 146 | } 147 | } 148 | 149 | mat.delete(); 150 | } 151 | 152 | // Mat::create(int, int, int) 153 | { 154 | let mat = new cv.Mat(); 155 | mat.create(10, 5, cv.CV_8UC3); 156 | let size = mat.size(); 157 | 158 | assert.ok(mat.type() === cv.CV_8UC3); 159 | assert.ok(size.height === 10); 160 | assert.ok(size.width === 5); 161 | assert.ok(mat.channels() === 3); 162 | 163 | mat.delete(); 164 | } 165 | // Mat::create(Size, int) 166 | { 167 | let mat = new cv.Mat(); 168 | mat.create({height: 10, width: 5}, cv.CV_8UC4); 169 | let size = mat.size(); 170 | 171 | assert.ok(mat.type() === cv.CV_8UC4); 172 | assert.ok(size.height === 10); 173 | assert.ok(size.width === 5); 174 | assert.ok(mat.channels() === 4); 175 | 176 | mat.delete(); 177 | } 178 | // clone 179 | { 180 | let mat = cv.Mat.ones(5, 5, cv.CV_8UC1); 181 | let mat2 = mat.clone(); 182 | 183 | assert.equal(mat.channels, mat2.channels); 184 | assert.equal(mat.size().height, mat2.size().height); 185 | assert.equal(mat.size().width, mat2.size().width); 186 | 187 | assert.deepEqual(mat.data, mat2.data); 188 | 189 | 190 | mat.delete(); 191 | mat2.delete(); 192 | } 193 | // copyTo 194 | { 195 | let mat = cv.Mat.ones(5, 5, cv.CV_8UC1); 196 | let mat2 = new cv.Mat(); 197 | mat.copyTo(mat2); 198 | 199 | assert.equal(mat.channels, mat2.channels); 200 | assert.equal(mat.size().height, mat2.size().height); 201 | assert.equal(mat.size().width, mat2.size().width); 202 | 203 | assert.deepEqual(mat.data, mat2.data); 204 | 205 | 206 | mat.delete(); 207 | mat2.delete(); 208 | } 209 | // copyTo1 210 | { 211 | let mat = cv.Mat.ones(5, 5, cv.CV_8UC1); 212 | let mat2 = new cv.Mat(); 213 | let mask = new cv.Mat(5, 5, cv.CV_8UC1, new cv.Scalar(1)); 214 | mat.copyTo(mat2, mask); 215 | 216 | assert.equal(mat.channels, mat2.channels); 217 | assert.equal(mat.size().height, mat2.size().height); 218 | assert.equal(mat.size().width, mat2.size().width); 219 | 220 | assert.deepEqual(mat.data, mat2.data); 221 | 222 | 223 | mat.delete(); 224 | mat2.delete(); 225 | mask.delete(); 226 | } 227 | 228 | // matFromArray 229 | { 230 | let arrayC1 = [0, -1, 2, -3]; 231 | let arrayC2 = [0, -1, 2, -3, 4, -5, 6, -7]; 232 | let arrayC3 = [0, -1, 2, -3, 4, -5, 6, -7, 9, -9, 10, -11]; 233 | let arrayC4 = [0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, 13, 14, 15]; 234 | 235 | let mat8UC1 = cv.matFromArray(2, 2, cv.CV_8UC1, arrayC1); 236 | let mat8UC2 = cv.matFromArray(2, 2, cv.CV_8UC2, arrayC2); 237 | let mat8UC3 = cv.matFromArray(2, 2, cv.CV_8UC3, arrayC3); 238 | let mat8UC4 = cv.matFromArray(2, 2, cv.CV_8UC4, arrayC4); 239 | 240 | let mat8SC1 = cv.matFromArray(2, 2, cv.CV_8SC1, arrayC1); 241 | let mat8SC2 = cv.matFromArray(2, 2, cv.CV_8SC2, arrayC2); 242 | let mat8SC3 = cv.matFromArray(2, 2, cv.CV_8SC3, arrayC3); 243 | let mat8SC4 = cv.matFromArray(2, 2, cv.CV_8SC4, arrayC4); 244 | 245 | let mat16UC1 = cv.matFromArray(2, 2, cv.CV_16UC1, arrayC1); 246 | let mat16UC2 = cv.matFromArray(2, 2, cv.CV_16UC2, arrayC2); 247 | let mat16UC3 = cv.matFromArray(2, 2, cv.CV_16UC3, arrayC3); 248 | let mat16UC4 = cv.matFromArray(2, 2, cv.CV_16UC4, arrayC4); 249 | 250 | let mat16SC1 = cv.matFromArray(2, 2, cv.CV_16SC1, arrayC1); 251 | let mat16SC2 = cv.matFromArray(2, 2, cv.CV_16SC2, arrayC2); 252 | let mat16SC3 = cv.matFromArray(2, 2, cv.CV_16SC3, arrayC3); 253 | let mat16SC4 = cv.matFromArray(2, 2, cv.CV_16SC4, arrayC4); 254 | 255 | let mat32SC1 = cv.matFromArray(2, 2, cv.CV_32SC1, arrayC1); 256 | let mat32SC2 = cv.matFromArray(2, 2, cv.CV_32SC2, arrayC2); 257 | let mat32SC3 = cv.matFromArray(2, 2, cv.CV_32SC3, arrayC3); 258 | let mat32SC4 = cv.matFromArray(2, 2, cv.CV_32SC4, arrayC4); 259 | 260 | let mat32FC1 = cv.matFromArray(2, 2, cv.CV_32FC1, arrayC1); 261 | let mat32FC2 = cv.matFromArray(2, 2, cv.CV_32FC2, arrayC2); 262 | let mat32FC3 = cv.matFromArray(2, 2, cv.CV_32FC3, arrayC3); 263 | let mat32FC4 = cv.matFromArray(2, 2, cv.CV_32FC4, arrayC4); 264 | 265 | let mat64FC1 = cv.matFromArray(2, 2, cv.CV_64FC1, arrayC1); 266 | let mat64FC2 = cv.matFromArray(2, 2, cv.CV_64FC2, arrayC2); 267 | let mat64FC3 = cv.matFromArray(2, 2, cv.CV_64FC3, arrayC3); 268 | let mat64FC4 = cv.matFromArray(2, 2, cv.CV_64FC4, arrayC4); 269 | 270 | assert.deepEqual(mat8UC1.data, new Uint8Array(arrayC1)); 271 | assert.deepEqual(mat8UC2.data, new Uint8Array(arrayC2)); 272 | assert.deepEqual(mat8UC3.data, new Uint8Array(arrayC3)); 273 | assert.deepEqual(mat8UC4.data, new Uint8Array(arrayC4)); 274 | 275 | assert.deepEqual(mat8SC1.data8S, new Int8Array(arrayC1)); 276 | assert.deepEqual(mat8SC2.data8S, new Int8Array(arrayC2)); 277 | assert.deepEqual(mat8SC3.data8S, new Int8Array(arrayC3)); 278 | assert.deepEqual(mat8SC4.data8S, new Int8Array(arrayC4)); 279 | 280 | assert.deepEqual(mat16UC1.data16U, new Uint16Array(arrayC1)); 281 | assert.deepEqual(mat16UC2.data16U, new Uint16Array(arrayC2)); 282 | assert.deepEqual(mat16UC3.data16U, new Uint16Array(arrayC3)); 283 | assert.deepEqual(mat16UC4.data16U, new Uint16Array(arrayC4)); 284 | 285 | assert.deepEqual(mat16SC1.data16S, new Int16Array(arrayC1)); 286 | assert.deepEqual(mat16SC2.data16S, new Int16Array(arrayC2)); 287 | assert.deepEqual(mat16SC3.data16S, new Int16Array(arrayC3)); 288 | assert.deepEqual(mat16SC4.data16S, new Int16Array(arrayC4)); 289 | 290 | assert.deepEqual(mat32SC1.data32S, new Int32Array(arrayC1)); 291 | assert.deepEqual(mat32SC2.data32S, new Int32Array(arrayC2)); 292 | assert.deepEqual(mat32SC3.data32S, new Int32Array(arrayC3)); 293 | assert.deepEqual(mat32SC4.data32S, new Int32Array(arrayC4)); 294 | 295 | assert.deepEqual(mat32FC1.data32F, new Float32Array(arrayC1)); 296 | assert.deepEqual(mat32FC2.data32F, new Float32Array(arrayC2)); 297 | assert.deepEqual(mat32FC3.data32F, new Float32Array(arrayC3)); 298 | assert.deepEqual(mat32FC4.data32F, new Float32Array(arrayC4)); 299 | 300 | assert.deepEqual(mat64FC1.data64F, new Float64Array(arrayC1)); 301 | assert.deepEqual(mat64FC2.data64F, new Float64Array(arrayC2)); 302 | assert.deepEqual(mat64FC3.data64F, new Float64Array(arrayC3)); 303 | assert.deepEqual(mat64FC4.data64F, new Float64Array(arrayC4)); 304 | 305 | mat8UC1.delete(); 306 | mat8UC2.delete(); 307 | mat8UC3.delete(); 308 | mat8UC4.delete(); 309 | mat8SC1.delete(); 310 | mat8SC2.delete(); 311 | mat8SC3.delete(); 312 | mat8SC4.delete(); 313 | mat16UC1.delete(); 314 | mat16UC2.delete(); 315 | mat16UC3.delete(); 316 | mat16UC4.delete(); 317 | mat16SC1.delete(); 318 | mat16SC2.delete(); 319 | mat16SC3.delete(); 320 | mat16SC4.delete(); 321 | mat32SC1.delete(); 322 | mat32SC2.delete(); 323 | mat32SC3.delete(); 324 | mat32SC4.delete(); 325 | mat32FC1.delete(); 326 | mat32FC2.delete(); 327 | mat32FC3.delete(); 328 | mat32FC4.delete(); 329 | mat64FC1.delete(); 330 | mat64FC2.delete(); 331 | mat64FC3.delete(); 332 | mat64FC4.delete(); 333 | } 334 | 335 | // matFromImageData 336 | { 337 | // Only test in browser 338 | if (typeof window === 'undefined') { 339 | return; 340 | } 341 | let canvas = window.document.createElement('canvas'); 342 | canvas.width = 2; 343 | canvas.height = 2; 344 | let ctx = canvas.getContext('2d'); 345 | ctx.fillStyle='#FF0000'; 346 | ctx.fillRect(0, 0, 1, 1); 347 | ctx.fillRect(1, 1, 1, 1); 348 | 349 | let imageData = ctx.getImageData(0, 0, 2, 2); 350 | let mat = cv.matFromImageData(imageData); 351 | 352 | assert.deepEqual(mat.data, new Uint8Array(imageData.data)); 353 | 354 | mat.delete(); 355 | } 356 | 357 | // Mat(mat) 358 | { 359 | let mat = new cv.Mat(2, 2, cv.CV_8UC4, new cv.Scalar(1, 0, 1, 0)); 360 | let mat1 = new cv.Mat(mat); 361 | let mat2 = mat; 362 | 363 | assert.equal(mat.rows, mat1.rows); 364 | assert.equal(mat.cols, mat1.cols); 365 | assert.equal(mat.type(), mat1.type()); 366 | assert.deepEqual(mat.data, mat1.data); 367 | 368 | mat.delete(); 369 | 370 | assert.equal(mat1.isDeleted(), false); 371 | assert.equal(mat2.isDeleted(), true); 372 | 373 | mat1.delete(); 374 | } 375 | 376 | // mat.setTo 377 | { 378 | let mat = new cv.Mat(2, 2, cv.CV_8UC4); 379 | let s = [0, 1, 2, 3]; 380 | 381 | mat.setTo(s); 382 | 383 | assert.deepEqual(mat.ptr(0, 0), new Uint8Array(s)); 384 | assert.deepEqual(mat.ptr(0, 1), new Uint8Array(s)); 385 | assert.deepEqual(mat.ptr(1, 0), new Uint8Array(s)); 386 | assert.deepEqual(mat.ptr(1, 1), new Uint8Array(s)); 387 | 388 | let s1 = [0, 0, 0, 0]; 389 | mat.setTo(s1); 390 | let mask = cv.matFromArray(2, 2, cv.CV_8UC1, [0, 1, 0, 1]); 391 | mat.setTo(s, mask); 392 | 393 | assert.deepEqual(mat.ptr(0, 0), new Uint8Array(s1)); 394 | assert.deepEqual(mat.ptr(0, 1), new Uint8Array(s)); 395 | assert.deepEqual(mat.ptr(1, 0), new Uint8Array(s1)); 396 | assert.deepEqual(mat.ptr(1, 1), new Uint8Array(s)); 397 | 398 | mat.delete(); 399 | mask.delete(); 400 | } 401 | }); 402 | 403 | QUnit.test('test_mat_ptr', function(assert) { 404 | const RValue = 3; 405 | const GValue = 7; 406 | const BValue = 197; 407 | 408 | // cv.CV_8UC1 + Mat::ptr(int). 409 | { 410 | let mat = new cv.Mat(10, 10, cv.CV_8UC1); 411 | let view = mat.data; 412 | 413 | // Alter matrix[2, 1]. 414 | let step = 10; 415 | view[2 * step + 1] = RValue; 416 | 417 | // Access matrix[2, 1]. 418 | view = mat.ptr(2); 419 | 420 | assert.equal(view[1], RValue); 421 | 422 | mat.delete(); 423 | } 424 | 425 | // cv.CV_8UC3 + Mat::ptr(int). 426 | { 427 | let mat = new cv.Mat(10, 10, cv.CV_8UC3); 428 | let view = mat.data; 429 | 430 | // Alter matrix[2, 1]. 431 | let step = 3 * 10; 432 | view[2 * step + 3] = RValue; 433 | view[2 * step + 3 + 1] = GValue; 434 | view[2 * step + 3 + 2] = BValue; 435 | 436 | // Access matrix[2, 1]. 437 | view = mat.ptr(2); 438 | 439 | assert.equal(view[3], RValue); 440 | assert.equal(view[3 + 1], GValue); 441 | assert.equal(view[3 + 2], BValue); 442 | 443 | mat.delete(); 444 | } 445 | 446 | // cv.CV_8UC3 + Mat::ptr(int, int). 447 | { 448 | let mat = new cv.Mat(10, 10, cv.CV_8UC3); 449 | let view = mat.data; 450 | 451 | // Alter matrix[2, 1]. 452 | let step = 3 * 10; 453 | view[2 * step + 3] = RValue; 454 | view[2 * step + 3 + 1] = GValue; 455 | view[2 * step + 3 + 2] = BValue; 456 | 457 | // Access matrix[2, 1]. 458 | view = mat.ptr(2, 1); 459 | 460 | assert.equal(view[0], RValue); 461 | assert.equal(view[1], GValue); 462 | assert.equal(view[2], BValue); 463 | 464 | mat.delete(); 465 | } 466 | 467 | const RValueF32 = 3.3; 468 | const GValueF32 = 7.3; 469 | const BValueF32 = 197.3; 470 | const EPSILON = 0.001; 471 | 472 | // cv.CV_32FC1 + Mat::ptr(int). 473 | { 474 | let mat = new cv.Mat(10, 10, cv.CV_32FC1); 475 | let view = mat.data32F; 476 | 477 | // Alter matrix[2, 1]. 478 | let step = 10; 479 | view[2 * step + 1] = RValueF32; 480 | 481 | // Access matrix[2, 1]. 482 | view = mat.floatPtr(2); 483 | 484 | assert.ok(Math.abs(view[1] - RValueF32) < EPSILON); 485 | 486 | mat.delete(); 487 | } 488 | 489 | // cv.CV_32FC3 + Mat::ptr(int). 490 | { 491 | let mat = new cv.Mat(10, 10, cv.CV_32FC3); 492 | let view = mat.data32F; 493 | 494 | // Alter matrix[2, 1]. 495 | let step = mat.step1(0); 496 | view[2 * step + 3] = RValueF32; 497 | view[2 * step + 3 + 1] = GValueF32; 498 | view[2 * step + 3 + 2] = BValueF32; 499 | 500 | // Access matrix[2, 1]. 501 | view = mat.floatPtr(2); 502 | 503 | assert.ok(Math.abs(view[3] - RValueF32) < EPSILON); 504 | assert.ok(Math.abs(view[3 + 1] - GValueF32) < EPSILON); 505 | assert.ok(Math.abs(view[3 + 2] - BValueF32) < EPSILON); 506 | 507 | mat.delete(); 508 | } 509 | 510 | // cv.CV_32FC3 + Mat::ptr(int, int). 511 | { 512 | let mat = new cv.Mat(10, 10, cv.CV_32FC3); 513 | let view = mat.data32F; 514 | 515 | // Alter matrix[2, 1]. 516 | let step = mat.step1(0); 517 | view[2 * step + 3] = RValueF32; 518 | view[2 * step + 3 + 1] = GValueF32; 519 | view[2 * step + 3 + 2] = BValueF32; 520 | 521 | // Access matrix[2, 1]. 522 | view = mat.floatPtr(2, 1); 523 | 524 | assert.ok(Math.abs(view[0] - RValueF32) < EPSILON); 525 | assert.ok(Math.abs(view[1] - GValueF32) < EPSILON); 526 | assert.ok(Math.abs(view[2] - BValueF32) < EPSILON); 527 | 528 | mat.delete(); 529 | } 530 | }); 531 | 532 | QUnit.test('test_mat_zeros', function(assert) { 533 | let zeros = new Uint8Array(10*10).fill(0); 534 | // Mat::zeros(int, int, int) 535 | { 536 | let mat = cv.Mat.zeros(10, 10, cv.CV_8UC1); 537 | let view = mat.data; 538 | 539 | assert.deepEqual(view, zeros); 540 | 541 | mat.delete(); 542 | } 543 | 544 | // Mat::zeros(Size, int) 545 | { 546 | let mat = cv.Mat.zeros({height: 10, width: 10}, cv.CV_8UC1); 547 | let view = mat.data; 548 | 549 | assert.deepEqual(view, zeros); 550 | 551 | mat.delete(); 552 | } 553 | }); 554 | 555 | QUnit.test('test_mat_ones', function(assert) { 556 | let ones = new Uint8Array(10*10).fill(1); 557 | // Mat::ones(int, int, int) 558 | { 559 | let mat = cv.Mat.ones(10, 10, cv.CV_8UC1); 560 | let view = mat.data; 561 | 562 | assert.deepEqual(view, ones); 563 | } 564 | // Mat::ones(Size, int) 565 | { 566 | let mat = cv.Mat.ones({height: 10, width: 10}, cv.CV_8UC1); 567 | let view = mat.data; 568 | 569 | assert.deepEqual(view, ones); 570 | } 571 | }); 572 | 573 | QUnit.test('test_mat_eye', function(assert) { 574 | let eye4by4 = new Uint8Array([1, 0, 0, 0, 575 | 0, 1, 0, 0, 576 | 0, 0, 1, 0, 577 | 0, 0, 0, 1]); 578 | // Mat::eye(int, int, int) 579 | { 580 | let mat = cv.Mat.eye(4, 4, cv.CV_8UC1); 581 | let view = mat.data; 582 | 583 | assert.deepEqual(view, eye4by4); 584 | } 585 | 586 | // Mat::eye(Size, int) 587 | { 588 | let mat = cv.Mat.eye({height: 4, width: 4}, cv.CV_8UC1); 589 | let view = mat.data; 590 | 591 | assert.deepEqual(view, eye4by4); 592 | } 593 | }); 594 | 595 | QUnit.test('test_mat_miscs', function(assert) { 596 | // Mat::col(int) 597 | { 598 | let mat = cv.matFromArray(2, 2, cv.CV_8UC2, [1, 2, 3, 4, 5, 6, 7, 8]); 599 | let col = mat.col(1); 600 | 601 | assert.equal(col.isContinuous(), false); 602 | assert.equal(col.ptr(0, 0)[0], 3); 603 | assert.equal(col.ptr(0, 0)[1], 4); 604 | assert.equal(col.ptr(1, 0)[0], 7); 605 | assert.equal(col.ptr(1, 0)[1], 8); 606 | 607 | col.delete(); 608 | mat.delete(); 609 | } 610 | 611 | // Mat::row(int) 612 | { 613 | let mat = cv.Mat.zeros(5, 5, cv.CV_8UC2); 614 | let row = mat.row(1); 615 | let view = row.data; 616 | assert.equal(view[0], 0); 617 | assert.equal(view[4], 0); 618 | 619 | row.delete(); 620 | mat.delete(); 621 | } 622 | 623 | // Mat::convertTo(Mat, int, double, double) 624 | { 625 | let mat = cv.Mat.ones(5, 5, cv.CV_8UC3); 626 | let grayMat = cv.Mat.zeros(5, 5, cv.CV_8UC1); 627 | 628 | mat.convertTo(grayMat, cv.CV_8U, 2, 1); 629 | // dest = 2 * source(x, y) + 1. 630 | let view = grayMat.data; 631 | assert.equal(view[0], (1 * 2) + 1); 632 | 633 | mat.convertTo(grayMat, cv.CV_8U); 634 | // dest = 1 * source(x, y) + 0. 635 | assert.equal(view[0], 1); 636 | 637 | mat.convertTo(grayMat, cv.CV_8U, 2); 638 | // dest = 2 * source(x, y) + 0. 639 | assert.equal(view[0], 2); 640 | 641 | grayMat.delete(); 642 | mat.delete(); 643 | } 644 | 645 | // split 646 | { 647 | const R =7; 648 | const G =13; 649 | const B =29; 650 | 651 | let mat = cv.Mat.ones(5, 5, cv.CV_8UC3); 652 | let view = mat.data; 653 | view[0] = R; 654 | view[1] = G; 655 | view[2] = B; 656 | 657 | let bgrPlanes = new cv.MatVector(); 658 | cv.split(mat, bgrPlanes); 659 | assert.equal(bgrPlanes.size(), 3); 660 | 661 | let rMat = bgrPlanes.get(0); 662 | view = rMat.data; 663 | assert.equal(view[0], R); 664 | 665 | let gMat = bgrPlanes.get(1); 666 | view = gMat.data; 667 | assert.equal(view[0], G); 668 | 669 | let bMat = bgrPlanes.get(2); 670 | view = bMat.data; 671 | assert.equal(view[0], B); 672 | 673 | mat.delete(); 674 | rMat.delete(); 675 | gMat.delete(); 676 | bgrPlanes.delete(); 677 | bMat.delete(); 678 | } 679 | 680 | // elemSize 681 | { 682 | let mat = cv.Mat.ones(5, 5, cv.CV_8UC3); 683 | assert.equal(mat.elemSize(), 3); 684 | assert.equal(mat.elemSize1(), 1); 685 | 686 | let mat2 = cv.Mat.zeros(5, 5, cv.CV_8UC1); 687 | assert.equal(mat2.elemSize(), 1); 688 | assert.equal(mat2.elemSize1(), 1); 689 | 690 | let mat3 = cv.Mat.eye(5, 5, cv.CV_16UC3); 691 | assert.equal(mat3.elemSize(), 2 * 3); 692 | assert.equal(mat3.elemSize1(), 2); 693 | 694 | mat.delete(); 695 | mat2.delete(); 696 | mat3.delete(); 697 | } 698 | 699 | // step 700 | { 701 | let mat = cv.Mat.ones(5, 5, cv.CV_8UC3); 702 | assert.equal(mat.step[0], 15); 703 | assert.equal(mat.step[1], 3); 704 | 705 | let mat2 = cv.Mat.zeros(5, 5, cv.CV_8UC1); 706 | assert.equal(mat2.step[0], 5); 707 | assert.equal(mat2.step[1], 1); 708 | 709 | let mat3 = cv.Mat.eye(5, 5, cv.CV_16UC3); 710 | assert.equal(mat3.step[0], 30); 711 | assert.equal(mat3.step[1], 6); 712 | 713 | mat.delete(); 714 | mat2.delete(); 715 | mat3.delete(); 716 | } 717 | 718 | // dot 719 | { 720 | let mat = cv.Mat.ones(5, 5, cv.CV_8UC1); 721 | let mat2 = cv.Mat.eye(5, 5, cv.CV_8UC1); 722 | 723 | assert.equal(mat.dot(mat), 25); 724 | assert.equal(mat.dot(mat2), 5); 725 | assert.equal(mat2.dot(mat2), 5); 726 | 727 | mat.delete(); 728 | mat2.delete(); 729 | } 730 | 731 | // mul 732 | { 733 | const FACTOR = 5; 734 | let mat = cv.Mat.ones(4, 4, cv.CV_8UC1); 735 | let mat2 = cv.Mat.eye(4, 4, cv.CV_8UC1); 736 | 737 | let expected = new Uint8Array([FACTOR, 0, 0, 0, 738 | 0, FACTOR, 0, 0, 739 | 0, 0, FACTOR, 0, 740 | 0, 0, 0, FACTOR]); 741 | let mat3 = mat.mul(mat2, FACTOR); 742 | 743 | assert.deepEqual(mat3.data, expected); 744 | 745 | mat.delete(); 746 | mat2.delete(); 747 | mat3.delete(); 748 | } 749 | }); 750 | 751 | 752 | QUnit.test('test mat access', function(assert) { 753 | // test memory view 754 | { 755 | let data = new Uint8Array([0, 0, 0, 255, 0, 1, 2, 3]); 756 | let dataPtr = cv._malloc(8); 757 | 758 | let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 8); 759 | dataHeap.set(new Uint8Array(data.buffer)); 760 | 761 | let mat = new cv.Mat(8, 1, cv.CV_8UC1, dataPtr, 0); 762 | 763 | 764 | let unsignedCharView = new Uint8Array(data.buffer); 765 | let charView = new Int8Array(data.buffer); 766 | let shortView = new Int16Array(data.buffer); 767 | let unsignedShortView = new Uint16Array(data.buffer); 768 | let intView = new Int32Array(data.buffer); 769 | let float32View = new Float32Array(data.buffer); 770 | let float64View = new Float64Array(data.buffer); 771 | 772 | 773 | assert.deepEqual(unsignedCharView, mat.data); 774 | assert.deepEqual(charView, mat.data8S); 775 | assert.deepEqual(shortView, mat.data16S); 776 | assert.deepEqual(unsignedShortView, mat.data16U); 777 | assert.deepEqual(intView, mat.data32S); 778 | assert.deepEqual(float32View, mat.data32F); 779 | assert.deepEqual(float64View, mat.data64F); 780 | } 781 | 782 | // test ucharAt(i) 783 | { 784 | let data = new Uint8Array([0, 0, 0, 255, 0, 1, 2, 3]); 785 | let dataPtr = cv._malloc(8); 786 | 787 | let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 8); 788 | dataHeap.set(new Uint8Array(data.buffer)); 789 | 790 | let mat = new cv.Mat(8, 1, cv.CV_8UC1, dataPtr, 0); 791 | 792 | assert.equal(mat.ucharAt(0), 0); 793 | assert.equal(mat.ucharAt(1), 0); 794 | assert.equal(mat.ucharAt(2), 0); 795 | assert.equal(mat.ucharAt(3), 255); 796 | assert.equal(mat.ucharAt(4), 0); 797 | assert.equal(mat.ucharAt(5), 1); 798 | assert.equal(mat.ucharAt(6), 2); 799 | assert.equal(mat.ucharAt(7), 3); 800 | } 801 | 802 | // test ushortAt(i) 803 | { 804 | let data = new Uint16Array([0, 1000, 65000, 255, 0, 1, 2, 3]); 805 | let dataPtr = cv._malloc(16); 806 | 807 | let dataHeap = new Uint16Array(cv.HEAPU8.buffer, dataPtr, 8); 808 | dataHeap.set(new Uint16Array(data.buffer)); 809 | 810 | let mat = new cv.Mat(8, 1, cv.CV_16SC1, dataPtr, 0); 811 | 812 | assert.equal(mat.ushortAt(0), 0); 813 | assert.equal(mat.ushortAt(1), 1000); 814 | assert.equal(mat.ushortAt(2), 65000); 815 | assert.equal(mat.ushortAt(3), 255); 816 | assert.equal(mat.ushortAt(4), 0); 817 | assert.equal(mat.ushortAt(5), 1); 818 | assert.equal(mat.ushortAt(6), 2); 819 | assert.equal(mat.ushortAt(7), 3); 820 | } 821 | 822 | // test intAt(i) 823 | { 824 | let data = new Int32Array([0, -1000, 65000, 255, -2000000, -1, 2, 3]); 825 | let dataPtr = cv._malloc(32); 826 | 827 | let dataHeap = new Int32Array(cv.HEAPU32.buffer, dataPtr, 8); 828 | dataHeap.set(new Int32Array(data.buffer)); 829 | 830 | let mat = new cv.Mat(8, 1, cv.CV_32SC1, dataPtr, 0); 831 | 832 | assert.equal(mat.intAt(0), 0); 833 | assert.equal(mat.intAt(1), -1000); 834 | assert.equal(mat.intAt(2), 65000); 835 | assert.equal(mat.intAt(3), 255); 836 | assert.equal(mat.intAt(4), -2000000); 837 | assert.equal(mat.intAt(5), -1); 838 | assert.equal(mat.intAt(6), 2); 839 | assert.equal(mat.intAt(7), 3); 840 | } 841 | 842 | // test floatAt(i) 843 | { 844 | const EPSILON = 0.001; 845 | let data = new Float32Array([0, -10.5, 650.001, 255, -20.1, -1.2, 2, 3.5]); 846 | let dataPtr = cv._malloc(32); 847 | 848 | let dataHeap = new Float32Array(cv.HEAPU32.buffer, dataPtr, 8); 849 | dataHeap.set(new Float32Array(data.buffer)); 850 | 851 | let mat = new cv.Mat(8, 1, cv.CV_32FC1, dataPtr, 0); 852 | 853 | assert.equal(Math.abs(mat.floatAt(0)-0) < EPSILON, true); 854 | assert.equal(Math.abs(mat.floatAt(1)+10.5) < EPSILON, true); 855 | assert.equal(Math.abs(mat.floatAt(2)-650.001) < EPSILON, true); 856 | assert.equal(Math.abs(mat.floatAt(3)-255) < EPSILON, true); 857 | assert.equal(Math.abs(mat.floatAt(4)+20.1) < EPSILON, true); 858 | assert.equal(Math.abs(mat.floatAt(5)+1.2) < EPSILON, true); 859 | assert.equal(Math.abs(mat.floatAt(6)-2) < EPSILON, true); 860 | assert.equal(Math.abs(mat.floatAt(7)-3.5) < EPSILON, true); 861 | } 862 | 863 | // test intAt(i,j) 864 | { 865 | let mat = cv.Mat.eye({height: 3, width: 3}, cv.CV_32SC1); 866 | 867 | assert.equal(mat.intAt(0, 0), 1); 868 | assert.equal(mat.intAt(0, 1), 0); 869 | assert.equal(mat.intAt(0, 2), 0); 870 | assert.equal(mat.intAt(1, 0), 0); 871 | assert.equal(mat.intAt(1, 1), 1); 872 | assert.equal(mat.intAt(1, 2), 0); 873 | assert.equal(mat.intAt(2, 0), 0); 874 | assert.equal(mat.intAt(2, 1), 0); 875 | assert.equal(mat.intAt(2, 2), 1); 876 | 877 | mat.delete(); 878 | } 879 | }); 880 | 881 | QUnit.test('test_mat_operations', function(assert) { 882 | // test minMaxLoc 883 | { 884 | let src = cv.Mat.ones(4, 4, cv.CV_8UC1); 885 | 886 | src.data[2] = 0; 887 | src.data[5] = 2; 888 | 889 | let result = cv.minMaxLoc(src); 890 | 891 | assert.equal(result.minVal, 0); 892 | assert.equal(result.maxVal, 2); 893 | assert.deepEqual(result.minLoc, {x: 2, y: 0}); 894 | assert.deepEqual(result.maxLoc, {x: 1, y: 1}); 895 | 896 | src.delete(); 897 | } 898 | }); 899 | 900 | QUnit.test('test_mat_roi', function(assert) { 901 | // test minMaxLoc 902 | { 903 | let mat = cv.matFromArray(2, 2, cv.CV_8UC1, [0, 1, 2, 3]); 904 | let roi = mat.roi(new cv.Rect(1, 1, 1, 1)); 905 | 906 | assert.equal(roi.rows, 1); 907 | assert.equal(roi.cols, 1); 908 | assert.deepEqual(roi.data, new Uint8Array([mat.ucharAt(1, 1)])); 909 | 910 | mat.delete(); 911 | roi.delete(); 912 | } 913 | }); 914 | 915 | 916 | QUnit.test('test_mat_range', function(assert) { 917 | { 918 | let src = cv.matFromArray(2, 2, cv.CV_8UC1, [0, 1, 2, 3]); 919 | let mat = src.colRange(0, 1); 920 | 921 | assert.equal(mat.isContinuous(), false); 922 | assert.equal(mat.rows, 2); 923 | assert.equal(mat.cols, 1); 924 | assert.equal(mat.ucharAt(0), 0); 925 | assert.equal(mat.ucharAt(1), 2); 926 | 927 | mat.delete(); 928 | 929 | mat = src.colRange({start: 0, end: 1}); 930 | 931 | assert.equal(mat.isContinuous(), false); 932 | assert.equal(mat.rows, 2); 933 | assert.equal(mat.cols, 1); 934 | assert.equal(mat.ucharAt(0), 0); 935 | assert.equal(mat.ucharAt(1), 2); 936 | 937 | mat.delete(); 938 | 939 | mat = src.rowRange(1, 2); 940 | 941 | assert.equal(mat.rows, 1); 942 | assert.equal(mat.cols, 2); 943 | assert.deepEqual(mat.data, new Uint8Array([2, 3])); 944 | 945 | mat.delete(); 946 | 947 | mat = src.rowRange({start: 1, end: 2}); 948 | 949 | assert.equal(mat.rows, 1); 950 | assert.equal(mat.cols, 2); 951 | assert.deepEqual(mat.data, new Uint8Array([2, 3])); 952 | 953 | mat.delete(); 954 | 955 | src.delete(); 956 | } 957 | }); 958 | 959 | QUnit.test('test_mat_diag', function(assert) { 960 | // test diag 961 | { 962 | let mat = cv.matFromArray(3, 3, cv.CV_8UC1, [0, 1, 2, 3, 4, 5, 6, 7, 8]); 963 | let d = mat.diag(); 964 | let d1 = mat.diag(1); 965 | let d2 = mat.diag(-1); 966 | 967 | assert.equal(mat.isContinuous(), true); 968 | assert.equal(d.isContinuous(), false); 969 | assert.equal(d1.isContinuous(), false); 970 | assert.equal(d2.isContinuous(), false); 971 | 972 | assert.equal(d.ucharAt(0), 0); 973 | assert.equal(d.ucharAt(1), 4); 974 | assert.equal(d.ucharAt(2), 8); 975 | 976 | assert.equal(d1.ucharAt(0), 1); 977 | assert.equal(d1.ucharAt(1), 5); 978 | 979 | assert.equal(d2.ucharAt(0), 3); 980 | assert.equal(d2.ucharAt(1), 7); 981 | 982 | mat.delete(); 983 | d.delete(); 984 | d1.delete(); 985 | d2.delete(); 986 | } 987 | }); 988 | -------------------------------------------------------------------------------- /demo/server/test_objdetect.js: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 | // 5 | // By downloading, copying, installing or using the software you agree to this license. 6 | // If you do not agree to this license, do not download, install, 7 | // copy or use the software. 8 | // 9 | // 10 | // License Agreement 11 | // For Open Source Computer Vision Library 12 | // 13 | // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 14 | // Third party copyrights are property of their respective owners. 15 | // 16 | // Redistribution and use in source and binary forms, with or without modification, 17 | // are permitted provided that the following conditions are met: 18 | // 19 | // * Redistribution's of source code must retain the above copyright notice, 20 | // this list of conditions and the following disclaimer. 21 | // 22 | // * Redistribution's in binary form must reproduce the above copyright notice, 23 | // this list of conditions and the following disclaimer in the documentation 24 | // and/or other materials provided with the distribution. 25 | // 26 | // * The name of the copyright holders may not be used to endorse or promote products 27 | // derived from this software without specific prior written permission. 28 | // 29 | // This software is provided by the copyright holders and contributors "as is" and 30 | // any express or implied warranties, including, but not limited to, the implied 31 | // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 | // In no event shall the Intel Corporation or contributors be liable for any direct, 33 | // indirect, incidental, special, exemplary, or consequential damages 34 | // (including, but not limited to, procurement of substitute goods or services; 35 | // loss of use, data, or profits; or business interruption) however caused 36 | // and on any theory of liability, whether in contract, strict liability, 37 | // or tort (including negligence or otherwise) arising in any way out of 38 | // the use of this software, even if advised of the possibility of such damage. 39 | // 40 | // 41 | 42 | // ////////////////////////////////////////////////////////////////////////////////////// 43 | // Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu 44 | // 45 | // LICENSE AGREEMENT 46 | // Copyright (c) 2015 The Regents of the University of California (Regents) 47 | // 48 | // Redistribution and use in source and binary forms, with or without 49 | // modification, are permitted provided that the following conditions are met: 50 | // 1. Redistributions of source code must retain the above copyright 51 | // notice, this list of conditions and the following disclaimer. 52 | // 2. Redistributions in binary form must reproduce the above copyright 53 | // notice, this list of conditions and the following disclaimer in the 54 | // documentation and/or other materials provided with the distribution. 55 | // 3. Neither the name of the University nor the 56 | // names of its contributors may be used to endorse or promote products 57 | // derived from this software without specific prior written permission. 58 | // 59 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY 60 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 61 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 62 | // DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY 63 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 64 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 65 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 66 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 67 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 68 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69 | // 70 | 71 | if (typeof module !== 'undefined' && module.exports) { 72 | // The environment is Node.js 73 | var cv = require('./opencv.js'); // eslint-disable-line no-var 74 | cv.FS_createLazyFile('/', 'haarcascade_frontalface_default.xml', // eslint-disable-line new-cap 75 | 'haarcascade_frontalface_default.xml', true, false); 76 | } 77 | 78 | QUnit.module('Object Detection', {}); 79 | QUnit.test('Cascade classification', function(assert) { 80 | // Group rectangle 81 | { 82 | let rectList = new cv.RectVector(); 83 | let weights = new cv.IntVector(); 84 | let groupThreshold = 1; 85 | const eps = 0.2; 86 | 87 | let rect1 = new cv.Rect(1, 2, 3, 4); 88 | let rect2 = new cv.Rect(1, 4, 2, 3); 89 | 90 | rectList.push_back(rect1); 91 | rectList.push_back(rect2); 92 | 93 | cv.groupRectangles(rectList, weights, groupThreshold, eps); 94 | 95 | 96 | rectList.delete(); 97 | weights.delete(); 98 | } 99 | 100 | // CascadeClassifier 101 | { 102 | let classifier = new cv.CascadeClassifier(); 103 | const modelPath = '/haarcascade_frontalface_default.xml'; 104 | 105 | assert.equal(classifier.empty(), true); 106 | 107 | 108 | classifier.load(modelPath); 109 | assert.equal(classifier.empty(), false); 110 | 111 | let image = cv.Mat.eye({height: 10, width: 10}, cv.CV_8UC3); 112 | let objects = new cv.RectVector(); 113 | let numDetections = new cv.IntVector(); 114 | const scaleFactor = 1.1; 115 | const minNeighbors = 3; 116 | const flags = 0; 117 | const minSize = {height: 0, width: 0}; 118 | const maxSize = {height: 10, width: 10}; 119 | 120 | classifier.detectMultiScale2(image, objects, numDetections, scaleFactor, 121 | minNeighbors, flags, minSize, maxSize); 122 | 123 | // test default parameters 124 | classifier.detectMultiScale2(image, objects, numDetections, scaleFactor, 125 | minNeighbors, flags, minSize); 126 | classifier.detectMultiScale2(image, objects, numDetections, scaleFactor, 127 | minNeighbors, flags); 128 | classifier.detectMultiScale2(image, objects, numDetections, scaleFactor, 129 | minNeighbors); 130 | classifier.detectMultiScale2(image, objects, numDetections, scaleFactor); 131 | 132 | classifier.delete(); 133 | objects.delete(); 134 | numDetections.delete(); 135 | } 136 | 137 | // HOGDescriptor 138 | { 139 | let hog = new cv.HOGDescriptor(); 140 | let mat = new cv.Mat({height: 10, width: 10}, cv.CV_8UC1); 141 | let descriptors = new cv.FloatVector(); 142 | let locations = new cv.PointVector(); 143 | 144 | 145 | assert.equal(hog.winSize.height, 128); 146 | assert.equal(hog.winSize.width, 64); 147 | assert.equal(hog.nbins, 9); 148 | assert.equal(hog.derivAperture, 1); 149 | assert.equal(hog.winSigma, -1); 150 | assert.equal(hog.histogramNormType, 0); 151 | assert.equal(hog.nlevels, 64); 152 | 153 | hog.nlevels = 32; 154 | assert.equal(hog.nlevels, 32); 155 | 156 | hog.delete(); 157 | mat.delete(); 158 | descriptors.delete(); 159 | locations.delete(); 160 | } 161 | }); 162 | -------------------------------------------------------------------------------- /demo/server/test_photo.js: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 | // 5 | // By downloading, copying, installing or using the software you agree to this license. 6 | // If you do not agree to this license, do not download, install, 7 | // copy or use the software. 8 | // 9 | // 10 | // License Agreement 11 | // For Open Source Computer Vision Library 12 | // 13 | // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 14 | // Third party copyrights are property of their respective owners. 15 | // 16 | // Redistribution and use in source and binary forms, with or without modification, 17 | // are permitted provided that the following conditions are met: 18 | // 19 | // * Redistribution's of source code must retain the above copyright notice, 20 | // this list of conditions and the following disclaimer. 21 | // 22 | // * Redistribution's in binary form must reproduce the above copyright notice, 23 | // this list of conditions and the following disclaimer in the documentation 24 | // and/or other materials provided with the distribution. 25 | // 26 | // * The name of the copyright holders may not be used to endorse or promote products 27 | // derived from this software without specific prior written permission. 28 | // 29 | // This software is provided by the copyright holders and contributors "as is" and 30 | // any express or implied warranties, including, but not limited to, the implied 31 | // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 | // In no event shall the Intel Corporation or contributors be liable for any direct, 33 | // indirect, incidental, special, exemplary, or consequential damages 34 | // (including, but not limited to, procurement of substitute goods or services; 35 | // loss of use, data, or profits; or business interruption) however caused 36 | // and on any theory of liability, whether in contract, strict liability, 37 | // or tort (including negligence or otherwise) arising in any way out of 38 | // the use of this software, even if advised of the possibility of such damage. 39 | // 40 | 41 | // Author : Rijubrata Bhaumik, Intel Corporation. rijubrata.bhaumik[at]intel[dot]com 42 | 43 | if (typeof module !== 'undefined' && module.exports) { 44 | // The environment is Node.js 45 | var cv = require('./opencv.js'); // eslint-disable-line no-var 46 | } 47 | 48 | 49 | QUnit.module('Photo', {}); 50 | 51 | QUnit.test('test_photo', function(assert) { 52 | // CalibrateDebevec 53 | { 54 | let calibration = new cv.CalibrateDebevec(); 55 | assert.ok(true, calibration); 56 | //let response = calibration.process(images, exposures); 57 | } 58 | // CalibrateRobertson 59 | { 60 | let calibration = new cv.CalibrateRobertson(); 61 | assert.ok(true, calibration); 62 | //let response = calibration.process(images, exposures); 63 | } 64 | 65 | // MergeDebevec 66 | { 67 | let merge = new cv.MergeDebevec(); 68 | assert.ok(true, merge); 69 | //let hdr = merge.process(images, exposures, response); 70 | } 71 | // MergeMertens 72 | { 73 | let merge = new cv.MergeMertens(); 74 | assert.ok(true, merge); 75 | //let hdr = merge.process(images, exposures, response); 76 | } 77 | // MergeRobertson 78 | { 79 | let merge = new cv.MergeRobertson(); 80 | assert.ok(true, merge); 81 | //let hdr = merge.process(images, exposures, response); 82 | } 83 | 84 | // TonemapDrago 85 | { 86 | let tonemap = new cv.TonemapDrago(); 87 | assert.ok(true, tonemap); 88 | // let ldr = new cv.Mat(); 89 | // let retval = tonemap.process(hdr, ldr); 90 | } 91 | // TonemapMantiuk 92 | { 93 | let tonemap = new cv.TonemapMantiuk(); 94 | assert.ok(true, tonemap); 95 | // let ldr = new cv.Mat(); 96 | // let retval = tonemap.process(hdr, ldr); 97 | } 98 | // TonemapReinhard 99 | { 100 | let tonemap = new cv.TonemapReinhard(); 101 | assert.ok(true, tonemap); 102 | // let ldr = new cv.Mat(); 103 | // let retval = tonemap.process(hdr, ldr); 104 | } 105 | // Inpaint 106 | { 107 | let src = new cv.Mat(100, 100, cv.CV_8UC3, new cv.Scalar(127, 127, 127, 255)); 108 | let mask = new cv.Mat(100, 100, cv.CV_8UC1, new cv.Scalar(0, 0, 0, 0)); 109 | let dst = new cv.Mat(); 110 | cv.line(mask, new cv.Point(10, 50), new cv.Point(90, 50), new cv.Scalar(255, 255, 255, 255),5); 111 | cv.inpaint(src, mask, dst, 3, cv.INPAINT_TELEA); 112 | assert.equal(dst.rows, 100); 113 | assert.equal(dst.cols, 100); 114 | assert.equal(dst.channels(), 3); 115 | } 116 | }); 117 | -------------------------------------------------------------------------------- /demo/server/test_utils.js: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 | // 5 | // By downloading, copying, installing or using the software you agree to this license. 6 | // If you do not agree to this license, do not download, install, 7 | // copy or use the software. 8 | // 9 | // 10 | // License Agreement 11 | // For Open Source Computer Vision Library 12 | // 13 | // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 14 | // Third party copyrights are property of their respective owners. 15 | // 16 | // Redistribution and use in source and binary forms, with or without modification, 17 | // are permitted provided that the following conditions are met: 18 | // 19 | // * Redistribution's of source code must retain the above copyright notice, 20 | // this list of conditions and the following disclaimer. 21 | // 22 | // * Redistribution's in binary form must reproduce the above copyright notice, 23 | // this list of conditions and the following disclaimer in the documentation 24 | // and/or other materials provided with the distribution. 25 | // 26 | // * The name of the copyright holders may not be used to endorse or promote products 27 | // derived from this software without specific prior written permission. 28 | // 29 | // This software is provided by the copyright holders and contributors "as is" and 30 | // any express or implied warranties, including, but not limited to, the implied 31 | // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 | // In no event shall the Intel Corporation or contributors be liable for any direct, 33 | // indirect, incidental, special, exemplary, or consequential damages 34 | // (including, but not limited to, procurement of substitute goods or services; 35 | // loss of use, data, or profits; or business interruption) however caused 36 | // and on any theory of liability, whether in contract, strict liability, 37 | // or tort (including negligence or otherwise) arising in any way out of 38 | // the use of this software, even if advised of the possibility of such damage. 39 | // 40 | 41 | // ////////////////////////////////////////////////////////////////////////////////////// 42 | // Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu 43 | // 44 | // LICENSE AGREEMENT 45 | // Copyright (c) 2015 The Regents of the University of California (Regents) 46 | // 47 | // Redistribution and use in source and binary forms, with or without 48 | // modification, are permitted provided that the following conditions are met: 49 | // 1. Redistributions of source code must retain the above copyright 50 | // notice, this list of conditions and the following disclaimer. 51 | // 2. Redistributions in binary form must reproduce the above copyright 52 | // notice, this list of conditions and the following disclaimer in the 53 | // documentation and/or other materials provided with the distribution. 54 | // 3. Neither the name of the University nor the 55 | // names of its contributors may be used to endorse or promote products 56 | // derived from this software without specific prior written permission. 57 | // 58 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY 59 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 60 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 61 | // DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY 62 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 63 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 64 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 65 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 66 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 67 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 | // 69 | 70 | if (typeof module !== 'undefined' && module.exports) { 71 | // The environment is Node.js 72 | var cv = require('./opencv.js'); // eslint-disable-line no-var 73 | } 74 | QUnit.module('Utils', {}); 75 | QUnit.test('Test vectors', function(assert) { 76 | { 77 | let pointVector = new cv.PointVector(); 78 | for (let i=0; i<100; ++i) { 79 | pointVector.push_back({x: i, y: 2*i}); 80 | } 81 | 82 | assert.equal(pointVector.size(), 100); 83 | 84 | let index = 10; 85 | let item = pointVector.get(index); 86 | assert.equal(item.x, index); 87 | assert.equal(item.y, 2*index); 88 | 89 | index = 0; 90 | item = pointVector.get(index); 91 | assert.equal(item.x, index); 92 | assert.equal(item.y, 2*index); 93 | 94 | index = 99; 95 | item = pointVector.get(index); 96 | assert.equal(item.x, index); 97 | assert.equal(item.y, 2*index); 98 | 99 | pointVector.delete(); 100 | } 101 | 102 | { 103 | let pointVector = new cv.PointVector(); 104 | for (let i=0; i<100; ++i) { 105 | pointVector.push_back(new cv.Point(i, 2*i)); 106 | } 107 | 108 | pointVector.push_back(new cv.Point()); 109 | 110 | assert.equal(pointVector.size(), 101); 111 | 112 | let index = 10; 113 | let item = pointVector.get(index); 114 | assert.equal(item.x, index); 115 | assert.equal(item.y, 2*index); 116 | 117 | index = 0; 118 | item = pointVector.get(index); 119 | assert.equal(item.x, index); 120 | assert.equal(item.y, 2*index); 121 | 122 | index = 99; 123 | item = pointVector.get(index); 124 | assert.equal(item.x, index); 125 | assert.equal(item.y, 2*index); 126 | 127 | index = 100; 128 | item = pointVector.get(index); 129 | assert.equal(item.x, 0); 130 | assert.equal(item.y, 0); 131 | 132 | pointVector.delete(); 133 | } 134 | }); 135 | QUnit.test('Test Rect', function(assert) { 136 | let rectVector = new cv.RectVector(); 137 | let rect = {x: 1, y: 2, width: 3, height: 4}; 138 | rectVector.push_back(rect); 139 | rectVector.push_back(new cv.Rect()); 140 | rectVector.push_back(new cv.Rect(rect)); 141 | rectVector.push_back(new cv.Rect({x: 5, y: 6}, {width: 7, height: 8})); 142 | rectVector.push_back(new cv.Rect(9, 10, 11, 12)); 143 | 144 | assert.equal(rectVector.size(), 5); 145 | 146 | let item = rectVector.get(0); 147 | assert.equal(item.x, 1); 148 | assert.equal(item.y, 2); 149 | assert.equal(item.width, 3); 150 | assert.equal(item.height, 4); 151 | 152 | item = rectVector.get(1); 153 | assert.equal(item.x, 0); 154 | assert.equal(item.y, 0); 155 | assert.equal(item.width, 0); 156 | assert.equal(item.height, 0); 157 | 158 | item = rectVector.get(2); 159 | assert.equal(item.x, 1); 160 | assert.equal(item.y, 2); 161 | assert.equal(item.width, 3); 162 | assert.equal(item.height, 4); 163 | 164 | item = rectVector.get(3); 165 | assert.equal(item.x, 5); 166 | assert.equal(item.y, 6); 167 | assert.equal(item.width, 7); 168 | assert.equal(item.height, 8); 169 | 170 | item = rectVector.get(4); 171 | assert.equal(item.x, 9); 172 | assert.equal(item.y, 10); 173 | assert.equal(item.width, 11); 174 | assert.equal(item.height, 12); 175 | 176 | rectVector.delete(); 177 | }); 178 | QUnit.test('Test Size', function(assert) { 179 | { 180 | let mat = new cv.Mat(); 181 | mat.create({width: 5, height: 10}, cv.CV_8UC4); 182 | let size = mat.size(); 183 | 184 | assert.ok(mat.type() === cv.CV_8UC4); 185 | assert.ok(size.height === 10); 186 | assert.ok(size.width === 5); 187 | assert.ok(mat.channels() === 4); 188 | 189 | mat.delete(); 190 | } 191 | 192 | { 193 | let mat = new cv.Mat(); 194 | mat.create(new cv.Size(5, 10), cv.CV_8UC4); 195 | let size = mat.size(); 196 | 197 | assert.ok(mat.type() === cv.CV_8UC4); 198 | assert.ok(size.height === 10); 199 | assert.ok(size.width === 5); 200 | assert.ok(mat.channels() === 4); 201 | 202 | mat.delete(); 203 | } 204 | }); 205 | 206 | 207 | QUnit.test('test_rotated_rect', function(assert) { 208 | { 209 | let rect = {center: {x: 100, y: 100}, size: {height: 100, width: 50}, angle: 30}; 210 | 211 | assert.equal(rect.center.x, 100); 212 | assert.equal(rect.center.y, 100); 213 | assert.equal(rect.angle, 30); 214 | assert.equal(rect.size.height, 100); 215 | assert.equal(rect.size.width, 50); 216 | } 217 | 218 | { 219 | let rect = new cv.RotatedRect(); 220 | 221 | assert.equal(rect.center.x, 0); 222 | assert.equal(rect.center.y, 0); 223 | assert.equal(rect.angle, 0); 224 | assert.equal(rect.size.height, 0); 225 | assert.equal(rect.size.width, 0); 226 | 227 | let points = cv.RotatedRect.points(rect); 228 | 229 | assert.equal(points[0].x, 0); 230 | assert.equal(points[0].y, 0); 231 | assert.equal(points[1].x, 0); 232 | assert.equal(points[1].y, 0); 233 | assert.equal(points[2].x, 0); 234 | assert.equal(points[2].y, 0); 235 | assert.equal(points[3].x, 0); 236 | assert.equal(points[3].y, 0); 237 | } 238 | 239 | { 240 | let rect = new cv.RotatedRect({x: 100, y: 100}, {height: 100, width: 50}, 30); 241 | 242 | assert.equal(rect.center.x, 100); 243 | assert.equal(rect.center.y, 100); 244 | assert.equal(rect.angle, 30); 245 | assert.equal(rect.size.height, 100); 246 | assert.equal(rect.size.width, 50); 247 | 248 | let points = cv.RotatedRect.points(rect); 249 | 250 | assert.equal(points[0].x, cv.RotatedRect.boundingRect2f(rect).x); 251 | assert.equal(points[1].y, cv.RotatedRect.boundingRect2f(rect).y); 252 | } 253 | }); 254 | -------------------------------------------------------------------------------- /demo/server/test_video.js: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 | // 5 | // By downloading, copying, installing or using the software you agree to this license. 6 | // If you do not agree to this license, do not download, install, 7 | // copy or use the software. 8 | // 9 | // 10 | // License Agreement 11 | // For Open Source Computer Vision Library 12 | // 13 | // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 14 | // Third party copyrights are property of their respective owners. 15 | // 16 | // Redistribution and use in source and binary forms, with or without modification, 17 | // are permitted provided that the following conditions are met: 18 | // 19 | // * Redistribution's of source code must retain the above copyright notice, 20 | // this list of conditions and the following disclaimer. 21 | // 22 | // * Redistribution's in binary form must reproduce the above copyright notice, 23 | // this list of conditions and the following disclaimer in the documentation 24 | // and/or other materials provided with the distribution. 25 | // 26 | // * The name of the copyright holders may not be used to endorse or promote products 27 | // derived from this software without specific prior written permission. 28 | // 29 | // This software is provided by the copyright holders and contributors "as is" and 30 | // any express or implied warranties, including, but not limited to, the implied 31 | // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 | // In no event shall the Intel Corporation or contributors be liable for any direct, 33 | // indirect, incidental, special, exemplary, or consequential damages 34 | // (including, but not limited to, procurement of substitute goods or services; 35 | // loss of use, data, or profits; or business interruption) however caused 36 | // and on any theory of liability, whether in contract, strict liability, 37 | // or tort (including negligence or otherwise) arising in any way out of 38 | // the use of this software, even if advised of the possibility of such damage. 39 | // 40 | 41 | // ////////////////////////////////////////////////////////////////////////////////////// 42 | // Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu 43 | // 44 | // LICENSE AGREEMENT 45 | // Copyright (c) 2015 The Regents of the University of California (Regents) 46 | // 47 | // Redistribution and use in source and binary forms, with or without 48 | // modification, are permitted provided that the following conditions are met: 49 | // 1. Redistributions of source code must retain the above copyright 50 | // notice, this list of conditions and the following disclaimer. 51 | // 2. Redistributions in binary form must reproduce the above copyright 52 | // notice, this list of conditions and the following disclaimer in the 53 | // documentation and/or other materials provided with the distribution. 54 | // 3. Neither the name of the University nor the 55 | // names of its contributors may be used to endorse or promote products 56 | // derived from this software without specific prior written permission. 57 | // 58 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY 59 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 60 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 61 | // DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY 62 | // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 63 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 64 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 65 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 66 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 67 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 | // 69 | 70 | if (typeof module !== 'undefined' && module.exports) { 71 | // The environment is Node.js 72 | var cv = require('./opencv.js'); // eslint-disable-line no-var 73 | } 74 | 75 | QUnit.module('Video', {}); 76 | QUnit.test('Background Segmentation', function(assert) { 77 | // BackgroundSubtractorMOG2 78 | { 79 | const history = 600; 80 | const varThreshold = 15; 81 | const detectShadows = true; 82 | 83 | let mog2 = new cv.BackgroundSubtractorMOG2(history, varThreshold, detectShadows); 84 | 85 | assert.equal(mog2 instanceof cv.BackgroundSubtractorMOG2, true); 86 | 87 | mog2.delete(); 88 | 89 | mog2 = new cv.BackgroundSubtractorMOG2(); 90 | 91 | assert.equal(mog2 instanceof cv.BackgroundSubtractorMOG2, true); 92 | 93 | mog2.delete(); 94 | 95 | mog2 = new cv.BackgroundSubtractorMOG2(history); 96 | 97 | assert.equal(mog2 instanceof cv.BackgroundSubtractorMOG2, true); 98 | 99 | mog2.delete(); 100 | 101 | mog2 = new cv.BackgroundSubtractorMOG2(history, varThreshold); 102 | 103 | assert.equal(mog2 instanceof cv.BackgroundSubtractorMOG2, true); 104 | 105 | mog2.delete(); 106 | } 107 | }); 108 | -------------------------------------------------------------------------------- /demo/server/tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | OpenCV JS Tests 5 | 6 | 7 | 8 | 18 | 19 | 93 | 94 | 95 | 96 |
97 |
98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /demo/server/tests.js: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 | // 5 | // By downloading, copying, installing or using the software you agree to this license. 6 | // If you do not agree to this license, do not download, install, 7 | // copy or use the software. 8 | // 9 | // 10 | // License Agreement 11 | // For Open Source Computer Vision Library 12 | // 13 | // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 14 | // Third party copyrights are property of their respective owners. 15 | // 16 | // Redistribution and use in source and binary forms, with or without modification, 17 | // are permitted provided that the following conditions are met: 18 | // 19 | // * Redistribution's of source code must retain the above copyright notice, 20 | // this list of conditions and the following disclaimer. 21 | // 22 | // * Redistribution's in binary form must reproduce the above copyright notice, 23 | // this list of conditions and the following disclaimer in the documentation 24 | // and/or other materials provided with the distribution. 25 | // 26 | // * The name of the copyright holders may not be used to endorse or promote products 27 | // derived from this software without specific prior written permission. 28 | // 29 | // This software is provided by the copyright holders and contributors "as is" and 30 | // any express or implied warranties, including, but not limited to, the implied 31 | // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 | // In no event shall the Intel Corporation or contributors be liable for any direct, 33 | // indirect, incidental, special, exemplary, or consequential damages 34 | // (including, but not limited to, procurement of substitute goods or services; 35 | // loss of use, data, or profits; or business interruption) however caused 36 | // and on any theory of liability, whether in contract, strict liability, 37 | // or tort (including negligence or otherwise) arising in any way out of 38 | // the use of this software, even if advised of the possibility of such damage. 39 | // 40 | 41 | let testrunner = require('node-qunit'); 42 | testrunner.options.maxBlockDuration = 20000; // cause opencv_js.js need time to load 43 | 44 | testrunner.run( 45 | { 46 | code: 'opencv.js', 47 | tests: ['test_mat.js', 'test_utils.js', 'test_imgproc.js', 48 | 'test_objdetect.js', 'test_video.js', 'test_features2d.js', 49 | 'test_photo.js', 50 | 'test_calib3d.js' 51 | ], 52 | }, 53 | function(err, report) { 54 | console.log(report.failed + ' failed, ' + report.passed + ' passed'); 55 | if (report.failed) { 56 | process.on('exit', function() { 57 | process.exit(1); 58 | }); 59 | } 60 | } 61 | ); 62 | --------------------------------------------------------------------------------