done
This commit is contained in:
63
Server/controllers/classificationController.js
Normal file
63
Server/controllers/classificationController.js
Normal file
@ -0,0 +1,63 @@
|
||||
const tf = require('@tensorflow/tfjs-node');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Path ke model
|
||||
const modelPath = path.join(
|
||||
__dirname,
|
||||
'../resources/ResNet-50_tomato-leaf-disease-tfjs_v8/model.json'
|
||||
);
|
||||
|
||||
let model;
|
||||
|
||||
// Fungsi untuk memuat model
|
||||
const loadModel = async () => {
|
||||
try {
|
||||
model = await tf.loadLayersModel(`file://${modelPath}`);
|
||||
console.log('Model loaded successfully.');
|
||||
} catch (err) {
|
||||
console.error('Error loading model:', err);
|
||||
throw new Error('Model loading failed.');
|
||||
}
|
||||
};
|
||||
|
||||
// Memuat model saat aplikasi dimulai
|
||||
loadModel();
|
||||
|
||||
const preprocessImage = async (imagePath) => {
|
||||
const imageBuffer = fs.readFileSync(imagePath);
|
||||
let tensor = tf.node.decodeImage(imageBuffer, 3);
|
||||
tensor = tf.image.resizeBilinear(tensor, [224, 224]);
|
||||
tensor = tensor.expandDims(0);
|
||||
//tensor = tensor.toFloat().div(tf.scalar(255.0));
|
||||
return tensor;
|
||||
};
|
||||
|
||||
// Fungsi untuk mengklasifikasikan gambar
|
||||
const classifyImage = async (imagePath) => {
|
||||
try {
|
||||
const classes = [
|
||||
'bacterial_spot',
|
||||
'healthy',
|
||||
'late_blight',
|
||||
'leaf_curl_virus',
|
||||
'leaf_mold',
|
||||
'mosaic_virus',
|
||||
'septoria_leaf_spot',
|
||||
];
|
||||
|
||||
const tensor = await preprocessImage(imagePath);
|
||||
const predictions = model.predict(tensor);
|
||||
const predictedClassIndex = predictions.argMax(-1).dataSync()[0];
|
||||
|
||||
// Ambil nama kelas berdasarkan indeks
|
||||
const predictedClassName = classes[predictedClassIndex];
|
||||
|
||||
return { index: predictedClassIndex, class: predictedClassName };
|
||||
} catch (err) {
|
||||
console.error('Error during classification:', err);
|
||||
throw new Error('Error during classification.');
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { classifyImage };
|
63
Server/controllers/classificationController.js.save
Normal file
63
Server/controllers/classificationController.js.save
Normal file
@ -0,0 +1,63 @@
|
||||
const tf = require('@tensorflow/tfjs-node');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Path ke model
|
||||
const modelPath = path.join(
|
||||
__dirname,
|
||||
'../resources/ResNet-50_tomato-leaf-disease-tfjs_v8/model.json'
|
||||
);
|
||||
|
||||
let model;
|
||||
|
||||
// Fungsi untuk memuat model
|
||||
const loadModel = async () => {
|
||||
try {
|
||||
model = await tf.loadLayersModel(`file://${modelPath}`);
|
||||
console.log('Model loaded successfully.');
|
||||
} catch (err) {
|
||||
console.error('Error loading model:', err);
|
||||
throw new Error('Model loading failed.');
|
||||
}
|
||||
};
|
||||
|
||||
// Memuat model saat aplikasi dimulai
|
||||
loadModel();
|
||||
|
||||
const preprocessImage = async (imagePath) => {
|
||||
const imageBuffer = fs.readFileSync(imagePath);
|
||||
let tensor = tf.node.decodeImage(imageBuffer, 3);
|
||||
tensor = tf.image.resizeBilinear(tensor, [224, 224]);
|
||||
tensor = tensor.expandDims(0);
|
||||
//tensor = tensor.toFloat().div(tf.scalar(255.0));
|
||||
return tensor;
|
||||
};
|
||||
|
||||
// Fungsi untuk mengklasifikasikan gambar
|
||||
const classifyImage = async (imagePath) => {
|
||||
try {
|
||||
const classes = [
|
||||
'bacterial_spot',
|
||||
'healthy',
|
||||
'late_blight',
|
||||
'leaf_curl_virus',
|
||||
'leaf_mold',
|
||||
'mosaic_virus',
|
||||
'septoria_leaf_spot',
|
||||
];
|
||||
|
||||
const tensor = await preprocessImage(imagePath);
|
||||
const predictions = model.predict(tensor);
|
||||
const predictedClassIndex = predictions.argMax(-1).dataSync()[0];
|
||||
|
||||
// Ambil nama kelas berdasarkan indeks
|
||||
const predictedClassName = classes[predictedClassIndex];
|
||||
|
||||
return { index: predictedClassIndex, class: predictedClassName };
|
||||
} catch (err) {
|
||||
console.error('Error during classification:', err);
|
||||
throw new Error('Error during classification.');
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { classifyImage };
|
61
Server/controllers/classificationController.js.save.1
Normal file
61
Server/controllers/classificationController.js.save.1
Normal file
@ -0,0 +1,61 @@
|
||||
const tf = require('@tensorflow/tfjs-node');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Path ke model
|
||||
const modelPath = path.join(
|
||||
__dirname,
|
||||
'../resources/ResNet-50_tomato-leaf-disease-tfjs_nobg/model.json'
|
||||
);
|
||||
|
||||
let model;
|
||||
|
||||
const loadModel = async () => {
|
||||
try {
|
||||
model = await tf.loadLayersModel(`file://${modelPath}`);
|
||||
console.log('Model loaded successfully.');
|
||||
} catch (err) {
|
||||
console.error('Error loading model:', err);
|
||||
throw new Error('Model loading failed.');
|
||||
}
|
||||
};
|
||||
|
||||
loadModel();
|
||||
|
||||
const preprocessImage = async (imagePath) => {
|
||||
const imageBuffer = fs.readFileSync(imagePath);
|
||||
let tensor = tf.node.decodeImage(imageBuffer, 3);
|
||||
tensor = tf.image.resizeBilinear(tensor, [224, 224]);
|
||||
tensor = tensor.expandDims(0);
|
||||
//tensor = tensor.toFloat().div(tf.scalar(255.0));
|
||||
return tensor;
|
||||
};
|
||||
|
||||
// Fungsi untuk mengklasifikasikan gambar
|
||||
const classifyImage = async (imagePath) => {
|
||||
try {
|
||||
const classes = [
|
||||
'bacterial_spot',
|
||||
'healthy',
|
||||
'late_blight',
|
||||
'leaf_curl_virus',
|
||||
'leaf_mold',
|
||||
'mosaic_virus',
|
||||
'septoria_leaf_spot',
|
||||
];
|
||||
|
||||
const tensor = await preprocessImage(imagePath);
|
||||
const predictions = model.predict(tensor);
|
||||
const predictedClassIndex = predictions.argMax(-1).dataSync()[0];
|
||||
|
||||
// Ambil nama kelas berdasarkan indeks
|
||||
const predictedClassName = classes[predictedClassIndex];
|
||||
|
||||
return { index: predictedClassIndex, class: predictedClassName };
|
||||
} catch (err) {
|
||||
console.error('Error during classification:', err);
|
||||
throw new Error('Error during classification.');
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { classifyImage };
|
23
Server/middleware/authMiddleware.js
Normal file
23
Server/middleware/authMiddleware.js
Normal file
@ -0,0 +1,23 @@
|
||||
function basicAuth(req, res, next) {
|
||||
const authHeader = req.headers['authorization'];
|
||||
|
||||
if (!authHeader || !authHeader.startsWith('Basic ')) {
|
||||
res.setHeader('WWW-Authenticate', 'Basic');
|
||||
return res.status(401).send('Authentication required.');
|
||||
}
|
||||
|
||||
const base64Credentials = authHeader.split(' ')[1];
|
||||
const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii');
|
||||
const [username, password] = credentials.split(':');
|
||||
|
||||
const USERNAME = 'rahasia';
|
||||
const PASSWORD = 'tomat';
|
||||
|
||||
if (username === USERNAME && password === PASSWORD) {
|
||||
next();
|
||||
} else {
|
||||
return res.status(403).send('Access denied.');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = basicAuth;
|
18
Server/package.json
Normal file
18
Server/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@tensorflow/tfjs-node": "^4.8.0",
|
||||
"express": "^4.21.2",
|
||||
"multer": "^1.4.5-lts.1"
|
||||
},
|
||||
"name": "tomato_leaf_care",
|
||||
"version": "1.0.0",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": ""
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
13
Server/routes/checkRoute.js
Normal file
13
Server/routes/checkRoute.js
Normal file
@ -0,0 +1,13 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/check', (req, res) => {
|
||||
res.status(200).json({
|
||||
status: 'ok',
|
||||
message: 'Server is up and running',
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
31
Server/routes/classificationRoute.js
Normal file
31
Server/routes/classificationRoute.js
Normal file
@ -0,0 +1,31 @@
|
||||
const express = require('express');
|
||||
const multer = require('multer');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { classifyImage } = require('../controllers/classificationController');
|
||||
|
||||
const router = express.Router();
|
||||
const upload = multer({ dest: 'uploads/' });
|
||||
|
||||
router.post('/classify', upload.single('image'), async (req, res) => {
|
||||
try {
|
||||
if (!req.file) {
|
||||
return res.status(400).json({ error: 'No image file uploaded' });
|
||||
}
|
||||
|
||||
const imagePath = path.join(__dirname, `../${req.file.path}`);
|
||||
const predictedClass = await classifyImage(imagePath);
|
||||
|
||||
fs.unlinkSync(imagePath);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
predictedClass,
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
28
Server/server.js
Normal file
28
Server/server.js
Normal file
@ -0,0 +1,28 @@
|
||||
const express = require("express");
|
||||
const fs = require("fs");
|
||||
const https = require("https");
|
||||
|
||||
const basicAuth = require("./middleware/authMiddleware")
|
||||
const classificationRoutes = require("./routes/classificationRoute");
|
||||
const checkRoutes = require("./routes/checkRoute");
|
||||
|
||||
const app = express();
|
||||
const port = 8000;
|
||||
|
||||
//const sslOptions = {
|
||||
// key: fs.readFileSync("./ssl/server.key"),
|
||||
// cert: fs.readFileSync("./ssl/server.crt")
|
||||
//};
|
||||
|
||||
app.use("/tomatoleafcare", basicAuth, classificationRoutes);
|
||||
app.use("/tomatoleafcare", basicAuth, checkRoutes);
|
||||
|
||||
//https.createServer(sslOptions, app).listen(port, () => {
|
||||
// console.log(`HTTPS Server is running on port ${port}...`);
|
||||
//});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server running on http://localhost:${port}`);
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user