├── .gitignore
├── .travis.yml
├── test
├── files
│ ├── eye-tjs.json
│ ├── leye-old-tjs.json
│ ├── leye-old.json
│ ├── eye.json
│ ├── leye-old.xml
│ ├── eye2.xml
│ ├── eye.xml
│ └── eye-malformed.xml
├── test-converter-tjs-transform.js
└── test-converter-tjs.js
├── .editorconfig
├── package.json
├── LICENSE
├── src
├── converter-tjs-transform.js
└── converter-tjs.js
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | modified_files/
3 | *.log
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
4 | - "0.11"
5 |
--------------------------------------------------------------------------------
/test/files/eye-tjs.json:
--------------------------------------------------------------------------------
1 | [20,20,-1.4562760591506958,1,1,2,0,8,20,12,-1,0,14,20,6,2,0.12963959574699402,-0.7730420827865601,0.6835014820098877]
2 |
--------------------------------------------------------------------------------
/test/files/leye-old-tjs.json:
--------------------------------------------------------------------------------
1 | [
2 | 18,
3 | 12,
4 | -1.9446439743041992,
5 | 1,
6 | 0,
7 | 2,
8 | 3,
9 | 0,
10 | 12,
11 | 12,
12 | -1,
13 | 7,
14 | 4,
15 | 4,
16 | 4,
17 | 9,
18 | -0.5461140871047974,
19 | 0.8206881880760193,
20 | -0.7562180161476135
21 | ]
22 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_size = 2
6 | indent_style = tab
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.js]
13 | indent_style = space
14 |
15 | [*.yml]
16 | indent_style = space
17 |
18 |
19 | [*.xml]
20 | insert_final_newline = false
21 |
--------------------------------------------------------------------------------
/test/files/leye-old.json:
--------------------------------------------------------------------------------
1 | {
2 | "nstages": 1,
3 | "stages": [
4 | {
5 | "stageThreshold": -1.9446439743041992,
6 | "nodes": [
7 | {
8 | "left_val": 0.8206881880760193,
9 | "right_val": -0.7562180161476135,
10 | "threshold": -0.5461140871047974,
11 | "f": 0
12 | }
13 | ],
14 | "nnodes": 1
15 | }
16 | ],
17 | "rects": [
18 | {
19 | "data": [
20 | "3 0 12 12 -1.",
21 | "7 4 4 4 9."
22 | ],
23 | "tilted": 0
24 | }
25 | ],
26 | "maxWeakCount": 0,
27 | "cascadeSize": {
28 | "width": 18,
29 | "height": 12
30 | },
31 | "maxCatCount": 0
32 | }
--------------------------------------------------------------------------------
/test/files/eye.json:
--------------------------------------------------------------------------------
1 | {
2 | "nstages": 1,
3 | "stages": [
4 | {
5 | "stageThreshold": -1.4562760591506958,
6 | "nodes": [
7 | {
8 | "left_val": -0.7730420827865601,
9 | "right_val": 0.6835014820098877,
10 | "threshold": 0.12963959574699402,
11 | "f": 0
12 | }
13 | ],
14 | "nnodes": 1
15 | }
16 | ],
17 | "rects": [
18 | {
19 | "data": [
20 | "0 8 20 12 -1.",
21 | "0 14 20 6 2."
22 | ],
23 | "tilted": 1
24 | }
25 | ],
26 | "maxWeakCount": 0,
27 | "cascadeSize": {
28 | "width": 20,
29 | "height": 20
30 | },
31 | "maxCatCount": 0
32 | }
33 |
--------------------------------------------------------------------------------
/test/files/leye-old.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 18 12
4 |
5 | <_>
6 |
7 |
8 | <_>
9 |
10 | <_>
11 |
12 |
13 |
14 | <_>3 0 12 12 -1.
15 | <_>7 4 4 4 9.
16 |
17 | 0
18 |
19 | -5.4611408710479736e-001
20 | 8.2068818807601929e-001
21 | -7.5621801614761353e-001
22 |
23 |
24 |
25 | -1.9446439743041992e+000
26 | -1
27 | -1
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gulp-converter-tjs",
3 | "description": "Converts new type of OpenCV HaarCascade xml data to tracking.js internal rep",
4 | "version": "0.0.3",
5 | "main": "src/converter-tjs-transform.js",
6 | "scripts": {
7 | "test": "mocha test"
8 | },
9 | "author": "Ciro S. Costa (http://www.cirocosta.com.br/)",
10 | "license": "MIT",
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/cirocosta/gulp-converter-tjs.git"
14 | },
15 | "bugs": {
16 | "url": "https://github.com/cirocosta/gulp-converter-tjs/issues"
17 | },
18 | "homepage": "https://github.com/cirocosta/gulp-converter-tjs",
19 | "dependencies": {
20 | "gulp-util": "^3.0.0",
21 | "through2": "^0.5.1",
22 | "xml-stream": "^0.4.5"
23 | },
24 | "devDependencies": {
25 | "gulp": "^3.8.7",
26 | "mocha": "^1.21.4",
27 | "vinyl": "^0.3.2"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/files/eye2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BOOST
5 | HAAR
6 | 50
7 | 50
8 |
9 | 1
10 |
11 |
12 | 0
13 |
14 | 1
15 |
16 | <_>
17 | 1
18 | -1.4515760591501958e+00
19 |
20 | <_>
21 | 0 -1 0 1.5913959574199405e-01
22 | -7.7304208278151001e-01 1.8350148200988770e-01
23 |
24 |
25 |
26 |
27 |
28 | <_>
29 |
30 | <_>0 8 20 12 -1.
31 | <_>0 14 20 1 2.
32 |
33 | 1
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test/files/eye.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BOOST
5 | HAAR
6 | 20
7 | 20
8 |
9 | 1
10 |
11 |
12 | 0
13 |
14 | 1
15 |
16 | <_>
17 | 1
18 | -1.4562760591506958e+00
19 |
20 | <_>
21 | 0 -1 0 1.2963959574699402e-01
22 | -7.7304208278656006e-01 6.8350148200988770e-01
23 |
24 |
25 |
26 |
27 |
28 | <_>
29 |
30 | <_>0 8 20 12 -1.
31 | <_>0 14 20 6 2.
32 |
33 | 1
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Ciro S. Costa
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/test/files/eye-malformed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BOOST
5 | HAAR
6 | 20
7 | 20
8 |
9 | 1
10 |
11 |
12 | 0
13 |
14 | 1
15 |
16 | <_>
17 | 1
18 | -1.4562760591506958e+00
19 |
20 | <_>
21 | 0 -1 0 1.2963959574699402e-01
22 | -7.7304208278656006e-01 6.8350148200988770e-01
23 |
24 |
25 |
26 |
27 |
28 | <_>
29 |
30 | <_>0 8 20 12 -1.
31 | <_>0 14 20 6 2.
32 |
33 |
34 | <_>
35 |
36 | <_>0 55 22 3 -3.
37 | <_>1 1 20 3 1.
38 |
39 | 1
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/converter-tjs-transform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var through = require('through2')
4 | , converter = require('./converter-tjs')()
5 | , Readable = require('stream').Readable || require('readable-stream')
6 | , PluginError = require('gulp-util').PluginError
7 | , NAME = 'gulp-converter-tjs';
8 |
9 | /**
10 | * Creates a stream w/ data.
11 | */
12 | function createStream (data) {
13 | var rs = new Readable({ objectMode: true });
14 | rs.push(data);
15 | rs.push(null);
16 |
17 | return rs;
18 | }
19 |
20 | /**
21 | * The transform itself
22 | */
23 | function ConverterTJS () {
24 | if (!(this instanceof ConverterTJS))
25 | return new ConverterTJS();
26 |
27 | function _transform (file, enc, callback) {
28 | if (file.isStream())
29 | return (this.emit('error', new PluginError(NAME, 'Streams are not supported!')),
30 | callback());
31 |
32 | if (file.isBuffer()) {
33 | var stream = createStream(file.contents.toString());
34 | var scope = this;
35 |
36 | stream.on('error', this.emit.bind(this, 'error'));
37 | converter.convert(stream, function (err, data) {
38 | if (err)
39 | return (scope.emit('error', new PluginError(NAME, err)),
40 | callback());
41 |
42 | file.contents = new Buffer(JSON.stringify(converter.toTJS(data)));
43 | scope.push(file);
44 | callback();
45 | });
46 | }
47 | }
48 |
49 | return through.obj(_transform);
50 | }
51 |
52 | module.exports = ConverterTJS;
53 |
--------------------------------------------------------------------------------
/test/test-converter-tjs-transform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var assert = require('assert')
4 | , fs = require('fs')
5 | , gutil = require('gulp-util')
6 | , File = require('vinyl')
7 | , converterTjs = require('../src/converter-tjs-transform')
8 | , path = require('path').resolve(__dirname, './files');
9 |
10 | describe('converterTransform', function() {
11 | it('should be sane', function() {
12 | assert(!!converterTjs);
13 | });
14 |
15 | var converter;
16 |
17 | it('should not deal with gulp streams', function(done) {
18 | converter = converterTjs();
19 | var stream = fs.createReadStream(path + '/eye.xml');
20 | var file = new File({contents: stream});
21 |
22 | assert.throws(function () {
23 | converter.write(file);
24 | }, 'Streams are not allowed');
25 |
26 | done();
27 | });
28 |
29 | describe('Regarding the new format', function() {
30 |
31 | beforeEach(function () {
32 | converter = converterTjs();
33 | });
34 |
35 | it('should deal with gulp buffers', function(done) {
36 | var xml = fs.readFileSync(path + '/eye.xml');
37 | var file = new File({contents: new Buffer(xml)});
38 |
39 | converter.write(file);
40 | converter.end();
41 |
42 | converter.once('data', function (f) {
43 | var actual = JSON.parse(f.contents.toString());
44 | var expected = JSON.parse(
45 | fs.readFileSync(path + '/eye-tjs.json'));
46 |
47 | assert.deepEqual(actual, expected);
48 | done();
49 | });
50 | });
51 | });
52 |
53 |
54 | describe('Regarding the Old format', function() {
55 |
56 | beforeEach(function () {
57 | converter = converterTjs('old');
58 | });
59 |
60 | it('should deal with gulp buffers regarding old format', function(done) {
61 | var xml = fs.readFileSync(path + '/leye-old.xml');
62 | var file = new File({contents: new Buffer(xml)});
63 |
64 | converter.write(file);
65 | converter.end();
66 |
67 | converter.once('data', function (f) {
68 | var actual = JSON.parse(f.contents.toString());
69 | var expected = JSON.parse(
70 | fs.readFileSync(path + '/leye-old-tjs.json'));
71 |
72 | assert.deepEqual(actual, expected);
73 | done();
74 | });
75 | });
76 | });
77 |
78 | });
79 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # gulp-converter-tjs [](https://travis-ci.org/cirocosta/gulp-converter-tjs)
2 |
3 | > Converts new and old type of [OpenCV](https://github.com/Itseez/opencv) HaarCascade XML data to [tracking.js](https://github.com/eduardolundgren/tracking.js)' internal format.
4 |
5 | ## Process
6 |
7 | *converter-tjs* takes a XML of OpenCV training data (new or old type), parses it to an internal representation (JavaScript object) and then pushes to stdout the *tracking.js* representation of it.
8 |
9 | ### Example
10 |
11 | ```javascript
12 | var gulp = require('gulp');
13 | var converterTjs = require('gulp-converter-tjs');
14 |
15 | gulp.task('default', function () {
16 | gulp.src('./test/files/haarcascade_frontalface_alt.xml')
17 | .pipe(converterTjs())
18 | .pipe(gulp.dest('./modified-files'));
19 | });
20 | ```
21 |
22 | ```xml
23 |
24 |
25 |
26 | BOOST
27 | HAAR
28 | 20
29 | 20
30 |
31 | 1
32 |
33 |
34 | 0
35 |
36 | 1
37 |
38 | <_>
39 | 1
40 | -1.4562760591506958e+00
41 |
42 | <_>
43 | 0 -1 0 1.2963959574699402e-01
44 | -7.7304208278656006e-01 6.8350148200988770e-01
45 |
46 |
47 |
48 |
49 |
50 | <_>
51 |
52 | <_>0 8 20 12 -1.
53 | <_>0 14 20 6 2.
54 |
55 | 1
56 |
57 |
58 |
59 |
60 | ```
61 |
62 | turns into
63 |
64 | ```json
65 | {
66 | "nstages": 1,
67 | "stages": [
68 | {
69 | "stageThreshold": -1.4562760591506958,
70 | "nodes": [
71 | {
72 | "left_val": -0.77304208278656006,
73 | "right_val": -0.68350148200988770,
74 | "threshold": 0.12963959574699402,
75 | "f": 0
76 | }
77 | ],
78 | "nnodes": 1
79 | }
80 | ],
81 | "rects": [
82 | {
83 | "data": [
84 | "0 8 20 12 -1.",
85 | "0 14 20 6 2."
86 | ],
87 | "tilted": 1
88 | }
89 | ],
90 | "maxWeakCount": 0,
91 | "cascadeSize": {
92 | "width": 20,
93 | "height": 20
94 | },
95 | "maxCatCount": 0
96 | }
97 | ```
98 |
99 | which turns into
100 |
101 | ```javascript
102 | [20,20,-1.4562760591506958,1,1,2,0,8,20,12,-1,0,14,20,6,2,0.12963959574699402, -0.77304208278656006,-0.68350148200988770]
103 |
104 | // which is similar to a flattened nested array w/ loops ('[]') like the following:
105 |
106 | [width, height,
107 | [stageThreshold, nodeLength,
108 | [tilted, rectsLength,
109 | [rL, rT, rW, rH, rWeigth]
110 | nThreshold, nL, nR]]]
111 | ```
112 |
--------------------------------------------------------------------------------
/test/test-converter-tjs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var fs = require('fs')
4 | , path = require('path')
5 | , assert = require('assert')
6 | , ConverterTJS = require('../src/converter-tjs')
7 | , Readable = require('stream').Readable || require('readable-stream');
8 |
9 |
10 | function createStream (data) {
11 | var rs = new Readable({ objectMode: true });
12 | rs.push(data);
13 | rs.push(null);
14 |
15 | return rs;
16 | }
17 |
18 | describe('converter\'s', function() {
19 | it('should be sane', function() {
20 | assert(!!ConverterTJS);
21 | });
22 |
23 | var converter = new ConverterTJS();
24 | var filesPath = path.resolve(__dirname, './files');
25 |
26 | describe('convert method', function() {
27 | it('should convert new type directly from a stream', function(done) {
28 | var stream = fs.createReadStream(filesPath + '/eye.xml',
29 | {encoding: 'utf8'});
30 |
31 | converter.convert(stream, function (err, result) {
32 | if (err) done(err);
33 |
34 | var expected = fs.readFileSync(filesPath + '/eye.json');
35 |
36 | assert.deepEqual(result, JSON.parse(expected));
37 | done();
38 | });
39 | });
40 |
41 | it('should convert new type from a fake stream', function (done) {
42 | var fileContent = fs.readFileSync(filesPath + '/eye.xml',
43 | {enconding: 'utf8'});
44 | var stream = createStream(fileContent);
45 |
46 | converter.convert(stream, function (err, result) {
47 | if (err) done(err);
48 |
49 | var expected = fs.readFileSync(filesPath + '/eye.json');
50 |
51 | assert.deepEqual(result, JSON.parse(expected));
52 | done();
53 | });
54 | });
55 |
56 | it('should throw if malformed new type of haar cascade', function(done) {
57 | var stream = fs.createReadStream(filesPath + '/eye-malformed.xml',
58 | {encoding: 'utf8'});
59 |
60 | converter.convert(stream, function (err, result) {
61 | if (err)
62 | (assert(err), done());
63 | else
64 | done(new Error('Should throw an exception'));
65 | });
66 | });
67 |
68 | it('should convert an old type directly from a stream', function(done) {
69 | var stream = fs.createReadStream(filesPath + '/leye-old.xml',
70 | {encoding: 'utf8'});
71 |
72 | converter.convert(stream, function (err, result) {
73 | if (err) done (err);
74 |
75 | var expected = fs.readFileSync(filesPath + '/leye-old.json');
76 |
77 | assert.deepEqual(result, JSON.parse(expected));
78 | done();
79 | });
80 | });
81 | });
82 |
83 | describe('toTJS method', function() {
84 | it('should convert a haarStruct from the new type of xml', function() {
85 | var fileRes = fs.readFileSync(filesPath + '/eye-tjs.json');
86 | var orig = fs.readFileSync(filesPath + '/eye.json');
87 |
88 | var expected = JSON.parse(fileRes);
89 | var actual = converter.toTJS(JSON.parse(orig));
90 |
91 | assert.deepEqual(actual, expected)
92 | });
93 |
94 | it('should convert a haarStruct from the old type of xml', function() {
95 | var fileRes = fs.readFileSync(filesPath + '/leye-old-tjs.json');
96 | var orig = fs.readFileSync(filesPath + '/leye-old.json');
97 | var expected = JSON.parse(fileRes);
98 | var actual = converter.toTJS(JSON.parse(orig));
99 |
100 | assert.deepEqual(actual, expected);
101 | });
102 | });
103 | });
104 |
--------------------------------------------------------------------------------
/src/converter-tjs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var fs = require('fs')
4 | , path = require('path')
5 | , XmlStream = require('xml-stream');
6 |
7 | /**
8 | * Constructor
9 | */
10 | function ConverterTJS () {
11 | if (!(this instanceof ConverterTJS))
12 | return new ConverterTJS();
13 | }
14 |
15 |
16 | /**
17 | * Converts the new type of opencv haarcascade
18 | * classifiers to an internal representation.
19 | * @param {stream} stream stream of xml
20 | * @param {Function} cb callback function
21 | * to be resolved with
22 | * (err|data), w/ data
23 | * being the result
24 | * structure
25 | */
26 | ConverterTJS.prototype.convert = function (stream, cb) {
27 | if (!stream)
28 | throw new Error('A stream must be passed');
29 |
30 | var f = 0;
31 | var g = 0;
32 |
33 | var xml = new XmlStream(stream);
34 | var haarStruct = {
35 | nstages: 0,
36 | stages: [],
37 | rects: [],
38 | maxWeakCount: 0,
39 | cascadeSize: {
40 | width: 0,
41 | height: 0
42 | },
43 | maxCatCount: 0
44 | };
45 |
46 | xml.collect('_');
47 |
48 | xml.on('endElement: size', function (item) {
49 | var sizes = item['$text'].split(' ');
50 |
51 | haarStruct.cascadeSize.width = +sizes[0];
52 | haarStruct.cascadeSize.height = +sizes[1];
53 | });
54 |
55 | xml.on('endElement: cascade > height', function (item) {
56 | haarStruct.cascadeSize.height = +item['$text'];
57 | });
58 |
59 | xml.on('endElement: cascade > width', function (item) {
60 | haarStruct.cascadeSize.width = +item['$text'];
61 | });
62 |
63 | xml.on('endElement: stages > _', function (item) {
64 | if (!item.trees) {
65 | // dealing with the new type
66 | var stage = {
67 | stageThreshold: parseFloat(item.stageThreshold),
68 | nodes: []
69 | };
70 |
71 | stage.nnodes = item.weakClassifiers['_'].length;
72 |
73 | for (var i = 0 ; i < stage.nnodes; i++) {
74 | var internalNodes = item
75 | .weakClassifiers['_'][i]
76 | .internalNodes.split(' ');
77 | var leafValues = item
78 | .weakClassifiers['_'][i]
79 | .leafValues.split(' ');
80 | var node = {
81 | left_val: '',
82 | right_val: '',
83 | threshold: ''
84 | };
85 |
86 | g++;
87 |
88 | node.left_val = parseFloat(leafValues[0]);
89 | node.right_val = parseFloat(leafValues[1]);
90 | node.f = +internalNodes[2];
91 | node.threshold = parseFloat(internalNodes[3]);
92 |
93 | stage.nodes.push(node);
94 | }
95 |
96 | haarStruct.nstages++;
97 | haarStruct.stages.push(stage);
98 | } else {
99 | // dealing with the old type
100 | var trees = item.trees._;
101 | var stage = {
102 | stageThreshold: parseFloat(item.stage_threshold),
103 | nodes: []
104 | };
105 |
106 | stage.nnodes = trees.length;
107 |
108 | for (var i in trees) {
109 | var tree = trees[i]._;
110 | var node = {
111 | "left_val": parseFloat(tree[0].left_val),
112 | "right_val": parseFloat(tree[0].right_val),
113 | "threshold": parseFloat(tree[0].threshold),
114 | "f": f++
115 | };
116 |
117 | g++;
118 | stage.nodes.push(node);
119 |
120 | haarStruct.rects.push({
121 | data: tree[0].feature.rects._,
122 | tilted: +tree[0].feature.tilted
123 | });
124 | }
125 |
126 | haarStruct.nstages++;
127 | haarStruct.stages.push(stage);
128 | }
129 | });
130 |
131 | xml.on('endElement: features > _', function(item) {
132 | haarStruct.rects.push({
133 | data: item.rects['_'],
134 | tilted: item.tilted ? 1 : 0
135 | });
136 |
137 | f++;
138 | });
139 |
140 | xml.on('error', function (err) {
141 | cb(err);
142 | });
143 |
144 | xml.on('end', function () {
145 | if (g !== f)
146 | return cb(new Error('Number of rects does not mach number of Nodes'));
147 | cb(null, haarStruct);
148 | });
149 | };
150 |
151 | /**
152 | * Converts from the internal structure to
153 | * tracking.js-ready opencv representation of
154 | * haarcascade classifiers
155 | * @param {Object} orig the internal rep of the
156 | * xml passed to convert
157 | * @return {[type]} the tracking.js-ready
158 | * rep
159 | */
160 | ConverterTJS.prototype.toTJS = function (orig) {
161 | var results = [];
162 | var f = 0;
163 |
164 | // width and height
165 | results.push(orig.cascadeSize.width);
166 | results.push(orig.cascadeSize.height);
167 |
168 | // iterate through stages
169 | for (var i = 0; i < orig.nstages;) {
170 | // stageThreshold, nodeLength
171 | var stage = orig.stages[i++];
172 |
173 | results.push(stage.stageThreshold);
174 | results.push(stage.nodes.length);
175 |
176 | // iterate through nodes
177 | for (var j = 0; j < stage.nnodes;) {
178 | // tilted, rectsLength
179 | var node = stage.nodes[j++];
180 | var rect = orig.rects[f++];
181 |
182 | results.push(rect.tilted);
183 | results.push(rect.data.length);
184 |
185 | // iterate through rects
186 | for (var k = 0, N = rect.data.length; k < N;) {
187 | // rectLeft, rectTop, rectWidth, rectHeight, rectWeight
188 | var R = rect.data[k++].split(' ');
189 | for (var l = 0, M = R.length; l < M; l++)
190 | results.push(+R[l]);
191 | }
192 |
193 | results.push(node.threshold);
194 | results.push(node.left_val);
195 | results.push(node.right_val);
196 | }
197 | }
198 |
199 | return results;
200 | };
201 |
202 | module.exports = ConverterTJS;
203 |
--------------------------------------------------------------------------------