This project is a Node.js TypeScript application that allows users to upload images of leaves, extract specific features, compare them with known species data, and store the information in a MongoDB database. The API can be extended to support more species and advanced image processing techniques.
- Image Upload: Users can upload leaf images via a REST API.
- Feature Extraction: The system extracts basic features (length, width, color) from the uploaded image.
- Comparison: Extracted features are compared against predefined known species to identify the leaf.
- Result Storage: The species and feature data are stored in MongoDB.
- Result Retrieval: Retrieve stored data including species information from the database.
- Node.js: JavaScript runtime used to build the backend server.
- TypeScript: Adds static typing to JavaScript to help catch errors early.
- MongoDB: NoSQL database to store leaf data.
- Mongoose: Object Data Modeling (ODM) library for MongoDB and Node.js.
- Multer: Middleware for handling
multipart/form-data
, used for image uploads. - Sharp: A high-performance image processing library to extract image metadata like dimensions.
- Express: Fast, unopinionated, minimalist web framework for Node.js.
- dotenv: For managing environment variables.
Ensure you have the following installed:
- Node.js (v12.x or higher)
- MongoDB (You can use a local instance or a cloud instance like MongoDB Atlas)
- npm (comes with Node.js)
-
Clone the repository:
git clone https://github.com/your-username/leaf-classification-api.git cd leaf-classification-api
-
Install dependencies:
npm install
-
Create a
.env
file in the root directory and add the following environment variables:MONGO_URI=mongodb://localhost:27017/leaf-classification PORT=5000
-
Ensure MongoDB is running on your machine or update the
MONGO_URI
to match your MongoDB setup.
To start the server in development mode, use the following command:
npx ts-node-dev src/server.ts
This will compile TypeScript and start the server on the specified port (default: 5000
).
To run both the backend and frontend servers using Nodemon, follow these steps:
-
Install Nodemon (if not already included in your project):
npm install --save-dev nodemon
-
Configure Scripts: Update your
package.json
to include scripts for running the backend and frontend servers concurrently. Here’s an example:"scripts": { "server": "cd src && nodemon --exec ts-node server.ts", "client": "cd client && yarn run dev", "dev": "concurrently \"npm run server\" \"npm run client\"" }
Adjust the
client
script as necessary based on your frontend setup. -
Run Both Servers: Use the following command to start both servers:
npm run dev
This command will run the backend server and the frontend application simultaneously, allowing them to communicate seamlessly.
-
Set Up Axios or Fetch: Use a library like Axios or the Fetch API to make HTTP requests from your frontend to the backend API. Ensure you install Axios if you choose to use it:
npm install axios
-
Make API Calls: In your frontend component, import Axios and make API calls to the backend. Here’s a simple example of how to upload an image:
import axios from 'axios'; const uploadImage = async (file) => { const formData = new FormData(); formData.append('image', file); try { const response = await axios.post('http://localhost:5000/api/images/upload', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }); console.log(response.data); } catch (error) { console.error('Error uploading image:', error); } };
-
CORS Configuration: If your frontend and backend are running on different ports (e.g., frontend on
3000
and backend on5000
), ensure you handle CORS (Cross-Origin Resource Sharing) in your Express server:import cors from 'cors'; const app = express(); app.use(cors());
- Endpoint:
POST /api/images/upload
- Description: Uploads an image of a leaf, extracts features, compares with known species, and stores the result in MongoDB.
- Request:
multipart/form-data
with animage
file. - Response:
{ "message": "Image uploaded successfully", "leaf": { "_id": "60e4f8ef5d9b2c1f88cfeab3", "species": "Oak", "image": "example.jpg", "features": { "length": 10, "width": 5, "color": "Green" }, "__v": 0 } }
- Endpoint:
GET /api/leaves
- Description: Retrieve all leaves stored in the MongoDB database.
- Response:
[ { "_id": "60e4f8ef5d9b2c1f88cfeab3", "species": "Oak", "image": "example.jpg", "features": { "length": 10, "width": 5, "color": "Green" }, "__v": 0 } ]
root/
│
├── src/
│ ├── controllers/
│ │ └── imageController.ts # Handles image processing logic
│ ├── models/
│ │ └── Leaf.ts # Mongoose model for Leaf data
│ ├── routes/
│ │ └── imageRoutes.ts # Routes for image upload and data access
│ ├── utils/
│ │ └── fileUtils.ts # Utility functions for file management
│ ├── app.ts # Express app configuration
│ ├── server.ts # Entry point to start the server
│ └── config/
│ └── db.ts # MongoDB connection configuration
├── uploads/ # Directory to store uploaded images
├── .env # Environment variables
├── package.json # Project dependencies
├── tsconfig.json # TypeScript configuration
└── README.md # Project documentation
- Image Upload: A user uploads a leaf image via a POST request to the
/upload
endpoint. - Feature Extraction: The image is processed using the Sharp library to extract its dimensions (length and width). Color is currently hardcoded as an example.
- Comparison: The extracted features are compared to predefined known species data stored in memory.
- Species Identification: If a match is found between the uploaded image's features and a known species, that species is associated with the image. Otherwise, it is marked as "Unknown".
- Data Storage: The image, species, and extracted features are stored in MongoDB for future reference.
- Result Retrieval: Users can retrieve stored leaf data via a GET request.
- A user uploads an image of a leaf (e.g., an Oak leaf).
- The API extracts the leaf's length, width, and color from the image.
- It compares the extracted features with known species data (Oak, Maple, Pine, etc.).
- If the features match a known species (e.g., Oak), the leaf is classified as "Oak" and saved to the database.
- The user can retrieve the classified leaf data from the database using the provided endpoints.
- Advanced Feature Extraction: Use machine learning or advanced image processing to extract more detailed features (e.g., vein patterns, texture).
- Dynamic Species Data: Instead of hardcoding species data, store the species information in MongoDB for scalability.
- User Authentication: Add user accounts and authentication to restrict access to certain API features.
- Pagination: Implement pagination for large data sets when retrieving multiple records.
- The color extraction logic is currently hardcoded. You may need a more sophisticated approach for real-world use cases.
- The species data is predefined in memory. This should eventually be moved to a database for flexibility.
This project is licensed under the MIT License. See the LICENSE file for details.
- Oge Obubu - Initial work - GitHub
{
"name": "leaf-classification-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"server": "cd src && nodemon --exec ts-node server.ts",
"client": "cd client && yarn run dev",
"dev": "concurrently \"npm run server\" \"npm run client\""
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@types/express": "^4.17.21",
"@types/mongoose": "^5.11.97",
"@types/multer": "^1.4.12",
"@types/node-cron": "^3.0.11",
"@types/sharp": "^0.32.0",
"@types/swagger-ui-express": "^4.1.6",
"dotenv": "^16.4.5",
"express": "^4.21.0",
"mongoose": "^8.6.3",
"multer": "^1.4.5-lts.1",
"node-cron": "^3.0.3",
"sharp": "^0.33.5",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"ts-node": "^10.9.2",
"typescript": "^5.6.2"
},
"devDependencies": {
"concurrently": "^9.0.1",
"nodemon": "^3.1.7"
}
}