test_imgproc.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  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. if (typeof module !== 'undefined' && module.exports) {
  70. // The environment is Node.js
  71. var cv = require('./opencv.js'); // eslint-disable-line no-var
  72. }
  73. QUnit.module('Image Processing', {});
  74. QUnit.test('test_imgProc', function(assert) {
  75. // calcHist
  76. {
  77. let vec1 = new cv.Mat.ones(new cv.Size(20, 20), cv.CV_8UC1); // eslint-disable-line new-cap
  78. let source = new cv.MatVector();
  79. source.push_back(vec1);
  80. let channels = [0];
  81. let histSize = [256];
  82. let ranges =[0, 256];
  83. let hist = new cv.Mat();
  84. let mask = new cv.Mat();
  85. let binSize = cv._malloc(4);
  86. let binView = new Int32Array(cv.HEAP8.buffer, binSize);
  87. binView[0] = 10;
  88. cv.calcHist(source, channels, mask, hist, histSize, ranges, false);
  89. // hist should contains a N X 1 array.
  90. let size = hist.size();
  91. assert.equal(size.height, 256);
  92. assert.equal(size.width, 1);
  93. // default parameters
  94. cv.calcHist(source, channels, mask, hist, histSize, ranges);
  95. size = hist.size();
  96. assert.equal(size.height, 256);
  97. assert.equal(size.width, 1);
  98. // Do we need to verify data in histogram?
  99. // let dataView = hist.data;
  100. // Free resource
  101. cv._free(binSize);
  102. mask.delete();
  103. hist.delete();
  104. }
  105. // cvtColor
  106. {
  107. let source = new cv.Mat(10, 10, cv.CV_8UC3);
  108. let dest = new cv.Mat();
  109. cv.cvtColor(source, dest, cv.COLOR_BGR2GRAY, 0);
  110. assert.equal(dest.channels(), 1);
  111. cv.cvtColor(source, dest, cv.COLOR_BGR2GRAY);
  112. assert.equal(dest.channels(), 1);
  113. cv.cvtColor(source, dest, cv.COLOR_BGR2BGRA, 0);
  114. assert.equal(dest.channels(), 4);
  115. cv.cvtColor(source, dest, cv.COLOR_BGR2BGRA);
  116. assert.equal(dest.channels(), 4);
  117. dest.delete();
  118. source.delete();
  119. }
  120. // equalizeHist
  121. {
  122. let source = new cv.Mat(10, 10, cv.CV_8UC1);
  123. let dest = new cv.Mat();
  124. cv.equalizeHist(source, dest);
  125. // eualizeHist changes the content of a image, but does not alter meta data
  126. // of it.
  127. assert.equal(source.channels(), dest.channels());
  128. assert.equal(source.type(), dest.type());
  129. dest.delete();
  130. source.delete();
  131. }
  132. // floodFill
  133. {
  134. let center = new cv.Point(5, 5);
  135. let rect = new cv.Rect(0, 0, 0, 0);
  136. let img = new cv.Mat.zeros(10, 10, cv.CV_8UC1);
  137. let color = new cv.Scalar (255);
  138. cv.circle(img, center, 3, color, 1);
  139. let edge = new cv.Mat();
  140. cv.Canny(img, edge, 100, 255);
  141. cv.copyMakeBorder(edge, edge, 1, 1, 1, 1, cv.BORDER_REPLICATE);
  142. let expected_img_data = new Uint8Array([
  143. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  144. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  145. 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
  146. 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
  147. 0, 0, 0, 255, 0, 255, 0, 255, 0, 0,
  148. 0, 0, 255, 255, 255, 255, 0, 0, 255, 0,
  149. 0, 0, 0, 255, 0, 0, 0, 255, 0, 0,
  150. 0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
  151. 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
  152. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
  153. let img_elem = 10*10*1;
  154. let expected_img_data_ptr = cv._malloc(img_elem);
  155. let expected_img_data_heap = new Uint8Array(cv.HEAPU8.buffer,
  156. expected_img_data_ptr,
  157. img_elem);
  158. expected_img_data_heap.set(new Uint8Array(expected_img_data.buffer));
  159. let expected_img = new cv.Mat( 10, 10, cv.CV_8UC1, expected_img_data_ptr, 0);
  160. let expected_rect = new cv.Rect(3,3,3,3);
  161. let compare_result = new cv.Mat(10, 10, cv.CV_8UC1);
  162. cv.floodFill(img, edge, center, color, rect);
  163. cv.compare (img, expected_img, compare_result, cv.CMP_EQ);
  164. // expect every pixels are the same.
  165. assert.equal (cv.countNonZero(compare_result), img.total());
  166. assert.equal (rect.x, expected_rect.x);
  167. assert.equal (rect.y, expected_rect.y);
  168. assert.equal (rect.width, expected_rect.width);
  169. assert.equal (rect.height, expected_rect.height);
  170. img.delete();
  171. edge.delete();
  172. expected_img.delete();
  173. compare_result.delete();
  174. }
  175. // fillPoly
  176. {
  177. let img_width = 6;
  178. let img_height = 6;
  179. let img = new cv.Mat.zeros(img_height, img_width, cv.CV_8UC1);
  180. let npts = 4;
  181. let square_point_data = new Uint8Array([
  182. 1, 1,
  183. 4, 1,
  184. 4, 4,
  185. 1, 4]);
  186. let square_points = cv.matFromArray(npts, 1, cv.CV_32SC2, square_point_data);
  187. let pts = new cv.MatVector();
  188. pts.push_back (square_points);
  189. let color = new cv.Scalar (255);
  190. let expected_img_data = new Uint8Array([
  191. 0, 0, 0, 0, 0, 0,
  192. 0, 255, 255, 255, 255, 0,
  193. 0, 255, 255, 255, 255, 0,
  194. 0, 255, 255, 255, 255, 0,
  195. 0, 255, 255, 255, 255, 0,
  196. 0, 0, 0, 0, 0, 0]);
  197. let expected_img = cv.matFromArray(img_height, img_width, cv.CV_8UC1, expected_img_data);
  198. cv.fillPoly(img, pts, color);
  199. let compare_result = new cv.Mat(img_height, img_width, cv.CV_8UC1);
  200. cv.compare (img, expected_img, compare_result, cv.CMP_EQ);
  201. // expect every pixels are the same.
  202. assert.equal (cv.countNonZero(compare_result), img.total());
  203. img.delete();
  204. square_points.delete();
  205. pts.delete();
  206. expected_img.delete();
  207. compare_result.delete();
  208. }
  209. // fillConvexPoly
  210. {
  211. let img_width = 6;
  212. let img_height = 6;
  213. let img = new cv.Mat.zeros(img_height, img_width, cv.CV_8UC1);
  214. let npts = 4;
  215. let square_point_data = new Uint8Array([
  216. 1, 1,
  217. 4, 1,
  218. 4, 4,
  219. 1, 4]);
  220. let square_points = cv.matFromArray(npts, 1, cv.CV_32SC2, square_point_data);
  221. let color = new cv.Scalar (255);
  222. let expected_img_data = new Uint8Array([
  223. 0, 0, 0, 0, 0, 0,
  224. 0, 255, 255, 255, 255, 0,
  225. 0, 255, 255, 255, 255, 0,
  226. 0, 255, 255, 255, 255, 0,
  227. 0, 255, 255, 255, 255, 0,
  228. 0, 0, 0, 0, 0, 0]);
  229. let expected_img = cv.matFromArray(img_height, img_width, cv.CV_8UC1, expected_img_data);
  230. cv.fillConvexPoly(img, square_points, color);
  231. let compare_result = new cv.Mat(img_height, img_width, cv.CV_8UC1);
  232. cv.compare (img, expected_img, compare_result, cv.CMP_EQ);
  233. // expect every pixels are the same.
  234. assert.equal (cv.countNonZero(compare_result), img.total());
  235. img.delete();
  236. square_points.delete();
  237. expected_img.delete();
  238. compare_result.delete();
  239. }
  240. });
  241. QUnit.test('test_segmentation', function(assert) {
  242. const THRESHOLD = 127.0;
  243. const THRESHOLD_MAX = 210.0;
  244. // threshold
  245. {
  246. let source = new cv.Mat(1, 5, cv.CV_8UC1);
  247. let sourceView = source.data;
  248. sourceView[0] = 0; // < threshold
  249. sourceView[1] = 100; // < threshold
  250. sourceView[2] = 200; // > threshold
  251. let dest = new cv.Mat();
  252. cv.threshold(source, dest, THRESHOLD, THRESHOLD_MAX, cv.THRESH_BINARY);
  253. let destView = dest.data;
  254. assert.equal(destView[0], 0);
  255. assert.equal(destView[1], 0);
  256. assert.equal(destView[2], THRESHOLD_MAX);
  257. }
  258. // adaptiveThreshold
  259. {
  260. let source = cv.Mat.zeros(1, 5, cv.CV_8UC1);
  261. let sourceView = source.data;
  262. sourceView[0] = 50;
  263. sourceView[1] = 150;
  264. sourceView[2] = 200;
  265. let dest = new cv.Mat();
  266. const C = 0;
  267. const blockSize = 3;
  268. cv.adaptiveThreshold(source, dest, THRESHOLD_MAX,
  269. cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, blockSize, C);
  270. let destView = dest.data;
  271. assert.equal(destView[0], 0);
  272. assert.equal(destView[1], THRESHOLD_MAX);
  273. assert.equal(destView[2], THRESHOLD_MAX);
  274. }
  275. });
  276. QUnit.test('test_shape', function(assert) {
  277. // moments
  278. {
  279. let points = new cv.Mat(1, 4, cv.CV_32SC2);
  280. let data32S = points.data32S;
  281. data32S[0]=50;
  282. data32S[1]=56;
  283. data32S[2]=53;
  284. data32S[3]=53;
  285. data32S[4]=46;
  286. data32S[5]=54;
  287. data32S[6]=49;
  288. data32S[7]=51;
  289. let m = cv.moments(points, false);
  290. let area = cv.contourArea(points, false);
  291. assert.equal(m.m00, 0);
  292. assert.equal(m.m01, 0);
  293. assert.equal(m.m10, 0);
  294. assert.equal(area, 0);
  295. // default parameters
  296. m = cv.moments(points);
  297. area = cv.contourArea(points);
  298. assert.equal(m.m00, 0);
  299. assert.equal(m.m01, 0);
  300. assert.equal(m.m10, 0);
  301. assert.equal(area, 0);
  302. points.delete();
  303. }
  304. });
  305. QUnit.test('test_min_enclosing', function(assert) {
  306. {
  307. let points = new cv.Mat(4, 1, cv.CV_32FC2);
  308. points.data32F[0] = 0;
  309. points.data32F[1] = 0;
  310. points.data32F[2] = 1;
  311. points.data32F[3] = 0;
  312. points.data32F[4] = 1;
  313. points.data32F[5] = 1;
  314. points.data32F[6] = 0;
  315. points.data32F[7] = 1;
  316. let circle = cv.minEnclosingCircle(points);
  317. assert.deepEqual(circle.center, {x: 0.5, y: 0.5});
  318. assert.ok(Math.abs(circle.radius - Math.sqrt(2) / 2) < 0.001);
  319. points.delete();
  320. }
  321. });
  322. QUnit.test('test_filter', function(assert) {
  323. // blur
  324. {
  325. let mat1 = cv.Mat.ones(5, 5, cv.CV_8UC3);
  326. let mat2 = new cv.Mat();
  327. cv.blur(mat1, mat2, {height: 3, width: 3}, {x: -1, y: -1}, cv.BORDER_DEFAULT);
  328. // Verify result.
  329. let size = mat2.size();
  330. assert.equal(mat2.channels(), 3);
  331. assert.equal(size.height, 5);
  332. assert.equal(size.width, 5);
  333. cv.blur(mat1, mat2, {height: 3, width: 3}, {x: -1, y: -1});
  334. // Verify result.
  335. size = mat2.size();
  336. assert.equal(mat2.channels(), 3);
  337. assert.equal(size.height, 5);
  338. assert.equal(size.width, 5);
  339. cv.blur(mat1, mat2, {height: 3, width: 3});
  340. // Verify result.
  341. size = mat2.size();
  342. assert.equal(mat2.channels(), 3);
  343. assert.equal(size.height, 5);
  344. assert.equal(size.width, 5);
  345. mat1.delete();
  346. mat2.delete();
  347. }
  348. // GaussianBlur
  349. {
  350. let mat1 = cv.Mat.ones(7, 7, cv.CV_8UC1);
  351. let mat2 = new cv.Mat();
  352. cv.GaussianBlur(mat1, mat2, new cv.Size(3, 3), 0, 0, // eslint-disable-line new-cap
  353. cv.BORDER_DEFAULT);
  354. // Verify result.
  355. let size = mat2.size();
  356. assert.equal(mat2.channels(), 1);
  357. assert.equal(size.height, 7);
  358. assert.equal(size.width, 7);
  359. }
  360. // medianBlur
  361. {
  362. let mat1 = cv.Mat.ones(9, 9, cv.CV_8UC3);
  363. let mat2 = new cv.Mat();
  364. cv.medianBlur(mat1, mat2, 3);
  365. // Verify result.
  366. let size = mat2.size();
  367. assert.equal(mat2.channels(), 3);
  368. assert.equal(size.height, 9);
  369. assert.equal(size.width, 9);
  370. }
  371. // Transpose
  372. {
  373. let mat1 = cv.Mat.eye(9, 9, cv.CV_8UC3);
  374. let mat2 = new cv.Mat();
  375. cv.transpose(mat1, mat2);
  376. // Verify result.
  377. let size = mat2.size();
  378. assert.equal(mat2.channels(), 3);
  379. assert.equal(size.height, 9);
  380. assert.equal(size.width, 9);
  381. }
  382. // bilateralFilter
  383. {
  384. let mat1 = cv.Mat.ones(11, 11, cv.CV_8UC3);
  385. let mat2 = new cv.Mat();
  386. cv.bilateralFilter(mat1, mat2, 3, 6, 1.5, cv.BORDER_DEFAULT);
  387. // Verify result.
  388. let size = mat2.size();
  389. assert.equal(mat2.channels(), 3);
  390. assert.equal(size.height, 11);
  391. assert.equal(size.width, 11);
  392. // default parameters
  393. cv.bilateralFilter(mat1, mat2, 3, 6, 1.5);
  394. // Verify result.
  395. size = mat2.size();
  396. assert.equal(mat2.channels(), 3);
  397. assert.equal(size.height, 11);
  398. assert.equal(size.width, 11);
  399. mat1.delete();
  400. mat2.delete();
  401. }
  402. // Watershed
  403. {
  404. let mat = cv.Mat.ones(11, 11, cv.CV_8UC3);
  405. let out = new cv.Mat(11, 11, cv.CV_32SC1);
  406. cv.watershed(mat, out);
  407. // Verify result.
  408. let size = out.size();
  409. assert.equal(out.channels(), 1);
  410. assert.equal(size.height, 11);
  411. assert.equal(size.width, 11);
  412. assert.equal(out.elemSize1(), 4);
  413. mat.delete();
  414. out.delete();
  415. }
  416. // Concat
  417. {
  418. let mat = cv.Mat.ones({height: 10, width: 5}, cv.CV_8UC3);
  419. let mat2 = cv.Mat.eye({height: 10, width: 5}, cv.CV_8UC3);
  420. let mat3 = cv.Mat.eye({height: 10, width: 5}, cv.CV_8UC3);
  421. let out = new cv.Mat();
  422. let input = new cv.MatVector();
  423. input.push_back(mat);
  424. input.push_back(mat2);
  425. input.push_back(mat3);
  426. cv.vconcat(input, out);
  427. // Verify result.
  428. let size = out.size();
  429. assert.equal(out.channels(), 3);
  430. assert.equal(size.height, 30);
  431. assert.equal(size.width, 5);
  432. assert.equal(out.elemSize1(), 1);
  433. cv.hconcat(input, out);
  434. // Verify result.
  435. size = out.size();
  436. assert.equal(out.channels(), 3);
  437. assert.equal(size.height, 10);
  438. assert.equal(size.width, 15);
  439. assert.equal(out.elemSize1(), 1);
  440. input.delete();
  441. out.delete();
  442. }
  443. // distanceTransform letiants
  444. {
  445. let mat = cv.Mat.ones(11, 11, cv.CV_8UC1);
  446. let out = new cv.Mat(11, 11, cv.CV_32FC1);
  447. let labels = new cv.Mat(11, 11, cv.CV_32FC1);
  448. const maskSize = 3;
  449. cv.distanceTransform(mat, out, cv.DIST_L2, maskSize, cv.CV_32F);
  450. // Verify result.
  451. let size = out.size();
  452. assert.equal(out.channels(), 1);
  453. assert.equal(size.height, 11);
  454. assert.equal(size.width, 11);
  455. assert.equal(out.elemSize1(), 4);
  456. cv.distanceTransformWithLabels(mat, out, labels, cv.DIST_L2, maskSize,
  457. cv.DIST_LABEL_CCOMP);
  458. // Verify result.
  459. size = out.size();
  460. assert.equal(out.channels(), 1);
  461. assert.equal(size.height, 11);
  462. assert.equal(size.width, 11);
  463. assert.equal(out.elemSize1(), 4);
  464. size = labels.size();
  465. assert.equal(labels.channels(), 1);
  466. assert.equal(size.height, 11);
  467. assert.equal(size.width, 11);
  468. assert.equal(labels.elemSize1(), 4);
  469. mat.delete();
  470. out.delete();
  471. labels.delete();
  472. }
  473. // Min, Max
  474. {
  475. let data1 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9]);
  476. let data2 = new Uint8Array([0, 4, 0, 8, 0, 12, 0, 16, 0]);
  477. let expectedMin = new Uint8Array([0, 2, 0, 4, 0, 6, 0, 8, 0]);
  478. let expectedMax = new Uint8Array([1, 4, 3, 8, 5, 12, 7, 16, 9]);
  479. let dataPtr = cv._malloc(3*3*1);
  480. let dataPtr2 = cv._malloc(3*3*1);
  481. let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 3*3*1);
  482. dataHeap.set(new Uint8Array(data1.buffer));
  483. let dataHeap2 = new Uint8Array(cv.HEAPU8.buffer, dataPtr2, 3*3*1);
  484. dataHeap2.set(new Uint8Array(data2.buffer));
  485. let mat1 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr, 0);
  486. let mat2 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr2, 0);
  487. let mat3 = new cv.Mat();
  488. cv.min(mat1, mat2, mat3);
  489. // Verify result.
  490. let size = mat2.size();
  491. assert.equal(mat2.channels(), 1);
  492. assert.equal(size.height, 3);
  493. assert.equal(size.width, 3);
  494. assert.deepEqual(mat3.data, expectedMin);
  495. cv.max(mat1, mat2, mat3);
  496. // Verify result.
  497. size = mat2.size();
  498. assert.equal(mat2.channels(), 1);
  499. assert.equal(size.height, 3);
  500. assert.equal(size.width, 3);
  501. assert.deepEqual(mat3.data, expectedMax);
  502. cv._free(dataPtr);
  503. cv._free(dataPtr2);
  504. }
  505. // Bitwise operations
  506. {
  507. let data1 = new Uint8Array([0, 1, 2, 4, 8, 16, 32, 64, 128]);
  508. let data2 = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255]);
  509. let expectedAnd = new Uint8Array([0, 1, 2, 4, 8, 16, 32, 64, 128]);
  510. let expectedOr = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255]);
  511. let expectedXor = new Uint8Array([255, 254, 253, 251, 247, 239, 223, 191, 127]);
  512. let expectedNot = new Uint8Array([255, 254, 253, 251, 247, 239, 223, 191, 127]);
  513. let dataPtr = cv._malloc(3*3*1);
  514. let dataPtr2 = cv._malloc(3*3*1);
  515. let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 3*3*1);
  516. dataHeap.set(new Uint8Array(data1.buffer));
  517. let dataHeap2 = new Uint8Array(cv.HEAPU8.buffer, dataPtr2, 3*3*1);
  518. dataHeap2.set(new Uint8Array(data2.buffer));
  519. let mat1 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr, 0);
  520. let mat2 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr2, 0);
  521. let mat3 = new cv.Mat();
  522. let none = new cv.Mat();
  523. cv.bitwise_not(mat1, mat3, none);
  524. // Verify result.
  525. let size = mat3.size();
  526. assert.equal(mat3.channels(), 1);
  527. assert.equal(size.height, 3);
  528. assert.equal(size.width, 3);
  529. assert.deepEqual(mat3.data, expectedNot);
  530. cv.bitwise_and(mat1, mat2, mat3, none);
  531. // Verify result.
  532. size = mat3.size();
  533. assert.equal(mat3.channels(), 1);
  534. assert.equal(size.height, 3);
  535. assert.equal(size.width, 3);
  536. assert.deepEqual(mat3.data, expectedAnd);
  537. cv.bitwise_or(mat1, mat2, mat3, none);
  538. // Verify result.
  539. size = mat3.size();
  540. assert.equal(mat3.channels(), 1);
  541. assert.equal(size.height, 3);
  542. assert.equal(size.width, 3);
  543. assert.deepEqual(mat3.data, expectedOr);
  544. cv.bitwise_xor(mat1, mat2, mat3, none);
  545. // Verify result.
  546. size = mat3.size();
  547. assert.equal(mat3.channels(), 1);
  548. assert.equal(size.height, 3);
  549. assert.equal(size.width, 3);
  550. assert.deepEqual(mat3.data, expectedXor);
  551. cv._free(dataPtr);
  552. cv._free(dataPtr2);
  553. }
  554. // Arithmetic operations
  555. {
  556. let data1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8]);
  557. let data2 = new Uint8Array([0, 2, 4, 6, 8, 10, 12, 14, 16]);
  558. let data3 = new Uint8Array([0, 1, 0, 1, 0, 1, 0, 1, 0]);
  559. // |data1 - data2|
  560. let expectedAbsDiff = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8]);
  561. let expectedAdd = new Uint8Array([0, 3, 6, 9, 12, 15, 18, 21, 24]);
  562. const alpha = 4;
  563. const beta = -1;
  564. const gamma = 3;
  565. // 4*data1 - data2 + 3
  566. let expectedWeightedAdd = new Uint8Array([3, 5, 7, 9, 11, 13, 15, 17, 19]);
  567. let dataPtr = cv._malloc(3*3*1);
  568. let dataPtr2 = cv._malloc(3*3*1);
  569. let dataPtr3 = cv._malloc(3*3*1);
  570. let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 3*3*1);
  571. dataHeap.set(new Uint8Array(data1.buffer));
  572. let dataHeap2 = new Uint8Array(cv.HEAPU8.buffer, dataPtr2, 3*3*1);
  573. dataHeap2.set(new Uint8Array(data2.buffer));
  574. let dataHeap3 = new Uint8Array(cv.HEAPU8.buffer, dataPtr3, 3*3*1);
  575. dataHeap3.set(new Uint8Array(data3.buffer));
  576. let mat1 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr, 0);
  577. let mat2 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr2, 0);
  578. let mat3 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr3, 0);
  579. let dst = new cv.Mat();
  580. let none = new cv.Mat();
  581. cv.absdiff(mat1, mat2, dst);
  582. // Verify result.
  583. let size = dst.size();
  584. assert.equal(dst.channels(), 1);
  585. assert.equal(size.height, 3);
  586. assert.equal(size.width, 3);
  587. assert.deepEqual(dst.data, expectedAbsDiff);
  588. cv.add(mat1, mat2, dst, none, -1);
  589. // Verify result.
  590. size = dst.size();
  591. assert.equal(dst.channels(), 1);
  592. assert.equal(size.height, 3);
  593. assert.equal(size.width, 3);
  594. assert.deepEqual(dst.data, expectedAdd);
  595. cv.addWeighted(mat1, alpha, mat2, beta, gamma, dst, -1);
  596. // Verify result.
  597. size = dst.size();
  598. assert.equal(dst.channels(), 1);
  599. assert.equal(size.height, 3);
  600. assert.equal(size.width, 3);
  601. assert.deepEqual(dst.data, expectedWeightedAdd);
  602. // default parameter
  603. cv.addWeighted(mat1, alpha, mat2, beta, gamma, dst);
  604. // Verify result.
  605. size = dst.size();
  606. assert.equal(dst.channels(), 1);
  607. assert.equal(size.height, 3);
  608. assert.equal(size.width, 3);
  609. assert.deepEqual(dst.data, expectedWeightedAdd);
  610. mat1.delete();
  611. mat2.delete();
  612. mat3.delete();
  613. dst.delete();
  614. none.delete();
  615. }
  616. // Integral letiants
  617. {
  618. let mat = cv.Mat.eye({height: 100, width: 100}, cv.CV_8UC3);
  619. let sum = new cv.Mat();
  620. let sqSum = new cv.Mat();
  621. let title = new cv.Mat();
  622. cv.integral(mat, sum, -1);
  623. // Verify result.
  624. let size = sum.size();
  625. assert.equal(sum.channels(), 3);
  626. assert.equal(size.height, 100+1);
  627. assert.equal(size.width, 100+1);
  628. cv.integral2(mat, sum, sqSum, -1, -1);
  629. // Verify result.
  630. size = sum.size();
  631. assert.equal(sum.channels(), 3);
  632. assert.equal(size.height, 100+1);
  633. assert.equal(size.width, 100+1);
  634. size = sqSum.size();
  635. assert.equal(sqSum.channels(), 3);
  636. assert.equal(size.height, 100+1);
  637. assert.equal(size.width, 100+1);
  638. mat.delete();
  639. sum.delete();
  640. sqSum.delete();
  641. title.delete();
  642. }
  643. // Mean, meanSTDev
  644. {
  645. let mat = cv.Mat.eye({height: 100, width: 100}, cv.CV_8UC3);
  646. let sum = new cv.Mat();
  647. let sqSum = new cv.Mat();
  648. let title = new cv.Mat();
  649. cv.integral(mat, sum, -1);
  650. // Verify result.
  651. let size = sum.size();
  652. assert.equal(sum.channels(), 3);
  653. assert.equal(size.height, 100+1);
  654. assert.equal(size.width, 100+1);
  655. cv.integral2(mat, sum, sqSum, -1, -1);
  656. // Verify result.
  657. size = sum.size();
  658. assert.equal(sum.channels(), 3);
  659. assert.equal(size.height, 100+1);
  660. assert.equal(size.width, 100+1);
  661. size = sqSum.size();
  662. assert.equal(sqSum.channels(), 3);
  663. assert.equal(size.height, 100+1);
  664. assert.equal(size.width, 100+1);
  665. mat.delete();
  666. sum.delete();
  667. sqSum.delete();
  668. title.delete();
  669. }
  670. // Invert
  671. {
  672. let inv1 = new cv.Mat();
  673. let inv2 = new cv.Mat();
  674. let inv3 = new cv.Mat();
  675. let inv4 = new cv.Mat();
  676. let data1 = new Float32Array([1, 0, 0,
  677. 0, 1, 0,
  678. 0, 0, 1]);
  679. let data2 = new Float32Array([0, 0, 0,
  680. 0, 5, 0,
  681. 0, 0, 0]);
  682. let data3 = new Float32Array([1, 1, 1, 0,
  683. 0, 3, 1, 2,
  684. 2, 3, 1, 0,
  685. 1, 0, 2, 1]);
  686. let data4 = new Float32Array([1, 4, 5,
  687. 4, 2, 2,
  688. 5, 2, 2]);
  689. let expected1 = new Float32Array([1, 0, 0,
  690. 0, 1, 0,
  691. 0, 0, 1]);
  692. // Inverse does not exist!
  693. let expected3 = new Float32Array([-3, -1/2, 3/2, 1,
  694. 1, 1/4, -1/4, -1/2,
  695. 3, 1/4, -5/4, -1/2,
  696. -3, 0, 1, 1]);
  697. let expected4 = new Float32Array([0, -1, 1,
  698. -1, 23/2, -9,
  699. 1, -9, 7]);
  700. let dataPtr1 = cv._malloc(3*3*4);
  701. let dataPtr2 = cv._malloc(3*3*4);
  702. let dataPtr3 = cv._malloc(4*4*4);
  703. let dataPtr4 = cv._malloc(3*3*4);
  704. let dataHeap = new Float32Array(cv.HEAP32.buffer, dataPtr1, 3*3);
  705. dataHeap.set(new Float32Array(data1.buffer));
  706. let dataHeap2 = new Float32Array(cv.HEAP32.buffer, dataPtr2, 3*3);
  707. dataHeap2.set(new Float32Array(data2.buffer));
  708. let dataHeap3 = new Float32Array(cv.HEAP32.buffer, dataPtr3, 4*4);
  709. dataHeap3.set(new Float32Array(data3.buffer));
  710. let dataHeap4 = new Float32Array(cv.HEAP32.buffer, dataPtr4, 3*3);
  711. dataHeap4.set(new Float32Array(data4.buffer));
  712. let mat1 = new cv.Mat(3, 3, cv.CV_32FC1, dataPtr1, 0);
  713. let mat2 = new cv.Mat(3, 3, cv.CV_32FC1, dataPtr2, 0);
  714. let mat3 = new cv.Mat(4, 4, cv.CV_32FC1, dataPtr3, 0);
  715. let mat4 = new cv.Mat(3, 3, cv.CV_32FC1, dataPtr4, 0);
  716. QUnit.assert.deepEqualWithTolerance = function( value, expected, tolerance ) {
  717. for (let i = 0; i < value.length; i= i+1) {
  718. this.pushResult( {
  719. result: Math.abs(value[i]-expected[i]) < tolerance,
  720. actual: value[i],
  721. expected: expected[i],
  722. } );
  723. }
  724. };
  725. cv.invert(mat1, inv1, 0);
  726. // Verify result.
  727. let size = inv1.size();
  728. assert.equal(inv1.channels(), 1);
  729. assert.equal(size.height, 3);
  730. assert.equal(size.width, 3);
  731. assert.deepEqualWithTolerance(inv1.data32F, expected1, 0.0001);
  732. cv.invert(mat2, inv2, 0);
  733. // Verify result.
  734. assert.deepEqualWithTolerance(inv3.data32F, expected3, 0.0001);
  735. cv.invert(mat3, inv3, 0);
  736. // Verify result.
  737. size = inv3.size();
  738. assert.equal(inv3.channels(), 1);
  739. assert.equal(size.height, 4);
  740. assert.equal(size.width, 4);
  741. assert.deepEqualWithTolerance(inv3.data32F, expected3, 0.0001);
  742. cv.invert(mat3, inv3, 1);
  743. // Verify result.
  744. assert.deepEqualWithTolerance(inv3.data32F, expected3, 0.0001);
  745. cv.invert(mat4, inv4, 2);
  746. // Verify result.
  747. assert.deepEqualWithTolerance(inv4.data32F, expected4, 0.0001);
  748. cv.invert(mat4, inv4, 3);
  749. // Verify result.
  750. assert.deepEqualWithTolerance(inv4.data32F, expected4, 0.0001);
  751. mat1.delete();
  752. mat2.delete();
  753. mat3.delete();
  754. mat4.delete();
  755. inv1.delete();
  756. inv2.delete();
  757. inv3.delete();
  758. inv4.delete();
  759. }
  760. //Rotate
  761. {
  762. let dst = new cv.Mat();
  763. let src = cv.matFromArray(3, 2, cv.CV_8U, [1,2,3,4,5,6]);
  764. cv.rotate(src, dst, cv.ROTATE_90_CLOCKWISE);
  765. size = dst.size();
  766. assert.equal(size.height, 2, "ROTATE_HEIGHT");
  767. assert.equal(size.width, 3, "ROTATE_WIGTH");
  768. let expected = new Uint8Array([5,3,1,6,4,2]);
  769. assert.deepEqual(dst.data, expected);
  770. dst.delete();
  771. src.delete();
  772. }
  773. });
  774. QUnit.test('warpPolar', function(assert) {
  775. const lines = new cv.Mat(255, 255, cv.CV_8U, new cv.Scalar(0));
  776. for (let r = 0; r < lines.rows; r++) {
  777. lines.row(r).setTo(new cv.Scalar(r));
  778. }
  779. cv.warpPolar(lines, lines, { width: 5, height: 5 }, new cv.Point(2, 2), 3,
  780. cv.INTER_CUBIC | cv.WARP_FILL_OUTLIERS | cv.WARP_INVERSE_MAP);
  781. assert.ok(lines instanceof cv.Mat);
  782. assert.deepEqual(Array.from(lines.data), [
  783. 159, 172, 191, 210, 223,
  784. 146, 159, 191, 223, 236,
  785. 128, 128, 0, 0, 0,
  786. 109, 96, 64, 32, 19,
  787. 96, 83, 64, 45, 32
  788. ]);
  789. });
  790. QUnit.test('IntelligentScissorsMB', function(assert) {
  791. const lines = new cv.Mat(50, 100, cv.CV_8U, new cv.Scalar(0));
  792. lines.row(10).setTo(new cv.Scalar(255));
  793. assert.ok(lines instanceof cv.Mat);
  794. let tool = new cv.segmentation_IntelligentScissorsMB();
  795. tool.applyImage(lines);
  796. assert.ok(lines instanceof cv.Mat);
  797. lines.delete();
  798. tool.buildMap(new cv.Point(10, 10));
  799. let contour = new cv.Mat();
  800. tool.getContour(new cv.Point(50, 10), contour);
  801. assert.equal(contour.type(), cv.CV_32SC2);
  802. assert.ok(contour.total() == 41, contour.total());
  803. tool.getContour(new cv.Point(80, 10), contour);
  804. assert.equal(contour.type(), cv.CV_32SC2);
  805. assert.ok(contour.total() == 71, contour.total());
  806. });