As the name implies, an API service to analyze palm fruit photos

Dr-Swopt 3a04becb84 update пре 2 часа
.claude 7b4d5a81fb update git пре 1 недеља
models dc5c309367 new survellance feature пре 4 дана
src 3a04becb84 update пре 2 часа
test dc5c309367 new survellance feature пре 4 дана
.gitignore 99147dc0cc feat: implement palm oil ripeness detection service with ONNX inference and SQLite history persistence пре 1 недеља
.prettierrc 2a3b8cd5d8 chore: initial commit with NestJS scaffolding and static definitions пре 1 недеља
CLAUDE.md 8c4cb6596a update backend for bvatch processing пре 3 часа
README.md 2b0175b00c minor fix пре 1 недеља
best.onnx 8e2434d036 palm oil component пре 1 недеља
eslint.config.mjs 2a3b8cd5d8 chore: initial commit with NestJS scaffolding and static definitions пре 1 недеља
nest-cli.json 2a3b8cd5d8 chore: initial commit with NestJS scaffolding and static definitions пре 1 недеља
package-lock.json dc5c309367 new survellance feature пре 4 дана
package.json dc5c309367 new survellance feature пре 4 дана
tsconfig.build.json 2a3b8cd5d8 chore: initial commit with NestJS scaffolding and static definitions пре 1 недеља
tsconfig.json dc5c309367 new survellance feature пре 4 дана

README.md

🌴 Palm Oil Ripeness Detection Service

A NestJS backend API that uses an ONNX-based YOLOv26 model to perform real-time ripeness classification of oil palm fresh fruit bunches (FFB). Detection results are mapped against MPOB (Malaysian Palm Oil Board) grading standards, persisted to a local SQLite database, and served via a REST API.


🚀 Features

  • AI Inference via ONNX Runtime — Runs a custom-trained YOLOv8 model (best.onnx) using onnxruntime-node for zero-dependency, high-performance server-side inference.
  • MPOB-Standard Classification — Detects and classifies palm oil bunches into 6 industry-standard grades: | Class | Description | |---|---| | Ripe | Optimal harvest quality | | Underripe | Harvested too early | | Unripe | Not yet ready | | Overripe | Past optimal harvest window | | Abnormal | ⚠️ Health alert | | Empty_Bunch | ⚠️ Health alert |
  • Industrial Summary — Each analysis response includes a per-class count summary for field reporting.
  • Health Alert Flagging — Detections with Abnormal or Empty_Bunch classes are automatically flagged with is_health_alert: true.
  • History Persistence — All scans are saved to a local SQLite database via TypeORM, with the last 50 records retrievable via the history endpoint.
  • CORS Enabled — Ready for integration with any frontend (Angular, React, etc.).
  • Image Pass-Through — The original image is returned as a Base64 data URI in the response for frontend canvas rendering.

🏗️ Architecture Overview

src/
├── main.ts                          # Bootstrap (port 3000, CORS enabled)
├── app.module.ts                    # Root module
└── palm-oil/
    ├── palm-oil.controller.ts       # REST endpoints
    ├── palm-oil.service.ts          # Orchestration logic & SQLite persistence
    ├── palm-oil.module.ts           # Feature module
    ├── providers/
    │   └── scanner.provider.ts      # ONNX inference pipeline (preprocess → infer → postprocess)
    ├── entities/
    │   └── history.entity.ts        # TypeORM entity for scan history
    ├── interfaces/
    │   └── palm-analysis.interface.ts  # TypeScript types for API response
    └── constants/
        └── mpob-standards.ts        # MPOB class map, grade colors, and health alert list

Inference Pipeline (ScannerProvider)

  1. Preprocess — Resize image to 640×640 using sharp, strip alpha, extract raw pixels, and transpose from HWC → CHW layout, normalizing to [0.0, 1.0].
  2. Inference — Feed the [1, 3, 640, 640] float tensor into the ONNX session. Input key: images.
  3. Postprocess — Parse the [1, N, 6] output tensor (x1, y1, x2, y2, confidence, class_index). Filter by a default confidence threshold of 0.25. Scale normalized bounding box coordinates to the original image pixel dimensions.

📋 Prerequisites

  • Node.js >=18
  • npm >=9
  • The ONNX model file best.onnx must be placed in the project root directory.

⚙️ Project Setup

npm install

▶️ Running the Service

# Development (single run)
npm run start

# Development (watch mode — auto-restarts on file changes)
npm run start:dev

# Production
npm run start:prod

The server starts on http://localhost:3000 by default. Set the PORT environment variable to override.


📡 API Endpoints

POST /palm-oil/analyze

Analyzes an uploaded image for palm oil ripeness.

Request: multipart/form-data

Field Type Description
image File The palm oil bunch image to analyze

Response: application/json

{
  "status": "success",
  "current_threshold": 0.25,
  "total_count": 4,
  "industrial_summary": {
    "Empty_Bunch": 0,
    "Underripe": 1,
    "Abnormal": 0,
    "Ripe": 2,
    "Unripe": 0,
    "Overripe": 1
  },
  "detections": [
    {
      "bunch_id": 1,
      "class": "Ripe",
      "confidence": 0.9312,
      "is_health_alert": false,
      "box": [120.5, 88.3, 450.2, 390.1]
    }
  ],
  "image_data": "data:image/jpeg;base64,...",
  "inference_ms": 42.15,
  "processing_ms": 115.30,
  "archive_id": "palm_1712345678901_456"
}

GET /palm-oil/history

Returns the last 50 scan records from the SQLite database, ordered by most recent first.

Response: application/json — Array of History entities.


🧪 Running Tests

# Unit tests
npm run test

# Unit tests (watch mode)
npm run test:watch

# End-to-end tests
npm run test:e2e

# Test coverage report
npm run test:cov

🗄️ Database

Scan history is persisted to a local SQLite file (palm_history.db) in the project root, managed by TypeORM with synchronize: true. No external database setup is required.

Each history record stores:

  • archive_id — Unique scan identifier
  • filename — Original uploaded file name
  • total_count — Number of detections
  • industrial_summary — Per-class count (JSON)
  • detections — Full detection array with bounding boxes (JSON)
  • inference_ms / processing_ms — Performance timings
  • created_at — Auto-generated timestamp

🗂️ Key Files

File Purpose
best.onnx YOLOv8 ONNX inference model (must be in project root)
palm_history.db SQLite scan history database (auto-created)
src/palm-oil/constants/mpob-standards.ts MPOB class definitions, colors, and health alert flags
src/palm-oil/providers/scanner.provider.ts Core AI inference pipeline
src/palm-oil/palm-oil.service.ts Business logic, summary generation, persistence
src/palm-oil/palm-oil.controller.ts REST API layer

📦 Core Dependencies

Package Purpose
@nestjs/core NestJS framework
onnxruntime-node ONNX model inference
sharp High-performance image preprocessing
typeorm + sqlite3 Database ORM and SQLite driver
class-validator DTO validation

📄 License

UNLICENSED — Private project.