@jaak.ai/stamps 2.0.0-dev.47 → 2.0.0-dev.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -730,7 +730,7 @@ class DetectionService {
730
730
  modelLoaded = false;
731
731
  deviceStrategy;
732
732
  MODEL_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/ddmyp-v2.onnx";
733
- MOBILENET_MODEL_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/cdmmp-v1.onnx";
733
+ MOBILENET_MODEL_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/squeezenet.onnx";
734
734
  MOBILENET_CLASSES_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/cdmmp-v1.json";
735
735
  INPUT_SIZE = 320;
736
736
  CONFIDENCE_THRESHOLD = 0.6;
@@ -792,15 +792,27 @@ class DetectionService {
792
792
  }
793
793
  try {
794
794
  this.logger.state('CARGANDO_MODELO_MOBILENET', { path: this.MOBILENET_MODEL_PATH });
795
- // Load class map
796
- const classResponse = await fetch(this.MOBILENET_CLASSES_PATH);
797
- if (!classResponse.ok) {
798
- throw new Error(`Failed to load class map: ${this.MOBILENET_CLASSES_PATH}`);
795
+ // Try to load class map (optional - SqueezeNet may not need it for basic classification)
796
+ try {
797
+ const classResponse = await fetch(this.MOBILENET_CLASSES_PATH);
798
+ if (classResponse.ok) {
799
+ this.mobileNetClassMap = await classResponse.json();
800
+ this.logger.state('CLASES_MOBILENET_CARGADAS', {
801
+ classCount: Object.keys(this.mobileNetClassMap).length
802
+ });
803
+ }
804
+ }
805
+ catch (error) {
806
+ this.logger.warn('No se pudo cargar el mapa de clases de MobileNet, usando clasificación básica');
807
+ // Create a basic class map for document types
808
+ this.mobileNetClassMap = {
809
+ "0": "document",
810
+ "1": "id_card",
811
+ "2": "passport",
812
+ "3": "license",
813
+ "4": "other"
814
+ };
799
815
  }
800
- this.mobileNetClassMap = await classResponse.json();
801
- this.logger.state('CLASES_MOBILENET_CARGADAS', {
802
- classCount: Object.keys(this.mobileNetClassMap).length
803
- });
804
816
  // Load model
805
817
  const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);
806
818
  try {
@@ -889,7 +901,7 @@ class DetectionService {
889
901
  try {
890
902
  this.logger.state('CLASIFICANDO_DOCUMENTO', { timestamp: Date.now() });
891
903
  const inputTensor = this.preprocessMobileNet(canvas);
892
- const feeds = { input: inputTensor };
904
+ const feeds = { [this.mobileNetSession.inputNames[0]]: inputTensor };
893
905
  const results = await this.mobileNetSession.run(feeds);
894
906
  const output = results[Object.keys(results)[0]].data;
895
907
  const maxIdx = output.reduce((bestIdx, val, idx, arr) => val > arr[bestIdx] ? idx : bestIdx, 0);
@@ -899,7 +911,8 @@ class DetectionService {
899
911
  class: className,
900
912
  confidence: confidence.toFixed(3),
901
913
  classIndex: maxIdx,
902
- timestamp: Date.now()
914
+ timestamp: Date.now(),
915
+ results
903
916
  });
904
917
  return {
905
918
  class: className,
@@ -938,7 +951,7 @@ class DetectionService {
938
951
  displayedVideoHeight = INPUT_SIZE / videoAspectRatio;
939
952
  }
940
953
  else {
941
- // Video is taller - pillarboxed in display
954
+ // Video is taller - pillarboxed in display
942
955
  displayedVideoHeight = INPUT_SIZE;
943
956
  displayedVideoWidth = INPUT_SIZE * videoAspectRatio;
944
957
  }
@@ -989,7 +1002,7 @@ class DetectionService {
989
1002
  const leftAligned = Math.abs(docLeft - maskLeft) <= tolerance;
990
1003
  return {
991
1004
  top: topAligned && leftAligned, // Esquina superior izquierda: borde top Y left alineados
992
- right: topAligned && rightAligned, // Esquina superior derecha: borde top Y right alineados
1005
+ right: topAligned && rightAligned, // Esquina superior derecha: borde top Y right alineados
993
1006
  bottom: bottomAligned && leftAligned, // Esquina inferior izquierda: borde bottom Y left alineados
994
1007
  left: bottomAligned && rightAligned // Esquina inferior derecha: borde bottom Y right alineados
995
1008
  };
@@ -1074,15 +1087,20 @@ class DetectionService {
1074
1087
  tempCanvas.width = 224;
1075
1088
  tempCanvas.height = 224;
1076
1089
  const tempCtx = tempCanvas.getContext('2d');
1090
+ // Resize image to 224x224 for SqueezeNet (using MobileNet interface)
1077
1091
  tempCtx.drawImage(canvas, 0, 0, 224, 224);
1078
1092
  const imageData = tempCtx.getImageData(0, 0, 224, 224);
1079
1093
  const data = imageData.data;
1080
1094
  const hw = 224 * 224;
1081
1095
  const arr = new Float32Array(3 * hw);
1096
+ // SqueezeNet preprocessing: normalize to [0,1] range and arrange in CHW format
1082
1097
  for (let i = 0; i < hw; i++) {
1083
- arr[i] = (data[i * 4 + 0] / 255 - 0.5) / 0.5;
1084
- arr[hw + i] = (data[i * 4 + 1] / 255 - 0.5) / 0.5;
1085
- arr[2 * hw + i] = (data[i * 4 + 2] / 255 - 0.5) / 0.5;
1098
+ // Red channel
1099
+ arr[i] = data[i * 4 + 0] / 255.0;
1100
+ // Green channel
1101
+ arr[hw + i] = data[i * 4 + 1] / 255.0;
1102
+ // Blue channel
1103
+ arr[2 * hw + i] = data[i * 4 + 2] / 255.0;
1086
1104
  }
1087
1105
  return new window.ort.Tensor('float32', arr, [1, 3, 224, 224]);
1088
1106
  }