Skip to content

Commit

Permalink
Resolving all console errors with respect to the image classification…
Browse files Browse the repository at this point in the history
… model
  • Loading branch information
mohanamisra committed Dec 30, 2024
1 parent 38d6347 commit e2488ad
Show file tree
Hide file tree
Showing 15 changed files with 491 additions and 21 deletions.
317 changes: 313 additions & 4 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@mui/material": "^6.3.0",
"@tensorflow/tfjs": "^4.22.0",
"axios": "^1.7.9",
"body-parser": "^1.20.3",
"cheerio": "^1.0.0",
Expand All @@ -24,6 +25,7 @@
"react": "^19.0.0-rc.1",
"react-dom": "^19.0.0-rc.1",
"react-leaflet": "^5.0.0-rc.2",
"react-modal": "^3.16.3",
"request-promise": "^4.2.6"
},
"devDependencies": {
Expand Down
Binary file added public/tfjs_model/group1-shard1of9.bin
Binary file not shown.
Binary file added public/tfjs_model/group1-shard2of9.bin
Binary file not shown.
Binary file added public/tfjs_model/group1-shard3of9.bin
Binary file not shown.
Binary file added public/tfjs_model/group1-shard4of9.bin
Binary file not shown.
Binary file added public/tfjs_model/group1-shard5of9.bin
Binary file not shown.
Binary file added public/tfjs_model/group1-shard6of9.bin
Binary file not shown.
Binary file added public/tfjs_model/group1-shard7of9.bin
Binary file not shown.
Binary file added public/tfjs_model/group1-shard8of9.bin
Binary file not shown.
Binary file added public/tfjs_model/group1-shard9of9.bin
Binary file not shown.
1 change: 1 addition & 0 deletions public/tfjs_model/model.json

Large diffs are not rendered by default.

Binary file added src/assets/upload_image.webp
Binary file not shown.
69 changes: 61 additions & 8 deletions src/components/DamageAssessmentTool/DamageAssessor.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,66 @@
.ai-damage-assessment {
.upload-section {
border: 3px dashed #007bff;
background-color: #f8f9fa;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
position: relative;
transition: background-color 0.3s, border-color 0.3s;
cursor: pointer;
}

.upload-section img {
height: 150px;
width: 150px;
margin-bottom: 10px;
opacity: 0.8;
}

.file-upload-label {
font-size: 16px;
font-weight: bold;
color: #0056b3;
margin-bottom: 8px;
text-align: center;
}

.file-upload-input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}

.file-name {
font-size: 14px;
color: #555;
margin-top: 10px;
margin-right: 10px;
font-style: italic;
}

p>.label {
font-weight: 600;
.modal {
background: #fff;
border-radius: 8px;
padding: 20px;
max-width: 400px;
margin: auto;
text-align: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

p {
margin-top: 6px;
line-height: 1.5rem;
}
.overlay {
background: rgba(0, 0, 0, 0.6);
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
}
123 changes: 114 additions & 9 deletions src/components/DamageAssessmentTool/DamageAssessor.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,125 @@
import React from 'react';
import "./DamageAssessor.css"
import React, { useState, useEffect } from 'react';
import "./DamageAssessor.css";
import * as tf from "@tensorflow/tfjs";
import uploadImage from "../../assets/upload_image.webp";
import Modal from 'react-modal';

const labels = [
"Flood",
"Earthquake",
"Wildfire",
"Tornado",
"Hurricane",
"Volcano",
"Drought",
"Landslide",
"Tsunami",
"Snowstorm",
"Thunderstorm",
"Hailstorm",
"Other"
];

const DamageAssessor = () => {
const [model, setModel] = useState(null);
const [fileName, setFileName] = useState('');
const [predictedClass, setPredictedClass] = useState('');
const [isModalOpen, setIsModalOpen] = useState(false);

useEffect(() => {
const loadModel = async () => {
const modelUrl = `public/tfjs_model/model.json`;
try {
const loadedModel = await tf.loadLayersModel(modelUrl);
setModel(loadedModel);
} catch (error) {
console.error("Error loading model:", error);
}
};
loadModel();
}, []);

const preprocessImage = async (file) => {
const imageBitmap = await createImageBitmap(file);
const canvas = document.createElement("canvas");
canvas.width = 256;
canvas.height = 256;
const ctx = canvas.getContext("2d");
ctx.drawImage(imageBitmap, 0, 0, 256, 256);

const imageData = ctx.getImageData(0, 0, 256, 256);
let tensor = tf.browser.fromPixels(imageData)
.expandDims()
.div(255.0);

return tensor;
};

const handleFileUpload = async (file) => {
if (file && ['image/jpeg', 'image/jpg', 'image/png', 'image/webp'].includes(file.type)) {
setFileName(file.name);

if (model) {
const preprocessedImage = await preprocessImage(file);
const prediction = model.predict(preprocessedImage).arraySync();
const predictedIndex = prediction.indexOf(Math.max(...prediction));
const predictedLabel = labels[predictedIndex];

setPredictedClass(predictedLabel);
setIsModalOpen(true);
} else {
alert("Model is not loaded yet. Please try again later.");
}
} else {
alert("Invalid file type. Please upload an image with .jpg, .jpeg, .png, or .webp extension.");
}
};

const handleChange = async (e) => {
if (e.target.files.length) {
await handleFileUpload(e.target.files[0]);
}
};

return (
<div className="ai-damage-assessment">
<h2>AI Damage Assessment Tool</h2>
<p>
<span className = "label">Step 1</span>: Upload an image whose damage you want to assess. We do not store any uploaded
images.<br/>
<span className = "label">Step 2</span>: Click the submit button.<br/>
<span className= "label">Step 3</span>: A dialog box with opens up.<br/>
<span className= "label">Step 4</span>: Review the AI analysis.<br/>
<span className= "label">Step 5</span>: Close the dialog box.<br/>
<span className="label">Step 1</span>: Upload an image whose damage you want to assess. We do not store any uploaded
images.<br />
<span className="label">Step 2</span>: Click the submit button.<br />
<span className="label">Step 3</span>: A dialog box opens up.<br />
<span className="label">Step 4</span>: Review the AI analysis.<br />
<span className="label">Step 5</span>: Close the dialog box.<br />
</p>
<div className="upload-section">
<img src={uploadImage} alt="Section for uploading images" />
<label htmlFor="file-upload" className="file-upload-label">
Drag and drop an image here or click to upload
</label>
<input
type="file"
id="file-upload"
accept=".jpg,.jpeg,.png,.webp"
className="file-upload-input"
onChange={handleChange}
/>
{fileName && <p className="file-name">Uploaded: {fileName}</p>}
</div>
<Modal
isOpen={isModalOpen}
onRequestClose={() => setIsModalOpen(false)}
contentLabel="Prediction Result"
className="modal"
ariaHideApp={false}
overlayClassName="overlay"
>
<h2>Prediction Result</h2>
<p>The uploaded image belongs to the class: <strong>{predictedClass}</strong></p>
<button onClick={() => setIsModalOpen(false)}>Close</button>
</Modal>
</div>
);
};

export default DamageAssessor;
export default DamageAssessor;

0 comments on commit e2488ad

Please sign in to comment.