@jaak.ai/stamps 2.0.0-dev.52 → 2.0.0-dev.54
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.
- package/dist/cjs/jaak-stamps.cjs.entry.js +159 -22
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
- package/dist/collection/services/CameraService.js +158 -21
- package/dist/collection/services/CameraService.js.map +1 -1
- package/dist/collection/services/DetectionService.js +1 -1
- package/dist/collection/services/DetectionService.js.map +1 -1
- package/dist/components/jaak-stamps.js +159 -22
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps.entry.js +159 -22
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/p-9ed19fa4.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-9ed19fa4.entry.js.map +1 -0
- package/dist/types/services/CameraService.d.ts +1 -0
- package/package.json +1 -1
- package/dist/jaak-stamps-webcomponent/p-ffb29fbd.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-ffb29fbd.entry.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DetectionService.js","sourceRoot":"","sources":["../../src/services/DetectionService.ts"],"names":[],"mappings":"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","sourcesContent":["import { IDetectionService, DetectionBox, SideAlignment, ClassificationResult } from './interfaces/IDetectionService';\nimport { ILogger } from './interfaces/ILogger';\nimport { IDeviceStrategy } from './strategies/IDeviceStrategy';\nimport { DeviceStrategyFactory } from './factories/DeviceStrategyFactory';\n\nexport class DetectionService implements IDetectionService {\n private session?: any;\n private mobileNetSession?: any;\n private mobileNetClassMap?: any;\n private modelLoaded: boolean = false;\n private deviceStrategy: IDeviceStrategy;\n\n private readonly MODEL_PATH = \"https://storage.googleapis.com/jaak-static/web/component/stamps/ddmyp-v2.onnx\";\n private readonly MOBILENET_MODEL_PATH = \"https://storage.googleapis.com/jaak-static/web/component/stamps/squeeze_quant.onnx\";\n private readonly MOBILENET_CLASSES_PATH = \"https://storage.googleapis.com/jaak-static/web/component/stamps/cdmmp-v1.json\";\n private readonly INPUT_SIZE = 320;\n private readonly CONFIDENCE_THRESHOLD = 0.6;\n\n // Canvas pool for optimization\n private preprocessCanvas?: HTMLCanvasElement;\n private preprocessCtx?: CanvasRenderingContext2D;\n private captureCanvas?: HTMLCanvasElement;\n\n constructor(\n private logger: ILogger,\n private debug: boolean = false,\n private useDocumentClassification: boolean = false\n ) {\n this.deviceStrategy = DeviceStrategyFactory.createStrategy();\n this.initializeCanvasPool();\n }\n\n async loadModel(): Promise<void> {\n if (this.modelLoaded || this.session) {\n this.logger.state('MODELO_YA_PRECARGADO', {\n sessionExists: !!this.session,\n modelPreloaded: this.modelLoaded\n });\n return;\n }\n\n try {\n this.logger.state('PRECARGANDO_MODELO_DETECCION', { modelPath: this.MODEL_PATH });\n\n const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);\n\n try {\n this.session = await (window as any).ort.InferenceSession.create(this.MODEL_PATH, sessionOptions);\n } catch (error) {\n if (error.message.includes('failed to allocate a buffer')) {\n this.logger.warn('Fallo en asignación de buffer durante precarga, intentando con configuración mínima');\n const fallbackOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'disabled',\n logSeverityLevel: 4,\n enableCpuMemArena: false,\n enableMemPattern: false,\n executionMode: 'sequential',\n interOpNumThreads: 1,\n intraOpNumThreads: 1,\n };\n this.session = await (window as any).ort.InferenceSession.create(this.MODEL_PATH, fallbackOptions);\n } else {\n throw error;\n }\n }\n\n this.modelLoaded = true;\n this.logger.state('MODELO_DETECCION_CARGADO_EXITOSAMENTE', { sessionCreated: !!this.session });\n } catch (error) {\n this.logger.error('Error al precargar modelo de detección:', error);\n throw error;\n }\n }\n\n async loadClassificationModel(): Promise<void> {\n if (!this.useDocumentClassification) {\n return;\n }\n\n try {\n this.logger.state('CARGANDO_MODELO_MOBILENET', { path: this.MOBILENET_MODEL_PATH });\n\n // Try to load class map (optional - SqueezeNet may not need it for basic classification)\n try {\n const classResponse = await fetch(this.MOBILENET_CLASSES_PATH);\n if (classResponse.ok) {\n this.mobileNetClassMap = await classResponse.json();\n this.logger.state('CLASES_MOBILENET_CARGADAS', {\n classCount: Object.keys(this.mobileNetClassMap).length\n });\n }\n } catch (error) {\n this.logger.warn('No se pudo cargar el mapa de clases de MobileNet, usando clasificación básica');\n // Create a basic class map for document types\n this.mobileNetClassMap = {\n \"0\": \"document\",\n \"1\": \"id_card\",\n \"2\": \"passport\",\n \"3\": \"license\",\n \"4\": \"other\"\n };\n }\n\n // Load model\n const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);\n try {\n this.mobileNetSession = await (window as any).ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, sessionOptions);\n } catch (error) {\n if (error.message.includes('failed to allocate a buffer')) {\n this.logger.warn('Fallo en asignación de buffer de MobileNet, intentando con configuración mínima');\n const fallbackOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'disabled',\n logSeverityLevel: 4,\n enableCpuMemArena: false,\n enableMemPattern: false,\n executionMode: 'sequential',\n interOpNumThreads: 1,\n intraOpNumThreads: 1,\n };\n this.mobileNetSession = await (window as any).ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, fallbackOptions);\n } else {\n throw error;\n }\n }\n this.logger.state('MODELO_MOBILENET_CARGADO_EXITOSAMENTE', {\n sessionCreated: !!this.mobileNetSession\n });\n\n } catch (error) {\n this.logger.error('Error al cargar modelo MobileNet:', error);\n throw error;\n }\n }\n\n isModelLoaded(): boolean {\n return this.modelLoaded && !!this.session;\n }\n\n preprocess(video: HTMLVideoElement): any {\n if (!this.preprocessCanvas || !this.preprocessCtx) {\n this.initializeCanvasPool();\n }\n\n this.preprocessCtx!.clearRect(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);\n this.preprocessCtx!.drawImage(video, 0, 0, this.INPUT_SIZE, this.INPUT_SIZE);\n\n const imageData = this.preprocessCtx!.getImageData(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);\n const [R, G, B] = [[], [], []] as number[][];\n const { data } = imageData;\n\n for (let i = 0; i < data.length; i += 4) {\n R.push(data[i] / 255);\n G.push(data[i + 1] / 255);\n B.push(data[i + 2] / 255);\n }\n\n const transposedData = new Float32Array(R.concat(G, B));\n const float16Data = new Uint16Array(transposedData.length);\n for (let i = 0; i < transposedData.length; i++) {\n float16Data[i] = this.float32ToFloat16(transposedData[i]);\n }\n return new (window as any).ort.Tensor(\"float16\", float16Data, [1, 3, this.INPUT_SIZE, this.INPUT_SIZE]);\n }\n\n async runInference(inputTensor: any): Promise<DetectionBox[]> {\n if (!this.session) {\n throw new Error('Detection model not loaded');\n }\n\n const feeds = { [this.session.inputNames[0]]: inputTensor };\n const results = await this.session.run(feeds);\n const output = results[this.session.outputNames[0]].data;\n\n const detections: DetectionBox[] = [];\n for (let i = 0; i < output.length; i += 6) {\n const [x1, y1, x2, y2, score, classId] = output.slice(i, i + 6);\n if (score > this.CONFIDENCE_THRESHOLD) {\n detections.push({\n x: x1,\n y: y1,\n w: x2 - x1,\n h: y2 - y1,\n score,\n classId\n });\n }\n }\n\n return detections;\n }\n\n async classifyDocument(canvas: HTMLCanvasElement): Promise<ClassificationResult | null> {\n if (!this.mobileNetSession || !this.mobileNetClassMap) {\n this.logger.warn('Modelo MobileNet no está cargado, saltando clasificación');\n return null;\n }\n\n try {\n this.logger.state('CLASIFICANDO_DOCUMENTO', { timestamp: Date.now() });\n\n const inputTensor = this.preprocessMobileNet(canvas);\n const feeds = { [this.mobileNetSession.inputNames[0]]: inputTensor };\n const results = await this.mobileNetSession.run(feeds);\n const output = results[Object.keys(results)[0]].data;\n\n const maxIdx = output.reduce((bestIdx: number, val: number, idx: number, arr: number[]) =>\n val > arr[bestIdx] ? idx : bestIdx, 0);\n const confidence = output[maxIdx];\n\n const className = this.mobileNetClassMap[maxIdx.toString()] || \"unknown\";\n\n this.logger.state('DOCUMENTO_CLASIFICADO', {\n class: className,\n confidence: confidence.toFixed(3),\n classIndex: maxIdx,\n timestamp: Date.now(),\n results\n });\n\n return {\n class: className,\n confidence: confidence,\n classIndex: maxIdx\n };\n\n } catch (error) {\n this.logger.error('Error al clasificar documento:', error);\n return null;\n }\n }\n\n checkSideAlignment(box: DetectionBox, maskConfig: any): SideAlignment {\n const { INPUT_SIZE, ID1_ASPECT_RATIO, shouldMirrorVideo, alignmentTolerance, maskSize, videoRef } = maskConfig;\n\n if (!videoRef) {\n return { top: false, right: false, bottom: false, left: false };\n }\n\n // Get video dimensions to calculate actual mask boundaries in model space\n const videoWidth = videoRef.videoWidth;\n const videoHeight = videoRef.videoHeight;\n\n if (videoWidth === 0 || videoHeight === 0) {\n return { top: false, right: false, bottom: false, left: false };\n }\n\n // Calculate video aspect ratio\n const videoAspectRatio = videoWidth / videoHeight;\n\n // The model sees video stretched to 320x320, but we need to calculate where\n // the mask should be in this distorted space to match the visual mask\n\n // In the visual display, we calculate mask size based on the limiting dimension\n // We need to replicate this logic but account for the distortion in model space\n\n // Calculate the \"display\" dimensions (what the visual mask calculations use)\n const containerAspectRatio = 1; // Assume square container for simplicity\n let displayedVideoWidth, displayedVideoHeight;\n\n if (videoAspectRatio > containerAspectRatio) {\n // Video is wider - letterboxed in display\n displayedVideoWidth = INPUT_SIZE;\n displayedVideoHeight = INPUT_SIZE / videoAspectRatio;\n } else {\n // Video is taller - pillarboxed in display\n displayedVideoHeight = INPUT_SIZE;\n displayedVideoWidth = INPUT_SIZE * videoAspectRatio;\n }\n\n // Calculate mask dimensions using the same logic as updateMaskDimensions\n const maxWidthByHeight = displayedVideoHeight * ID1_ASPECT_RATIO;\n\n let visualMaskWidth, visualMaskHeight;\n const sizeRatio = maskSize / 100;\n\n if (maxWidthByHeight <= displayedVideoWidth) {\n // Video height is the limiting factor\n visualMaskHeight = displayedVideoHeight * sizeRatio;\n visualMaskWidth = visualMaskHeight * ID1_ASPECT_RATIO;\n } else {\n // Video width is the limiting factor\n visualMaskWidth = displayedVideoWidth * sizeRatio;\n visualMaskHeight = visualMaskWidth / ID1_ASPECT_RATIO;\n }\n\n // Now map these visual mask dimensions to the distorted model space\n // The model stretches video to 320x320, so we need to apply the inverse transformation\n const modelMaskWidth = visualMaskWidth * (INPUT_SIZE / displayedVideoWidth);\n const modelMaskHeight = visualMaskHeight * (INPUT_SIZE / displayedVideoHeight);\n\n // Calculate mask boundaries in model coordinate system (always centered in 320x320)\n const maskCenterX = INPUT_SIZE / 2;\n const maskCenterY = INPUT_SIZE / 2;\n const maskLeft = maskCenterX - (modelMaskWidth / 2);\n const maskRight = maskCenterX + (modelMaskWidth / 2);\n const maskTop = maskCenterY - (modelMaskHeight / 2);\n const maskBottom = maskCenterY + (modelMaskHeight / 2);\n\n // Obtener las coordenadas del documento detectado\n let docLeft = box.x;\n let docRight = box.x + box.w;\n const docTop = box.y;\n const docBottom = box.y + box.h;\n\n // Si el video está en modo mirror, invertir las coordenadas horizontales\n if (shouldMirrorVideo) {\n const originalDocLeft = docLeft;\n const originalDocRight = docRight;\n docLeft = INPUT_SIZE - originalDocRight;\n docRight = INPUT_SIZE - originalDocLeft;\n }\n\n // Tolerancia para considerar que un lado está alineado (en píxeles)\n const tolerance = alignmentTolerance;\n\n // Verificar alineación de esquinas más estricta\n // Una esquina está alineada solo si AMBOS bordes que la forman están alineados\n const topAligned = Math.abs(docTop - maskTop) <= tolerance;\n const rightAligned = Math.abs(docRight - maskRight) <= tolerance;\n const bottomAligned = Math.abs(docBottom - maskBottom) <= tolerance;\n const leftAligned = Math.abs(docLeft - maskLeft) <= tolerance;\n\n return {\n top: topAligned && leftAligned, // Esquina superior izquierda: borde top Y left alineados\n right: topAligned && rightAligned, // Esquina superior derecha: borde top Y right alineados\n bottom: bottomAligned && leftAligned, // Esquina inferior izquierda: borde bottom Y left alineados\n left: bottomAligned && rightAligned // Esquina inferior derecha: borde bottom Y right alineados\n };\n }\n\n isCardInFrame(box: DetectionBox): boolean {\n const cardCenterX = box.x + box.w / 2;\n const cardCenterY = box.y + box.h / 2;\n const frameCenterX = this.INPUT_SIZE / 2;\n const frameCenterY = this.INPUT_SIZE / 2;\n const toleranceX = 40;\n const toleranceY = 30;\n\n const isCentered = Math.abs(cardCenterX - frameCenterX) < toleranceX &&\n Math.abs(cardCenterY - frameCenterY) < toleranceY;\n const isGoodSize = box.w > 150 && box.w < 300 && box.h > 90 && box.h < 200;\n\n return isCentered && isGoodSize;\n }\n\n areAllSidesAligned(alignment: SideAlignment): boolean {\n return alignment.top && alignment.right && alignment.bottom && alignment.left;\n }\n\n cleanup(): void {\n this.cleanupCanvasPool();\n\n if (this.session) {\n this.session.release?.();\n this.session = undefined;\n }\n if (this.mobileNetSession) {\n this.mobileNetSession.release?.();\n this.mobileNetSession = undefined;\n }\n this.mobileNetClassMap = undefined;\n this.modelLoaded = false;\n\n this.logger.state('DETECCION_SERVICE_LIMPIADO', { timestamp: Date.now() });\n }\n\n private initializeCanvasPool(): void {\n this.preprocessCanvas = document.createElement('canvas');\n this.preprocessCanvas.width = this.INPUT_SIZE;\n this.preprocessCanvas.height = this.INPUT_SIZE;\n this.preprocessCtx = this.preprocessCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true\n })!;\n\n this.captureCanvas = document.createElement('canvas');\n\n this.logger.state('CANVAS_POOL_INICIALIZADO', {\n preprocessCanvasSize: this.INPUT_SIZE\n });\n }\n\n private cleanupCanvasPool(): void {\n if (this.preprocessCanvas) {\n this.preprocessCtx = undefined;\n this.preprocessCanvas = undefined;\n }\n if (this.captureCanvas) {\n this.captureCanvas = undefined;\n }\n }\n\n private float32ToFloat16(value: number): number {\n const buffer = new ArrayBuffer(4);\n const view = new DataView(buffer);\n view.setFloat32(0, value, true);\n\n const f = view.getUint32(0, true);\n const sign = (f >> 31) & 0x1;\n const exp = (f >> 23) & 0xFF;\n const frac = f & 0x7FFFFF;\n\n let newExp = exp - 127 + 15;\n\n if (exp === 0) {\n newExp = 0;\n } else if (exp === 0xFF) {\n newExp = 0x1F;\n } else if (newExp >= 0x1F) {\n newExp = 0x1F;\n return (sign << 15) | (newExp << 10);\n } else if (newExp <= 0) {\n return (sign << 15);\n }\n\n return (sign << 15) | (newExp << 10) | (frac >> 13);\n }\n\n private preprocessMobileNet(canvas: HTMLCanvasElement): any {\n const tempCanvas = document.createElement('canvas');\n tempCanvas.width = 224;\n tempCanvas.height = 224;\n const tempCtx = tempCanvas.getContext('2d')!;\n\n // Resize image to 224x224 for SqueezeNet (using MobileNet interface)\n tempCtx.drawImage(canvas, 0, 0, 224, 224);\n\n const imageData = tempCtx.getImageData(0, 0, 224, 224);\n const data = imageData.data;\n const hw = 224 * 224;\n const arr = new Float32Array(3 * hw);\n\n // SqueezeNet preprocessing: normalize to [0,1] range and arrange in CHW format\n for (let i = 0; i < hw; i++) {\n // Red channel\n arr[i] = data[i * 4 + 0] / 255.0;\n // Green channel\n arr[hw + i] = data[i * 4 + 1] / 255.0;\n // Blue channel\n arr[2 * hw + i] = data[i * 4 + 2] / 255.0;\n }\n\n return new (window as any).ort.Tensor('float32', arr, [1, 3, 224, 224]);\n }\n\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DetectionService.js","sourceRoot":"","sources":["../../src/services/DetectionService.ts"],"names":[],"mappings":"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","sourcesContent":["import { IDetectionService, DetectionBox, SideAlignment, ClassificationResult } from './interfaces/IDetectionService';\nimport { ILogger } from './interfaces/ILogger';\nimport { IDeviceStrategy } from './strategies/IDeviceStrategy';\nimport { DeviceStrategyFactory } from './factories/DeviceStrategyFactory';\n\nexport class DetectionService implements IDetectionService {\n private session?: any;\n private mobileNetSession?: any;\n private mobileNetClassMap?: any;\n private modelLoaded: boolean = false;\n private deviceStrategy: IDeviceStrategy;\n\n private readonly MODEL_PATH = \"https://storage.googleapis.com/jaak-static/web/component/stamps/ddmyp-v2.onnx\";\n private readonly MOBILENET_MODEL_PATH = \"https://storage.googleapis.com/jaak-static/web/component/stamps/squeezenet_new_fp32.onnx\";\n private readonly MOBILENET_CLASSES_PATH = \"https://storage.googleapis.com/jaak-static/web/component/stamps/cdmmp-v1.json\";\n private readonly INPUT_SIZE = 320;\n private readonly CONFIDENCE_THRESHOLD = 0.6;\n\n // Canvas pool for optimization\n private preprocessCanvas?: HTMLCanvasElement;\n private preprocessCtx?: CanvasRenderingContext2D;\n private captureCanvas?: HTMLCanvasElement;\n\n constructor(\n private logger: ILogger,\n private debug: boolean = false,\n private useDocumentClassification: boolean = false\n ) {\n this.deviceStrategy = DeviceStrategyFactory.createStrategy();\n this.initializeCanvasPool();\n }\n\n async loadModel(): Promise<void> {\n if (this.modelLoaded || this.session) {\n this.logger.state('MODELO_YA_PRECARGADO', {\n sessionExists: !!this.session,\n modelPreloaded: this.modelLoaded\n });\n return;\n }\n\n try {\n this.logger.state('PRECARGANDO_MODELO_DETECCION', { modelPath: this.MODEL_PATH });\n\n const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);\n\n try {\n this.session = await (window as any).ort.InferenceSession.create(this.MODEL_PATH, sessionOptions);\n } catch (error) {\n if (error.message.includes('failed to allocate a buffer')) {\n this.logger.warn('Fallo en asignación de buffer durante precarga, intentando con configuración mínima');\n const fallbackOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'disabled',\n logSeverityLevel: 4,\n enableCpuMemArena: false,\n enableMemPattern: false,\n executionMode: 'sequential',\n interOpNumThreads: 1,\n intraOpNumThreads: 1,\n };\n this.session = await (window as any).ort.InferenceSession.create(this.MODEL_PATH, fallbackOptions);\n } else {\n throw error;\n }\n }\n\n this.modelLoaded = true;\n this.logger.state('MODELO_DETECCION_CARGADO_EXITOSAMENTE', { sessionCreated: !!this.session });\n } catch (error) {\n this.logger.error('Error al precargar modelo de detección:', error);\n throw error;\n }\n }\n\n async loadClassificationModel(): Promise<void> {\n if (!this.useDocumentClassification) {\n return;\n }\n\n try {\n this.logger.state('CARGANDO_MODELO_MOBILENET', { path: this.MOBILENET_MODEL_PATH });\n\n // Try to load class map (optional - SqueezeNet may not need it for basic classification)\n try {\n const classResponse = await fetch(this.MOBILENET_CLASSES_PATH);\n if (classResponse.ok) {\n this.mobileNetClassMap = await classResponse.json();\n this.logger.state('CLASES_MOBILENET_CARGADAS', {\n classCount: Object.keys(this.mobileNetClassMap).length\n });\n }\n } catch (error) {\n this.logger.warn('No se pudo cargar el mapa de clases de MobileNet, usando clasificación básica');\n // Create a basic class map for document types\n this.mobileNetClassMap = {\n \"0\": \"document\",\n \"1\": \"id_card\",\n \"2\": \"passport\",\n \"3\": \"license\",\n \"4\": \"other\"\n };\n }\n\n // Load model\n const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);\n try {\n this.mobileNetSession = await (window as any).ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, sessionOptions);\n } catch (error) {\n if (error.message.includes('failed to allocate a buffer')) {\n this.logger.warn('Fallo en asignación de buffer de MobileNet, intentando con configuración mínima');\n const fallbackOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'disabled',\n logSeverityLevel: 4,\n enableCpuMemArena: false,\n enableMemPattern: false,\n executionMode: 'sequential',\n interOpNumThreads: 1,\n intraOpNumThreads: 1,\n };\n this.mobileNetSession = await (window as any).ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, fallbackOptions);\n } else {\n throw error;\n }\n }\n this.logger.state('MODELO_MOBILENET_CARGADO_EXITOSAMENTE', {\n sessionCreated: !!this.mobileNetSession\n });\n\n } catch (error) {\n this.logger.error('Error al cargar modelo MobileNet:', error);\n throw error;\n }\n }\n\n isModelLoaded(): boolean {\n return this.modelLoaded && !!this.session;\n }\n\n preprocess(video: HTMLVideoElement): any {\n if (!this.preprocessCanvas || !this.preprocessCtx) {\n this.initializeCanvasPool();\n }\n\n this.preprocessCtx!.clearRect(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);\n this.preprocessCtx!.drawImage(video, 0, 0, this.INPUT_SIZE, this.INPUT_SIZE);\n\n const imageData = this.preprocessCtx!.getImageData(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);\n const [R, G, B] = [[], [], []] as number[][];\n const { data } = imageData;\n\n for (let i = 0; i < data.length; i += 4) {\n R.push(data[i] / 255);\n G.push(data[i + 1] / 255);\n B.push(data[i + 2] / 255);\n }\n\n const transposedData = new Float32Array(R.concat(G, B));\n const float16Data = new Uint16Array(transposedData.length);\n for (let i = 0; i < transposedData.length; i++) {\n float16Data[i] = this.float32ToFloat16(transposedData[i]);\n }\n return new (window as any).ort.Tensor(\"float16\", float16Data, [1, 3, this.INPUT_SIZE, this.INPUT_SIZE]);\n }\n\n async runInference(inputTensor: any): Promise<DetectionBox[]> {\n if (!this.session) {\n throw new Error('Detection model not loaded');\n }\n\n const feeds = { [this.session.inputNames[0]]: inputTensor };\n const results = await this.session.run(feeds);\n const output = results[this.session.outputNames[0]].data;\n\n const detections: DetectionBox[] = [];\n for (let i = 0; i < output.length; i += 6) {\n const [x1, y1, x2, y2, score, classId] = output.slice(i, i + 6);\n if (score > this.CONFIDENCE_THRESHOLD) {\n detections.push({\n x: x1,\n y: y1,\n w: x2 - x1,\n h: y2 - y1,\n score,\n classId\n });\n }\n }\n\n return detections;\n }\n\n async classifyDocument(canvas: HTMLCanvasElement): Promise<ClassificationResult | null> {\n if (!this.mobileNetSession || !this.mobileNetClassMap) {\n this.logger.warn('Modelo MobileNet no está cargado, saltando clasificación');\n return null;\n }\n\n try {\n this.logger.state('CLASIFICANDO_DOCUMENTO', { timestamp: Date.now() });\n\n const inputTensor = this.preprocessMobileNet(canvas);\n const feeds = { [this.mobileNetSession.inputNames[0]]: inputTensor };\n const results = await this.mobileNetSession.run(feeds);\n const output = results[Object.keys(results)[0]].data;\n\n const maxIdx = output.reduce((bestIdx: number, val: number, idx: number, arr: number[]) =>\n val > arr[bestIdx] ? idx : bestIdx, 0);\n const confidence = output[maxIdx];\n\n const className = this.mobileNetClassMap[maxIdx.toString()] || \"unknown\";\n\n this.logger.state('DOCUMENTO_CLASIFICADO', {\n class: className,\n confidence: confidence.toFixed(3),\n classIndex: maxIdx,\n timestamp: Date.now(),\n results\n });\n\n return {\n class: className,\n confidence: confidence,\n classIndex: maxIdx\n };\n\n } catch (error) {\n this.logger.error('Error al clasificar documento:', error);\n return null;\n }\n }\n\n checkSideAlignment(box: DetectionBox, maskConfig: any): SideAlignment {\n const { INPUT_SIZE, ID1_ASPECT_RATIO, shouldMirrorVideo, alignmentTolerance, maskSize, videoRef } = maskConfig;\n\n if (!videoRef) {\n return { top: false, right: false, bottom: false, left: false };\n }\n\n // Get video dimensions to calculate actual mask boundaries in model space\n const videoWidth = videoRef.videoWidth;\n const videoHeight = videoRef.videoHeight;\n\n if (videoWidth === 0 || videoHeight === 0) {\n return { top: false, right: false, bottom: false, left: false };\n }\n\n // Calculate video aspect ratio\n const videoAspectRatio = videoWidth / videoHeight;\n\n // The model sees video stretched to 320x320, but we need to calculate where\n // the mask should be in this distorted space to match the visual mask\n\n // In the visual display, we calculate mask size based on the limiting dimension\n // We need to replicate this logic but account for the distortion in model space\n\n // Calculate the \"display\" dimensions (what the visual mask calculations use)\n const containerAspectRatio = 1; // Assume square container for simplicity\n let displayedVideoWidth, displayedVideoHeight;\n\n if (videoAspectRatio > containerAspectRatio) {\n // Video is wider - letterboxed in display\n displayedVideoWidth = INPUT_SIZE;\n displayedVideoHeight = INPUT_SIZE / videoAspectRatio;\n } else {\n // Video is taller - pillarboxed in display\n displayedVideoHeight = INPUT_SIZE;\n displayedVideoWidth = INPUT_SIZE * videoAspectRatio;\n }\n\n // Calculate mask dimensions using the same logic as updateMaskDimensions\n const maxWidthByHeight = displayedVideoHeight * ID1_ASPECT_RATIO;\n\n let visualMaskWidth, visualMaskHeight;\n const sizeRatio = maskSize / 100;\n\n if (maxWidthByHeight <= displayedVideoWidth) {\n // Video height is the limiting factor\n visualMaskHeight = displayedVideoHeight * sizeRatio;\n visualMaskWidth = visualMaskHeight * ID1_ASPECT_RATIO;\n } else {\n // Video width is the limiting factor\n visualMaskWidth = displayedVideoWidth * sizeRatio;\n visualMaskHeight = visualMaskWidth / ID1_ASPECT_RATIO;\n }\n\n // Now map these visual mask dimensions to the distorted model space\n // The model stretches video to 320x320, so we need to apply the inverse transformation\n const modelMaskWidth = visualMaskWidth * (INPUT_SIZE / displayedVideoWidth);\n const modelMaskHeight = visualMaskHeight * (INPUT_SIZE / displayedVideoHeight);\n\n // Calculate mask boundaries in model coordinate system (always centered in 320x320)\n const maskCenterX = INPUT_SIZE / 2;\n const maskCenterY = INPUT_SIZE / 2;\n const maskLeft = maskCenterX - (modelMaskWidth / 2);\n const maskRight = maskCenterX + (modelMaskWidth / 2);\n const maskTop = maskCenterY - (modelMaskHeight / 2);\n const maskBottom = maskCenterY + (modelMaskHeight / 2);\n\n // Obtener las coordenadas del documento detectado\n let docLeft = box.x;\n let docRight = box.x + box.w;\n const docTop = box.y;\n const docBottom = box.y + box.h;\n\n // Si el video está en modo mirror, invertir las coordenadas horizontales\n if (shouldMirrorVideo) {\n const originalDocLeft = docLeft;\n const originalDocRight = docRight;\n docLeft = INPUT_SIZE - originalDocRight;\n docRight = INPUT_SIZE - originalDocLeft;\n }\n\n // Tolerancia para considerar que un lado está alineado (en píxeles)\n const tolerance = alignmentTolerance;\n\n // Verificar alineación de esquinas más estricta\n // Una esquina está alineada solo si AMBOS bordes que la forman están alineados\n const topAligned = Math.abs(docTop - maskTop) <= tolerance;\n const rightAligned = Math.abs(docRight - maskRight) <= tolerance;\n const bottomAligned = Math.abs(docBottom - maskBottom) <= tolerance;\n const leftAligned = Math.abs(docLeft - maskLeft) <= tolerance;\n\n return {\n top: topAligned && leftAligned, // Esquina superior izquierda: borde top Y left alineados\n right: topAligned && rightAligned, // Esquina superior derecha: borde top Y right alineados\n bottom: bottomAligned && leftAligned, // Esquina inferior izquierda: borde bottom Y left alineados\n left: bottomAligned && rightAligned // Esquina inferior derecha: borde bottom Y right alineados\n };\n }\n\n isCardInFrame(box: DetectionBox): boolean {\n const cardCenterX = box.x + box.w / 2;\n const cardCenterY = box.y + box.h / 2;\n const frameCenterX = this.INPUT_SIZE / 2;\n const frameCenterY = this.INPUT_SIZE / 2;\n const toleranceX = 40;\n const toleranceY = 30;\n\n const isCentered = Math.abs(cardCenterX - frameCenterX) < toleranceX &&\n Math.abs(cardCenterY - frameCenterY) < toleranceY;\n const isGoodSize = box.w > 150 && box.w < 300 && box.h > 90 && box.h < 200;\n\n return isCentered && isGoodSize;\n }\n\n areAllSidesAligned(alignment: SideAlignment): boolean {\n return alignment.top && alignment.right && alignment.bottom && alignment.left;\n }\n\n cleanup(): void {\n this.cleanupCanvasPool();\n\n if (this.session) {\n this.session.release?.();\n this.session = undefined;\n }\n if (this.mobileNetSession) {\n this.mobileNetSession.release?.();\n this.mobileNetSession = undefined;\n }\n this.mobileNetClassMap = undefined;\n this.modelLoaded = false;\n\n this.logger.state('DETECCION_SERVICE_LIMPIADO', { timestamp: Date.now() });\n }\n\n private initializeCanvasPool(): void {\n this.preprocessCanvas = document.createElement('canvas');\n this.preprocessCanvas.width = this.INPUT_SIZE;\n this.preprocessCanvas.height = this.INPUT_SIZE;\n this.preprocessCtx = this.preprocessCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true\n })!;\n\n this.captureCanvas = document.createElement('canvas');\n\n this.logger.state('CANVAS_POOL_INICIALIZADO', {\n preprocessCanvasSize: this.INPUT_SIZE\n });\n }\n\n private cleanupCanvasPool(): void {\n if (this.preprocessCanvas) {\n this.preprocessCtx = undefined;\n this.preprocessCanvas = undefined;\n }\n if (this.captureCanvas) {\n this.captureCanvas = undefined;\n }\n }\n\n private float32ToFloat16(value: number): number {\n const buffer = new ArrayBuffer(4);\n const view = new DataView(buffer);\n view.setFloat32(0, value, true);\n\n const f = view.getUint32(0, true);\n const sign = (f >> 31) & 0x1;\n const exp = (f >> 23) & 0xFF;\n const frac = f & 0x7FFFFF;\n\n let newExp = exp - 127 + 15;\n\n if (exp === 0) {\n newExp = 0;\n } else if (exp === 0xFF) {\n newExp = 0x1F;\n } else if (newExp >= 0x1F) {\n newExp = 0x1F;\n return (sign << 15) | (newExp << 10);\n } else if (newExp <= 0) {\n return (sign << 15);\n }\n\n return (sign << 15) | (newExp << 10) | (frac >> 13);\n }\n\n private preprocessMobileNet(canvas: HTMLCanvasElement): any {\n const tempCanvas = document.createElement('canvas');\n tempCanvas.width = 224;\n tempCanvas.height = 224;\n const tempCtx = tempCanvas.getContext('2d')!;\n\n // Resize image to 224x224 for SqueezeNet (using MobileNet interface)\n tempCtx.drawImage(canvas, 0, 0, 224, 224);\n\n const imageData = tempCtx.getImageData(0, 0, 224, 224);\n const data = imageData.data;\n const hw = 224 * 224;\n const arr = new Float32Array(3 * hw);\n\n // SqueezeNet preprocessing: normalize to [0,1] range and arrange in CHW format\n for (let i = 0; i < hw; i++) {\n // Red channel\n arr[i] = data[i * 4 + 0] / 255.0;\n // Green channel\n arr[hw + i] = data[i * 4 + 1] / 255.0;\n // Blue channel\n arr[2 * hw + i] = data[i * 4 + 2] / 255.0;\n }\n\n return new (window as any).ort.Tensor('float32', arr, [1, 3, 224, 224]);\n }\n\n}\n"]}
|
|
@@ -199,6 +199,7 @@ class CameraService {
|
|
|
199
199
|
deviceType = 'desktop';
|
|
200
200
|
preferredCameraFacing = null;
|
|
201
201
|
preferredCamera = 'auto';
|
|
202
|
+
isManuallySelected = false;
|
|
202
203
|
constructor(logger, eventBus, preferredCamera = 'auto') {
|
|
203
204
|
this.logger = logger;
|
|
204
205
|
this.eventBus = eventBus;
|
|
@@ -245,6 +246,11 @@ class CameraService {
|
|
|
245
246
|
}))
|
|
246
247
|
});
|
|
247
248
|
this.setInitialCameraPreference();
|
|
249
|
+
this.logger.state('PREFERENCIA_INICIAL_APLICADA', {
|
|
250
|
+
selectedCameraId: this.selectedCameraId,
|
|
251
|
+
preferredCameraFacing: this.preferredCameraFacing,
|
|
252
|
+
preferredCamera: this.preferredCamera
|
|
253
|
+
});
|
|
248
254
|
this.eventBus.emit('camera-changed', this.selectedCameraId);
|
|
249
255
|
return this.availableCameras;
|
|
250
256
|
}
|
|
@@ -270,6 +276,7 @@ class CameraService {
|
|
|
270
276
|
}
|
|
271
277
|
this.selectedCameraId = cameraId;
|
|
272
278
|
this.updatePreferredFacing(camera);
|
|
279
|
+
this.isManuallySelected = true; // Mark as manually selected
|
|
273
280
|
this.savePreference();
|
|
274
281
|
this.eventBus.emit('camera-changed', cameraId);
|
|
275
282
|
}
|
|
@@ -277,12 +284,31 @@ class CameraService {
|
|
|
277
284
|
return this.preferredCameraFacing;
|
|
278
285
|
}
|
|
279
286
|
async setupCamera(constraints) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
287
|
+
try {
|
|
288
|
+
const finalConstraints = constraints || await this.getMaxResolution();
|
|
289
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
290
|
+
video: finalConstraints,
|
|
291
|
+
audio: false
|
|
292
|
+
});
|
|
293
|
+
return stream;
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
this.logger.error('Error en setupCamera, intentando con restricciones básicas:', error);
|
|
297
|
+
// Fallback to basic constraints if getMaxResolution fails
|
|
298
|
+
const basicConstraints = {
|
|
299
|
+
width: { ideal: 1280 },
|
|
300
|
+
height: { ideal: 720 }
|
|
301
|
+
};
|
|
302
|
+
// Only add facingMode if not on desktop to avoid OverconstrainedError
|
|
303
|
+
if (this.deviceType !== 'desktop' && this.preferredCameraFacing) {
|
|
304
|
+
basicConstraints.facingMode = this.preferredCameraFacing;
|
|
305
|
+
}
|
|
306
|
+
this.logger.state('USANDO_RESTRICCIONES_BASICAS', { constraints: basicConstraints });
|
|
307
|
+
return await navigator.mediaDevices.getUserMedia({
|
|
308
|
+
video: basicConstraints,
|
|
309
|
+
audio: false
|
|
310
|
+
});
|
|
311
|
+
}
|
|
286
312
|
}
|
|
287
313
|
async switchCamera(cameraId) {
|
|
288
314
|
const selectedCamera = this.availableCameras.find(cam => cam.deviceId === cameraId);
|
|
@@ -294,7 +320,8 @@ class CameraService {
|
|
|
294
320
|
await this.setSelectedCamera(cameraId);
|
|
295
321
|
this.logger.state('CAMARA_CAMBIADA', {
|
|
296
322
|
label: selectedCamera.label,
|
|
297
|
-
deviceId: selectedCamera.deviceId
|
|
323
|
+
deviceId: selectedCamera.deviceId,
|
|
324
|
+
isManuallySelected: this.isManuallySelected
|
|
298
325
|
});
|
|
299
326
|
}
|
|
300
327
|
async flipToNextCamera() {
|
|
@@ -376,6 +403,13 @@ class CameraService {
|
|
|
376
403
|
setInitialCameraPreference() {
|
|
377
404
|
if (this.availableCameras.length === 0)
|
|
378
405
|
return;
|
|
406
|
+
// Clear any existing localStorage preferences to ensure fresh start
|
|
407
|
+
localStorage.removeItem('jaak-stamps-camera-preference');
|
|
408
|
+
this.logger.state('APLICANDO_PREFERENCIA_INICIAL', {
|
|
409
|
+
preferredCamera: this.preferredCamera,
|
|
410
|
+
availableCamerasCount: this.availableCameras.length
|
|
411
|
+
});
|
|
412
|
+
this.isManuallySelected = false; // Reset manual selection flag
|
|
379
413
|
if (this.preferredCamera === 'front') {
|
|
380
414
|
this.selectFrontCamera();
|
|
381
415
|
}
|
|
@@ -388,23 +422,56 @@ class CameraService {
|
|
|
388
422
|
}
|
|
389
423
|
selectFrontCamera() {
|
|
390
424
|
this.preferredCameraFacing = 'user';
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
425
|
+
this.logger.state('BUSCANDO_CAMARA_FRONTAL', {
|
|
426
|
+
availableCameras: this.availableCameras.map(cam => ({
|
|
427
|
+
id: cam.deviceId,
|
|
428
|
+
label: cam.label
|
|
429
|
+
}))
|
|
430
|
+
});
|
|
431
|
+
const frontCamera = this.availableCameras.find(camera => {
|
|
432
|
+
const label = camera.label.toLowerCase();
|
|
433
|
+
return label.includes('front') ||
|
|
434
|
+
label.includes('user') ||
|
|
435
|
+
label.includes('selfie') ||
|
|
436
|
+
label.includes('frontal') ||
|
|
437
|
+
(!label.includes('back') && !label.includes('rear') && !label.includes('environment'));
|
|
438
|
+
});
|
|
439
|
+
// If not found, use the first camera (usually front on mobile)
|
|
395
440
|
this.selectedCameraId = frontCamera ? frontCamera.deviceId : this.availableCameras[0].deviceId;
|
|
396
441
|
this.logger.state('CAMARA_FRONTAL_SELECCIONADA', {
|
|
442
|
+
found: !!frontCamera,
|
|
397
443
|
label: frontCamera?.label || this.availableCameras[0].label,
|
|
398
444
|
deviceId: this.selectedCameraId
|
|
399
445
|
});
|
|
400
446
|
}
|
|
401
447
|
selectBackCamera() {
|
|
402
448
|
this.preferredCameraFacing = 'environment';
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
449
|
+
this.logger.state('BUSCANDO_CAMARA_TRASERA', {
|
|
450
|
+
availableCameras: this.availableCameras.map(cam => ({
|
|
451
|
+
id: cam.deviceId,
|
|
452
|
+
label: cam.label
|
|
453
|
+
}))
|
|
454
|
+
});
|
|
455
|
+
// Try to find rear camera with multiple detection methods
|
|
456
|
+
let backCamera = this.availableCameras.find(camera => {
|
|
457
|
+
const label = camera.label.toLowerCase();
|
|
458
|
+
return label.includes('back') ||
|
|
459
|
+
label.includes('rear') ||
|
|
460
|
+
label.includes('environment') ||
|
|
461
|
+
label.includes('trasera') ||
|
|
462
|
+
label.includes('posterior');
|
|
463
|
+
});
|
|
464
|
+
// If not found by label, try to use the last camera (usually rear on mobile)
|
|
465
|
+
if (!backCamera && this.availableCameras.length > 1) {
|
|
466
|
+
backCamera = this.availableCameras[this.availableCameras.length - 1];
|
|
467
|
+
this.logger.state('USANDO_ULTIMA_CAMARA_COMO_TRASERA', {
|
|
468
|
+
label: backCamera.label,
|
|
469
|
+
deviceId: backCamera.deviceId
|
|
470
|
+
});
|
|
471
|
+
}
|
|
406
472
|
this.selectedCameraId = backCamera ? backCamera.deviceId : this.availableCameras[0].deviceId;
|
|
407
473
|
this.logger.state('CAMARA_TRASERA_SELECCIONADA', {
|
|
474
|
+
found: !!backCamera,
|
|
408
475
|
label: backCamera?.label || this.availableCameras[0].label,
|
|
409
476
|
deviceId: this.selectedCameraId
|
|
410
477
|
});
|
|
@@ -415,8 +482,10 @@ class CameraService {
|
|
|
415
482
|
this.logger.state('CAMARA_AUTO_SELECCIONADA_MOBILE', { type: 'rear' });
|
|
416
483
|
}
|
|
417
484
|
else {
|
|
418
|
-
|
|
485
|
+
// For desktop, prefer front camera (usually built-in webcam)
|
|
486
|
+
this.selectFrontCamera();
|
|
419
487
|
this.logger.state('CAMARA_AUTO_SELECCIONADA_DESKTOP', {
|
|
488
|
+
type: 'front',
|
|
420
489
|
label: this.availableCameras[0].label,
|
|
421
490
|
deviceId: this.selectedCameraId
|
|
422
491
|
});
|
|
@@ -430,15 +499,60 @@ class CameraService {
|
|
|
430
499
|
}
|
|
431
500
|
async getMaxResolution() {
|
|
432
501
|
try {
|
|
502
|
+
// Ensure device type is detected before determining constraints
|
|
503
|
+
if (!this.deviceType || this.deviceType === 'desktop') {
|
|
504
|
+
await this.detectDeviceType();
|
|
505
|
+
}
|
|
433
506
|
const videoConstraints = {};
|
|
434
|
-
|
|
507
|
+
this.logger.state('CONFIGURANDO_CONSTRAINS_CAMARA', {
|
|
508
|
+
selectedCameraId: this.selectedCameraId,
|
|
509
|
+
preferredCameraFacing: this.preferredCameraFacing,
|
|
510
|
+
preferredCamera: this.preferredCamera,
|
|
511
|
+
deviceType: this.deviceType,
|
|
512
|
+
isManuallySelected: this.isManuallySelected
|
|
513
|
+
});
|
|
514
|
+
if (this.isManuallySelected && this.selectedCameraId) {
|
|
515
|
+
// When manually selected, use deviceId for exact camera selection
|
|
435
516
|
videoConstraints.deviceId = { exact: this.selectedCameraId };
|
|
517
|
+
this.logger.state('USANDO_CAMARA_MANUAL', {
|
|
518
|
+
deviceId: this.selectedCameraId
|
|
519
|
+
});
|
|
436
520
|
}
|
|
437
521
|
else if (this.preferredCameraFacing) {
|
|
438
|
-
|
|
522
|
+
// Use facingMode for initial preference-based selection
|
|
523
|
+
// Use 'ideal' instead of 'exact' to avoid OverconstrainedError on desktop
|
|
524
|
+
const facingConstraint = this.deviceType === 'desktop'
|
|
525
|
+
? { ideal: this.preferredCameraFacing }
|
|
526
|
+
: { exact: this.preferredCameraFacing };
|
|
527
|
+
videoConstraints.facingMode = facingConstraint;
|
|
528
|
+
this.logger.state('USANDO_FACING_CONSTRAINT', {
|
|
529
|
+
facingMode: this.preferredCameraFacing,
|
|
530
|
+
constraintType: this.deviceType === 'desktop' ? 'ideal' : 'exact'
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
else if (this.selectedCameraId) {
|
|
534
|
+
videoConstraints.deviceId = { exact: this.selectedCameraId };
|
|
535
|
+
this.logger.state('USANDO_CAMARA_SELECCIONADA', {
|
|
536
|
+
deviceId: this.selectedCameraId
|
|
537
|
+
});
|
|
439
538
|
}
|
|
440
539
|
else {
|
|
441
|
-
|
|
540
|
+
// Use preferredCamera setting to determine default facing mode
|
|
541
|
+
if (this.preferredCamera === 'front') {
|
|
542
|
+
videoConstraints.facingMode = "user";
|
|
543
|
+
}
|
|
544
|
+
else if (this.preferredCamera === 'back') {
|
|
545
|
+
videoConstraints.facingMode = "environment";
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
// Auto mode: use environment for mobile/tablet, user for desktop
|
|
549
|
+
videoConstraints.facingMode = (this.deviceType === 'mobile' || this.deviceType === 'tablet') ? "environment" : "user";
|
|
550
|
+
}
|
|
551
|
+
this.logger.state('USANDO_PREFERENCIA_CONFIGURADA', {
|
|
552
|
+
facingMode: videoConstraints.facingMode,
|
|
553
|
+
preferredCamera: this.preferredCamera,
|
|
554
|
+
deviceType: this.deviceType
|
|
555
|
+
});
|
|
442
556
|
}
|
|
443
557
|
const tempStream = await navigator.mediaDevices.getUserMedia({
|
|
444
558
|
video: videoConstraints
|
|
@@ -470,6 +584,10 @@ class CameraService {
|
|
|
470
584
|
}
|
|
471
585
|
catch (err) {
|
|
472
586
|
this.logger.warn('No se pudieron obtener capacidades de cámara, usando configuración de respaldo');
|
|
587
|
+
// Ensure device type is detected before determining constraints
|
|
588
|
+
if (!this.deviceType || this.deviceType === 'desktop') {
|
|
589
|
+
await this.detectDeviceType();
|
|
590
|
+
}
|
|
473
591
|
const isTablet = /iPad|Android/i.test(navigator.userAgent) && window.innerWidth >= 768;
|
|
474
592
|
const fallbackConstraints = {
|
|
475
593
|
width: { ideal: isTablet ? 1280 : 1920 },
|
|
@@ -477,14 +595,33 @@ class CameraService {
|
|
|
477
595
|
};
|
|
478
596
|
// Apply basic focus settings even for fallback
|
|
479
597
|
this.applyBasicFocusSettings(fallbackConstraints);
|
|
480
|
-
if (this.selectedCameraId) {
|
|
598
|
+
if (this.isManuallySelected && this.selectedCameraId) {
|
|
599
|
+
// When manually selected, use deviceId for exact camera selection
|
|
481
600
|
fallbackConstraints.deviceId = { exact: this.selectedCameraId };
|
|
482
601
|
}
|
|
483
602
|
else if (this.preferredCameraFacing) {
|
|
484
|
-
|
|
603
|
+
// Use facingMode for initial preference-based selection
|
|
604
|
+
// Use 'ideal' instead of 'exact' to avoid OverconstrainedError on desktop
|
|
605
|
+
const facingConstraint = this.deviceType === 'desktop'
|
|
606
|
+
? { ideal: this.preferredCameraFacing }
|
|
607
|
+
: { exact: this.preferredCameraFacing };
|
|
608
|
+
fallbackConstraints.facingMode = facingConstraint;
|
|
609
|
+
}
|
|
610
|
+
else if (this.selectedCameraId) {
|
|
611
|
+
fallbackConstraints.deviceId = { exact: this.selectedCameraId };
|
|
485
612
|
}
|
|
486
613
|
else {
|
|
487
|
-
|
|
614
|
+
// Use preferredCamera setting to determine default facing mode
|
|
615
|
+
if (this.preferredCamera === 'front') {
|
|
616
|
+
fallbackConstraints.facingMode = "user";
|
|
617
|
+
}
|
|
618
|
+
else if (this.preferredCamera === 'back') {
|
|
619
|
+
fallbackConstraints.facingMode = "environment";
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
// Auto mode: use environment for mobile/tablet, user for desktop
|
|
623
|
+
fallbackConstraints.facingMode = (this.deviceType === 'mobile' || this.deviceType === 'tablet') ? "environment" : "user";
|
|
624
|
+
}
|
|
488
625
|
}
|
|
489
626
|
return fallbackConstraints;
|
|
490
627
|
}
|
|
@@ -728,7 +865,7 @@ class DetectionService {
|
|
|
728
865
|
modelLoaded = false;
|
|
729
866
|
deviceStrategy;
|
|
730
867
|
MODEL_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/ddmyp-v2.onnx";
|
|
731
|
-
MOBILENET_MODEL_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/
|
|
868
|
+
MOBILENET_MODEL_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/squeezenet_new_fp32.onnx";
|
|
732
869
|
MOBILENET_CLASSES_PATH = "https://storage.googleapis.com/jaak-static/web/component/stamps/cdmmp-v1.json";
|
|
733
870
|
INPUT_SIZE = 320;
|
|
734
871
|
CONFIDENCE_THRESHOLD = 0.6;
|