|
@@ -87,23 +87,48 @@ export class AnalyzerComponent implements OnInit {
|
|
|
|
|
|
|
|
await this.localInference.loadModel(modelPath);
|
|
await this.localInference.loadModel(modelPath);
|
|
|
|
|
|
|
|
|
|
+ // Get original image dimensions to pass to the parser
|
|
|
|
|
+ const img = await this.loadImageDimensions(this.selectedFile);
|
|
|
|
|
+
|
|
|
// 2. Preprocess the image to Float32Array [1, 3, 640, 640]
|
|
// 2. Preprocess the image to Float32Array [1, 3, 640, 640]
|
|
|
const imageData = await this.imageProcessor.processImage(this.selectedFile);
|
|
const imageData = await this.imageProcessor.processImage(this.selectedFile);
|
|
|
|
|
|
|
|
// 3. Run Inference locally
|
|
// 3. Run Inference locally
|
|
|
const outputTensor = await this.localInference.runInference(imageData);
|
|
const outputTensor = await this.localInference.runInference(imageData);
|
|
|
|
|
+ const rawData = outputTensor.data as Float32Array;
|
|
|
|
|
+
|
|
|
|
|
+ // 4. Decode Tensor -> Detections
|
|
|
|
|
+ // PASS img.width and img.height here
|
|
|
|
|
+ const detections = this.localInference.parseDetections(
|
|
|
|
|
+ rawData,
|
|
|
|
|
+ this.confidence,
|
|
|
|
|
+ img.width,
|
|
|
|
|
+ img.height
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // 5. Calculate Industrial Summary - Updated to match new categories
|
|
|
|
|
+ const summary: any = {
|
|
|
|
|
+ 'Empty_Bunch': 0,
|
|
|
|
|
+ 'Underripe': 0,
|
|
|
|
|
+ 'Abnormal': 0,
|
|
|
|
|
+ 'Ripe': 0,
|
|
|
|
|
+ 'Unripe': 0,
|
|
|
|
|
+ 'Overripe': 0
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ detections.forEach((d: any) => {
|
|
|
|
|
+ if (summary[d.class] !== undefined) summary[d.class]++;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
- // 4. Temporary Mock for Results (Post-processing math logic pending in Phase 5)
|
|
|
|
|
this.results = {
|
|
this.results = {
|
|
|
- industrial_summary: { 'Ripe': 0, 'Abnormal': 0, 'Underripe': 0 },
|
|
|
|
|
|
|
+ industrial_summary: summary,
|
|
|
inference_ms: performance.now() - start,
|
|
inference_ms: performance.now() - start,
|
|
|
- detections: []
|
|
|
|
|
|
|
+ detections: detections
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- console.log('Backend-less PoC: Inference Output Tensor:', outputTensor);
|
|
|
|
|
|
|
+ console.log('Backend-less PoC: Parsed Detections:', detections);
|
|
|
|
|
|
|
|
this.loading = false;
|
|
this.loading = false;
|
|
|
- // We still call drawDetections, but detections array is empty for now
|
|
|
|
|
setTimeout(() => this.drawDetections(), 100);
|
|
setTimeout(() => this.drawDetections(), 100);
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
console.error('Local Analysis Failed:', err);
|
|
console.error('Local Analysis Failed:', err);
|
|
@@ -111,6 +136,19 @@ export class AnalyzerComponent implements OnInit {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // Helper to get raw file dimensions
|
|
|
|
|
+ private loadImageDimensions(file: File): Promise<{width: number, height: number}> {
|
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
|
+ const img = new Image();
|
|
|
|
|
+ img.onload = () => {
|
|
|
|
|
+ const dimensions = { width: img.width, height: img.height };
|
|
|
|
|
+ URL.revokeObjectURL(img.src);
|
|
|
|
|
+ resolve(dimensions);
|
|
|
|
|
+ };
|
|
|
|
|
+ img.src = URL.createObjectURL(file);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
drawDetections(): void {
|
|
drawDetections(): void {
|
|
|
if (!this.results || !this.results.detections || !this.canvas) return;
|
|
if (!this.results || !this.results.detections || !this.canvas) return;
|
|
|
|
|
|