QR code color, eval wait for input option, optional tfjs AI models url

This commit is contained in:
Michal Kolář
2024-04-10 13:47:41 +02:00
committed by Stanislav Fifik
parent 315d1acc9b
commit a3b2b84b69
5 changed files with 55 additions and 9 deletions

View File

@@ -1,7 +1,8 @@
import { import {
BooleanVar, BooleanVar,
ImageVar, ImageVar,
NumberVar NumberVar,
StringVar,
} from '../io/AbstractIOSet'; } from '../io/AbstractIOSet';
import Node from "../Node"; import Node from "../Node";
import '@tensorflow/tfjs-backend-webgl'; import '@tensorflow/tfjs-backend-webgl';
@@ -66,6 +67,9 @@ const inputs = {
min: 0, min: 0,
max: 1, max: 1,
} as NumberVar, } as NumberVar,
modelUrl: {
type: 'String',
} as StringVar,
...(flow([ ...(flow([
bodyParts => keyBy(bodyParts, (bodyPart) => bodyPart), bodyParts => keyBy(bodyParts, (bodyPart) => bodyPart),
bodyParts => mapValues(bodyParts, () => ({ bodyParts => mapValues(bodyParts, () => ({
@@ -106,6 +110,7 @@ export default class BodyPartSegmentation extends Node<typeof inputs, typeof out
runtime: 'tfjs', runtime: 'tfjs',
modelType: 'general', modelType: 'general',
segmentBodyParts: true, segmentBodyParts: true,
modelUrl: this.in.modelUrl.value ? this.in.modelUrl.value : undefined,
} as BodyPixSegmentationConfig; } as BodyPixSegmentationConfig;
this.segmenter = await createSegmenter(model, segmenterConfig); this.segmenter = await createSegmenter(model, segmenterConfig);
} }

View File

@@ -1,6 +1,7 @@
import { import {
ImageVar, ImageVar,
NumberVar NumberVar,
StringVar,
} from '../io/AbstractIOSet'; } from '../io/AbstractIOSet';
import Node from "../Node"; import Node from "../Node";
import '@tensorflow/tfjs-backend-webgl'; import '@tensorflow/tfjs-backend-webgl';
@@ -35,6 +36,9 @@ const inputs = {
min: 0, min: 0,
max: 1, max: 1,
} as NumberVar, } as NumberVar,
modelUrl: {
type: 'String',
} as StringVar,
} }
const outputs = { const outputs = {
@@ -66,7 +70,8 @@ export default class BodySegmentation extends Node<typeof inputs, typeof outputs
const model = SupportedModels.MediaPipeSelfieSegmentation; const model = SupportedModels.MediaPipeSelfieSegmentation;
const segmenterConfig = { const segmenterConfig = {
runtime: 'tfjs', runtime: 'tfjs',
modelType: 'general' modelType: 'general',
modelUrl: this.in.modelUrl.value ? this.in.modelUrl.value : undefined,
} as MediaPipeSelfieSegmentationMediaPipeModelConfig; } as MediaPipeSelfieSegmentationMediaPipeModelConfig;
this.segmenter = await createSegmenter(model, segmenterConfig); this.segmenter = await createSegmenter(model, segmenterConfig);
} }

View File

@@ -1,13 +1,15 @@
import { import {
ImageVar, ImageVar,
NumberVar, VariableValueType NumberVar,
StringVar,
VariableValueType,
} from '../io/AbstractIOSet'; } from '../io/AbstractIOSet';
import Node from "../Node"; import Node from "../Node";
import '@tensorflow/tfjs-backend-webgl'; import '@tensorflow/tfjs-backend-webgl';
import {Face, import {Face,
FaceDetector, FaceDetector,
FaceDetectorInput, FaceDetectorInput,
MediaPipeFaceDetectorModelConfig, MediaPipeFaceDetectorMediaPipeModelConfig,
SupportedModels, SupportedModels,
createDetector, createDetector,
} from '@tensorflow-models/face-detection'; } from '@tensorflow-models/face-detection';
@@ -22,6 +24,9 @@ const inputs = {
image: { image: {
type: 'Image' type: 'Image'
} as ImageVar, } as ImageVar,
modelUrl: {
type: 'String',
} as StringVar,
} }
const outputs = { const outputs = {
@@ -97,7 +102,8 @@ export default class FaceFeaturePosition extends Node<typeof inputs, typeof outp
maxFaces: 1, maxFaces: 1,
modelType: 'short', modelType: 'short',
runtime: 'tfjs', runtime: 'tfjs',
} as MediaPipeFaceDetectorModelConfig; detectorModelUrl: this.in.modelUrl.value ? this.in.modelUrl.value : undefined,
} as MediaPipeFaceDetectorMediaPipeModelConfig;
this.detector = await createDetector(model, detectorConfig); this.detector = await createDetector(model, detectorConfig);
} }

View File

@@ -1,11 +1,16 @@
import Node from './Node'; import Node from './Node';
import { import {
ImageVar,
NumberVar, NumberVar,
StringVar, StringVar,
BooleanVar,
} from './io/AbstractIOSet'; } from './io/AbstractIOSet';
import get from 'lodash/get'; import get from 'lodash/get';
const inputs = { const inputs = {
image: {
type: 'Image'
} as ImageVar,
i0: { i0: {
type: 'Number', type: 'Number',
default: 0, default: 0,
@@ -41,16 +46,23 @@ const inputs = {
formula: { formula: {
type: 'String', type: 'String',
default: '', default: '',
} as StringVar } as StringVar,
waitForInput: {
type: 'Boolean',
default: true,
} as BooleanVar
}; };
const outputs = { const outputs = {
image: {
type: 'Image'
} as ImageVar,
result: { result: {
type: 'Number' type: 'Number'
} as NumberVar, } as NumberVar,
} }
export default class NumberBinaryOperation extends Node<typeof inputs, typeof outputs> { export default class Eval extends Node<typeof inputs, typeof outputs> {
constructor() { constructor() {
super('Eval', inputs, outputs); super('Eval', inputs, outputs);
} }
@@ -61,12 +73,20 @@ export default class NumberBinaryOperation extends Node<typeof inputs, typeof ou
) )
} }
hasAllConnectedInputsValue() {
if (this.in.waitForInput.value) {
return super.hasAllConnectedInputsValue();
}
return true;
}
evaluate() { evaluate() {
try { try {
this.out.result.value = eval(this.interpolate()); this.out.result.value = eval(this.interpolate());
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
this.out.image.value = this.in.image.value;
} }
async _update() { async _update() {

View File

@@ -2,6 +2,7 @@ import {
ImageVar, ImageVar,
NumberVar, NumberVar,
StringVar, StringVar,
ColorVar,
} from './io/AbstractIOSet'; } from './io/AbstractIOSet';
import Node from './Node'; import Node from './Node';
import {canvasPool2D} from '../canvas/CanvasPool'; import {canvasPool2D} from '../canvas/CanvasPool';
@@ -30,6 +31,10 @@ const inputs = {
type: 'Number', type: 'Number',
min: 0, min: 0,
} as NumberVar, } as NumberVar,
color: {
type: 'Color',
default: '#000000',
} as ColorVar,
} }
const outputs = { const outputs = {
@@ -59,7 +64,12 @@ export default class QRCodeGenerator extends Node<typeof inputs, typeof outputs>
const encodeHintTypeMap = new Map<EncodeHintType, any>(); const encodeHintTypeMap = new Map<EncodeHintType, any>();
encodeHintTypeMap.set(EncodeHintType.MARGIN, this.in.margin.value); encodeHintTypeMap.set(EncodeHintType.MARGIN, this.in.margin.value);
encodeHintTypeMap.set(EncodeHintType.ERROR_CORRECTION, QRCodeDecoderErrorCorrectionLevel[this.in.correction.value]); encodeHintTypeMap.set(EncodeHintType.ERROR_CORRECTION, QRCodeDecoderErrorCorrectionLevel[this.in.correction.value]);
const svgElement = this.writer.write(this.in.text.value, this.in.size.value, this.in.size.value, encodeHintTypeMap); const svgElement: SVGSVGElement = this.writer.write(this.in.text.value, this.in.size.value, this.in.size.value, encodeHintTypeMap);
for(const element of svgElement.querySelectorAll('[fill]')) {
element.setAttribute('fill', this.in.color.value);
}
const canvas = canvasPool2D.createCanvas(); const canvas = canvasPool2D.createCanvas();
canvas.width = this.in.size.value; canvas.width = this.in.size.value;
canvas.height = this.in.size.value; canvas.height = this.in.size.value;