1 | /**
|
2 | * @license
|
3 | * Copyright 2018 Google LLC. All Rights Reserved.
|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | * you may not use this file except in compliance with the License.
|
6 | * You may obtain a copy of the License at
|
7 | *
|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
9 | *
|
10 | * Unless required by applicable law or agreed to in writing, software
|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 | * See the License for the specific language governing permissions and
|
14 | * limitations under the License.
|
15 | * =============================================================================
|
16 | */
|
17 | // tslint:disable-next-line: no-imports-from-dist
|
18 | import * as tfOps from '@tensorflow/tfjs-core/dist/ops/ops_for_converter';
|
19 | import { getParamValue } from './utils';
|
20 | function nmsParams(node, tensorMap, context) {
|
21 | const boxes = getParamValue('boxes', node, tensorMap, context);
|
22 | const scores = getParamValue('scores', node, tensorMap, context);
|
23 | const maxOutputSize = getParamValue('maxOutputSize', node, tensorMap, context);
|
24 | const iouThreshold = getParamValue('iouThreshold', node, tensorMap, context);
|
25 | const scoreThreshold = getParamValue('scoreThreshold', node, tensorMap, context);
|
26 | const softNmsSigma = getParamValue('softNmsSigma', node, tensorMap, context);
|
27 | return {
|
28 | boxes,
|
29 | scores,
|
30 | maxOutputSize,
|
31 | iouThreshold,
|
32 | scoreThreshold,
|
33 | softNmsSigma
|
34 | };
|
35 | }
|
36 | export const executeOp = async (node, tensorMap, context, resourceManager, ops = tfOps) => {
|
37 | switch (node.op) {
|
38 | case 'NonMaxSuppressionV5': {
|
39 | const { boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma } = nmsParams(node, tensorMap, context);
|
40 | const result = await ops.image.nonMaxSuppressionWithScoreAsync(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma);
|
41 | return [result.selectedIndices, result.selectedScores];
|
42 | }
|
43 | case 'NonMaxSuppressionV4': {
|
44 | const { boxes, scores, maxOutputSize, iouThreshold, scoreThreshold } = nmsParams(node, tensorMap, context);
|
45 | const padToMaxOutputSize = getParamValue('padToMaxOutputSize', node, tensorMap, context);
|
46 | const result = await ops.image.nonMaxSuppressionPaddedAsync(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, padToMaxOutputSize);
|
47 | return [result.selectedIndices, result.validOutputs];
|
48 | }
|
49 | case 'NonMaxSuppressionV3':
|
50 | case 'NonMaxSuppressionV2': {
|
51 | const { boxes, scores, maxOutputSize, iouThreshold, scoreThreshold } = nmsParams(node, tensorMap, context);
|
52 | return [await ops.image.nonMaxSuppressionAsync(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold)];
|
53 | }
|
54 | case 'Where': {
|
55 | const condition = ops.cast(getParamValue('condition', node, tensorMap, context), 'bool');
|
56 | const result = [await ops.whereAsync(condition)];
|
57 | condition.dispose();
|
58 | return result;
|
59 | }
|
60 | case 'ListDiff': {
|
61 | return ops.setdiff1dAsync(getParamValue('x', node, tensorMap, context), getParamValue('y', node, tensorMap, context));
|
62 | }
|
63 | default:
|
64 | throw TypeError(`Node type ${node.op} is not implemented`);
|
65 | }
|
66 | };
|
67 | export const CATEGORY = 'dynamic';
|
68 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pY19leGVjdXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3RmanMtY29udmVydGVyL3NyYy9vcGVyYXRpb25zL2V4ZWN1dG9ycy9keW5hbWljX2V4ZWN1dG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUdILGlEQUFpRDtBQUNqRCxPQUFPLEtBQUssS0FBSyxNQUFNLGtEQUFrRCxDQUFDO0FBTzFFLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFFdEMsU0FBUyxTQUFTLENBQ2QsSUFBVSxFQUFFLFNBQTBCLEVBQUUsT0FBeUI7SUFDbkUsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBVyxDQUFDO0lBQ3pFLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQVcsQ0FBQztJQUMzRSxNQUFNLGFBQWEsR0FDZixhQUFhLENBQUMsZUFBZSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFXLENBQUM7SUFDdkUsTUFBTSxZQUFZLEdBQ2QsYUFBYSxDQUFDLGNBQWMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBVyxDQUFDO0lBQ3RFLE1BQU0sY0FBYyxHQUNoQixhQUFhLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQVcsQ0FBQztJQUN4RSxNQUFNLFlBQVksR0FDZCxhQUFhLENBQUMsY0FBYyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFXLENBQUM7SUFFdEUsT0FBTztRQUNMLEtBQUs7UUFDTCxNQUFNO1FBQ04sYUFBYTtRQUNiLFlBQVk7UUFDWixjQUFjO1FBQ2QsWUFBWTtLQUNiLENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxD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eXJpZ2h0IDIwMTggR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQge1RlbnNvciwgVGVuc29yMUQsIFRlbnNvcjJEfSBmcm9tICdAdGVuc29yZmxvdy90ZmpzLWNvcmUnO1xuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1pbXBvcnRzLWZyb20tZGlzdFxuaW1wb3J0ICogYXMgdGZPcHMgZnJvbSAnQHRlbnNvcmZsb3cvdGZqcy1jb3JlL2Rpc3Qvb3BzL29wc19mb3JfY29udmVydGVyJztcblxuaW1wb3J0IHtOYW1lZFRlbnNvcnNNYXB9IGZyb20gJy4uLy4uL2RhdGEvdHlwZXMnO1xuaW1wb3J0IHtFeGVjdXRpb25Db250ZXh0fSBmcm9tICcuLi8uLi9leGVjdXRvci9leGVjdXRpb25fY29udGV4dCc7XG5pbXBvcnQgeyBSZXNvdXJjZU1hbmFnZXIgfSBmcm9tICcuLi8uLi9leGVjdXRvci9yZXNvdXJjZV9tYW5hZ2VyJztcbmltcG9ydCB7SW50ZXJuYWxPcEFzeW5jRXhlY3V0b3IsIE5vZGV9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtnZXRQYXJhbVZhbHVlfSBmcm9tICcuL3V0aWxzJztcblxuZnVuY3Rpb24gbm1zUGFyYW1zKFxuICAgIG5vZGU6IE5vZGUsIHRlbnNvck1hcDogTmFtZWRUZW5zb3JzTWFwLCBjb250ZXh0OiBFeGVjdXRpb25Db250ZXh0KSB7XG4gIGNvbnN0IGJveGVzID0gZ2V0UGFyYW1WYWx1ZSgnYm94ZXMnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcjtcbiAgY29uc3Qgc2NvcmVzID0gZ2V0UGFyYW1WYWx1ZSgnc2NvcmVzJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBUZW5zb3I7XG4gIGNvbnN0IG1heE91dHB1dFNpemUgPVxuICAgICAgZ2V0UGFyYW1WYWx1ZSgnbWF4T3V0cHV0U2l6ZScsIG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCkgYXMgbnVtYmVyO1xuICBjb25zdCBpb3VUaHJlc2hvbGQgPVxuICAgICAgZ2V0UGFyYW1WYWx1ZSgnaW91VGhyZXNob2xkJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBudW1iZXI7XG4gIGNvbnN0IHNjb3JlVGhyZXNob2xkID1cbiAgICAgIGdldFBhcmFtVmFsdWUoJ3Njb3JlVGhyZXNob2xkJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBudW1iZXI7XG4gIGNvbnN0IHNvZnRObXNTaWdtYSA9XG4gICAgICBnZXRQYXJhbVZhbHVlKCdzb2Z0Tm1zU2lnbWEnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIG51bWJlcjtcblxuICByZXR1cm4ge1xuICAgIGJveGVzLFxuICAgIHNjb3JlcyxcbiAgICBtYXhPdXRwdXRTaXplLFxuICAgIGlvdVRocmVzaG9sZCxcbiAgICBzY29yZVRocmVzaG9sZCxcbiAgICBzb2Z0Tm1zU2lnbWFcbiAgfTtcbn1cblxuZXhwb3J0IGNvbnN0IGV4ZWN1dGVPcDogSW50ZXJuYWxPcEFzeW5jRXhlY3V0b3IgPSBhc3luYyhcbiAgICBub2RlOiBOb2RlLCB0ZW5zb3JNYXA6IE5hbWVkVGVuc29yc01hcCxcbiAgICBjb250ZXh0OiBFeGVjdXRpb25Db250ZXh0LCByZXNvdXJjZU1hbmFnZXI6IFJlc291cmNlTWFuYWdlcixcbiAgICBvcHMgPSB0Zk9wcyk6IFByb21pc2U8VGVuc29yW10+ID0+IHtcbiAgc3dpdGNoIChub2RlLm9wKSB7XG4gICAgY2FzZSAnTm9uTWF4U3VwcHJlc3Npb25WNSc6IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYm94ZXMsXG4gICAgICAgIHNjb3JlcyxcbiAgICAgICAgbWF4T3V0cHV0U2l6ZSxcbiAgICAgICAgaW91VGhyZXNob2xkLFxuICAgICAgICBzY29yZVRocmVzaG9sZCxcbiAgICAgICAgc29mdE5tc1NpZ21hXG4gICAgICB9ID0gbm1zUGFyYW1zKG5vZGUsIHRlbnNvck1hcCwgY29udGV4dCk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9wcy5pbWFnZS5ub25NYXhTdXBwcmVzc2lvbldpdGhTY29yZUFzeW5jKFxuICAgICAgICAgIGJveGVzIGFzIFRlbnNvcjJELCBzY29yZXMgYXMgVGVuc29yMUQsIG1heE91dHB1dFNpemUsIGlvdVRocmVzaG9sZCxcbiAgICAgICAgICBzY29yZVRocmVzaG9sZCwgc29mdE5tc1NpZ21hKTtcblxuICAgICAgcmV0dXJuIFtyZXN1bHQuc2VsZWN0ZWRJbmRpY2VzLCByZXN1bHQuc2VsZWN0ZWRTY29yZXNdO1xuICAgIH1cbiAgICBjYXNlICdOb25NYXhTdXBwcmVzc2lvblY0Jzoge1xuICAgICAgY29uc3Qge2JveGVzLCBzY29yZXMsIG1heE91dHB1dFNpemUsIGlvdVRocmVzaG9sZCwgc2NvcmVUaHJlc2hvbGR9ID1cbiAgICAgICAgICBubXNQYXJhbXMobm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KTtcblxuICAgICAgY29uc3QgcGFkVG9NYXhPdXRwdXRTaXplID1cbiAgICAgICAgICBnZXRQYXJhbVZhbHVlKCdwYWRUb01heE91dHB1dFNpemUnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzXG4gICAgICAgICAgYm9vbGVhbjtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb3BzLmltYWdlLm5vbk1heFN1cHByZXNzaW9uUGFkZGVkQXN5bmMoXG4gICAgICAgICAgYm94ZXMgYXMgVGVuc29yMkQsIHNjb3JlcyBhcyBUZW5zb3IxRCwgbWF4T3V0cHV0U2l6ZSwgaW91VGhyZXNob2xkLFxuICAgICAgICAgIHNjb3JlVGhyZXNob2xkLCBwYWRUb01heE91dHB1dFNpemUpO1xuXG4gICAgICByZXR1cm4gW3Jlc3VsdC5zZWxlY3RlZEluZGljZXMsIHJlc3VsdC52YWxpZE91dHB1dHNdO1xuICAgIH1cbiAgICBjYXNlICdOb25NYXhTdXBwcmVzc2lvblYzJzpcbiAgICBjYXNlICdOb25NYXhTdXBwcmVzc2lvblYyJzoge1xuICAgICAgY29uc3Qge2JveGVzLCBzY29yZXMsIG1heE91dHB1dFNpemUsIGlvdVRocmVzaG9sZCwgc2NvcmVUaHJlc2hvbGR9ID1cbiAgICAgICAgICBubXNQYXJhbXMobm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFthd2FpdCBvcHMuaW1hZ2Uubm9uTWF4U3VwcHJlc3Npb25Bc3luYyhcbiAgICAgICAgICBib3hlcyBhcyBUZW5zb3IyRCwgc2NvcmVzIGFzIFRlbnNvcjFELCBtYXhPdXRwdXRTaXplLCBpb3VUaHJlc2hvbGQsXG4gICAgICAgICAgc2NvcmVUaHJlc2hvbGQpXTtcbiAgICB9XG4gICAgY2FzZSAnV2hlcmUnOiB7XG4gICAgICBjb25zdCBjb25kaXRpb24gPSBvcHMuY2FzdChcbiAgICAgICAgICAoZ2V0UGFyYW1WYWx1ZSgnY29uZGl0aW9uJywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBUZW5zb3IpLFxuICAgICAgICAgICdib29sJyk7XG4gICAgICBjb25zdCByZXN1bHQgPSBbYXdhaXQgb3BzLndoZXJlQXN5bmMoY29uZGl0aW9uKV07XG4gICAgICBjb25kaXRpb24uZGlzcG9zZSgpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgY2FzZSAnTGlzdERpZmYnOiB7XG4gICAgICByZXR1cm4gb3BzLnNldGRpZmYxZEFzeW5jKFxuICAgICAgICAgIGdldFBhcmFtVmFsdWUoJ3gnLCBub2RlLCB0ZW5zb3JNYXAsIGNvbnRleHQpIGFzIFRlbnNvcixcbiAgICAgICAgICBnZXRQYXJhbVZhbHVlKCd5Jywgbm9kZSwgdGVuc29yTWFwLCBjb250ZXh0KSBhcyBUZW5zb3IpO1xuICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgVHlwZUVycm9yKGBOb2RlIHR5cGUgJHtub2RlLm9wfSBpcyBub3QgaW1wbGVtZW50ZWRgKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IENBVEVHT1JZID0gJ2R5bmFtaWMnO1xuIl19 |
\ | No newline at end of file |