Upload 7 files
Browse files- app.py +50 -0
- class_distribution.csv +6 -0
- eda.py +102 -0
- model_improved.zip +3 -0
- packages.txt +1 -0
- prediction.py +70 -0
- requirements.txt +8 -0
app.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Import libraries
|
2 |
+
import eda, prediction
|
3 |
+
import streamlit as st
|
4 |
+
|
5 |
+
# Add sidebar
|
6 |
+
navigation = st.sidebar.selectbox('Navigation', ['Home', 'Exploratory Data Analysis', 'Vegetable Image Classification'])
|
7 |
+
|
8 |
+
st.sidebar.markdown('# About')
|
9 |
+
|
10 |
+
# Introduction
|
11 |
+
st.sidebar.write('''
|
12 |
+
This tool is designed to explore and predict vegetable images. It uses advanced data analysis and machine learning models to provide insights and predictions that can help in understanding and addressing vegetable image classification effectively.
|
13 |
+
''')
|
14 |
+
|
15 |
+
# Define the Home Page
|
16 |
+
def show_home():
|
17 |
+
|
18 |
+
|
19 |
+
st.markdown('---')
|
20 |
+
|
21 |
+
st.write('''
|
22 |
+
This tool provides functionalities for Exploratory Data Analysis and Prediction regarding vegetable image classification.
|
23 |
+
Use the navigation pane on the left to select the module you wish to utilize.
|
24 |
+
''')
|
25 |
+
|
26 |
+
# Dataset
|
27 |
+
st.write('#### 📈 Dataset')
|
28 |
+
st.markdown('''
|
29 |
+
The dataset contains pertinent information on various vegetable images. It includes images of Cabbage, Capsicum, Carrot, Cauliflower, and Pumpkin.
|
30 |
+
''')
|
31 |
+
|
32 |
+
# Problem Statement
|
33 |
+
st.write('#### ⚠️ Problem Statement')
|
34 |
+
st.markdown('''
|
35 |
+
The challenge is to accurately classify different types of vegetables from images. This classification task can help in various applications such as automated sorting, inventory management, and enhancing user experiences in agriculture-related applications.
|
36 |
+
''')
|
37 |
+
|
38 |
+
# Objective
|
39 |
+
st.write('#### 💡 Objective')
|
40 |
+
st.markdown('''
|
41 |
+
The goal of this project is to create a `Convolutional Neural Network (CNN)` model that accurately predicts the type of vegetable from images. It will distinguish between **Cabbage**, **Capsicum**, **Carrot**, **Cauliflower**, and **Pumpkin**, primarily using `accuracy` as the evaluation metric. This aims to improve classification accuracy and assist in various practical applications.
|
42 |
+
''')
|
43 |
+
|
44 |
+
# Create condition to access different pages
|
45 |
+
if navigation == 'Home':
|
46 |
+
show_home()
|
47 |
+
elif navigation == 'Exploratory Data Analysis':
|
48 |
+
eda.run()
|
49 |
+
elif navigation == 'Vegetable Image Classification':
|
50 |
+
prediction.run()
|
class_distribution.csv
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Case Category,Number of Images
|
2 |
+
Cabbage,125
|
3 |
+
Capsicum,125
|
4 |
+
Carrot,125
|
5 |
+
Cauliflower,125
|
6 |
+
Pumpkin,125
|
eda.py
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import os
|
4 |
+
from PIL import Image
|
5 |
+
import matplotlib.pyplot as plt
|
6 |
+
import plotly.express as px
|
7 |
+
|
8 |
+
# Function to check if file exists
|
9 |
+
def check_file(file_path):
|
10 |
+
if not os.path.exists(file_path):
|
11 |
+
st.error(f"File {file_path} not found. Please make sure the file exists in the correct directory.")
|
12 |
+
return False
|
13 |
+
return True
|
14 |
+
|
15 |
+
# Create the main program
|
16 |
+
def run():
|
17 |
+
file_path = 'class_distribution.csv'
|
18 |
+
|
19 |
+
# Check if the file exists
|
20 |
+
if not check_file(file_path):
|
21 |
+
return
|
22 |
+
|
23 |
+
# Load the data from the CSV file
|
24 |
+
cases_df = pd.read_csv(file_path)
|
25 |
+
|
26 |
+
# Add a title for the Streamlit app
|
27 |
+
st.title("Exploratory Data Analysis")
|
28 |
+
|
29 |
+
# Add subtitle
|
30 |
+
st.write('''Choose what to visualize:''')
|
31 |
+
|
32 |
+
# Create a multi-select dropdown for choosing visualization type
|
33 |
+
visualization_type = st.multiselect('Select Visualization:', ('Class Distribution', 'Images'))
|
34 |
+
|
35 |
+
if 'Class Distribution' in visualization_type:
|
36 |
+
# Create an interactive bar chart with Plotly
|
37 |
+
st.subheader('Number of Images in Each Case Category')
|
38 |
+
fig = px.bar(cases_df, x='Case Category', y='Number of Images',
|
39 |
+
color='Case Category',
|
40 |
+
labels={'Number of Images': 'Number of Images', 'Case Category': 'Case Category'},
|
41 |
+
height=400,
|
42 |
+
color_discrete_sequence=['lightsteelblue', 'navajowhite', 'lightsalmon'])
|
43 |
+
fig.update_layout(showlegend=False)
|
44 |
+
st.plotly_chart(fig)
|
45 |
+
|
46 |
+
# Add additional information if necessary
|
47 |
+
st.write('''Diagram batang menunjukkan distribusi gambar untuk lima kategori sayuran.''')
|
48 |
+
st.write('''1. **Cabbage**: Kategori ini memiliki 125 gambar, yang menunjukkan fokus signifikan pada penangkapan kondisi kubis.''')
|
49 |
+
st.write('''2. **Capsicum**: Terdapat 125 gambar untuk kategori ini, menunjukkan pentingnya penangkapan kondisi capsicum.''')
|
50 |
+
st.write('''3. **Carrot**: Kategori ini memiliki 125 gambar, menandakan perhatian yang seimbang terhadap kondisi wortel.''')
|
51 |
+
st.write('''4. **Cauliflower**: Terdapat 125 gambar untuk kategori ini, menunjukkan upaya untuk menangkap variasi dalam kondisi kembang kol.''')
|
52 |
+
st.write('''5. **Pumpkin**: Kategori ini memiliki 125 gambar, menunjukkan fokus untuk memahami kondisi labu.''')
|
53 |
+
st.write('''Distribusi yang seimbang ini diharapkan dapat meningkatkan diagnostik untuk semua kondisi sayuran.''')
|
54 |
+
|
55 |
+
if 'Images' in visualization_type:
|
56 |
+
|
57 |
+
# Add title
|
58 |
+
st.markdown('''### **Image Visualization**''')
|
59 |
+
|
60 |
+
# Define the directories for each class
|
61 |
+
class_dirs = {'Cabbage': './Image_Sample/Cabbage',
|
62 |
+
'Capsicum': './Image_Sample/Capsicum',
|
63 |
+
'Carrot': './Image_Sample/Carrot',
|
64 |
+
'Cauliflower': './Image_Sample/Cauliflower',
|
65 |
+
'Pumpkin': './Image_Sample/Pumpkin'}
|
66 |
+
|
67 |
+
# Display images and descriptions for each category in separate sections
|
68 |
+
for class_name, folder in class_dirs.items():
|
69 |
+
st.subheader(f'{class_name} Images')
|
70 |
+
image_files = [f for f in os.listdir(folder) if f.endswith(('png', 'jpg', 'jpeg'))][:5]
|
71 |
+
fig, axes = plt.subplots(1, len(image_files), figsize=(20, 4)) # Adjust subplot layout as needed
|
72 |
+
|
73 |
+
for idx, image_file in enumerate(image_files):
|
74 |
+
img_path = os.path.join(folder, image_file)
|
75 |
+
img = Image.open(img_path)
|
76 |
+
if len(image_files) > 1:
|
77 |
+
axes[idx].imshow(img)
|
78 |
+
axes[idx].axis('off')
|
79 |
+
axes[idx].set_title(image_file)
|
80 |
+
else:
|
81 |
+
axes.imshow(img)
|
82 |
+
axes.axis('off')
|
83 |
+
axes.set_title(image_file)
|
84 |
+
|
85 |
+
plt.tight_layout()
|
86 |
+
st.pyplot(fig)
|
87 |
+
|
88 |
+
# Add description for each class after displaying images
|
89 |
+
if class_name == 'Cabbage':
|
90 |
+
st.write('''Gambar kubis menunjukkan daun-daun dengan permukaan yang halus dan bebas dari kerusakan parah atau pertumbuhan yang tidak teratur.''')
|
91 |
+
elif class_name == 'Capsicum':
|
92 |
+
st.write('''Gambar capsicum memperlihatkan permukaan yang bersih dan tidak adanya tanda-tanda kerusakan signifikan, menunjukkan kondisi kesehatan yang baik.''')
|
93 |
+
elif class_name == 'Carrot':
|
94 |
+
st.write('''Gambar wortel menunjukkan permukaan yang halus tanpa tanda-tanda pertumbuhan yang tidak biasa, menandakan kondisi yang sehat.''')
|
95 |
+
elif class_name == 'Cauliflower':
|
96 |
+
st.write('''Gambar kembang kol menunjukkan distribusi permukaan yang rata dan tidak ada pertumbuhan yang tidak teratur, menunjukkan kondisi yang baik.''')
|
97 |
+
elif class_name == 'Pumpkin':
|
98 |
+
st.write('''Gambar labu memperlihatkan permukaan yang bersih dan struktur yang sehat, tanpa tanda-tanda kerusakan yang signifikan.''')
|
99 |
+
|
100 |
+
# Run the app
|
101 |
+
if __name__ == '__main__':
|
102 |
+
run()
|
model_improved.zip
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:5df8162fb47bf5da0f9ad76997299fd144ba4c25dbd593b7dd3938a7471c94c2
|
3 |
+
size 57700873
|
packages.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
python3-opencv
|
prediction.py
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
from PIL import Image
|
4 |
+
from keras.models import load_model
|
5 |
+
from time import sleep
|
6 |
+
|
7 |
+
# Load the saved model
|
8 |
+
model_path = 'model_improved.keras'
|
9 |
+
try:
|
10 |
+
model = load_model(model_path)
|
11 |
+
except ValueError as e:
|
12 |
+
st.error(f"Error loading model: {e}")
|
13 |
+
|
14 |
+
# Define the labels
|
15 |
+
labels = ['Cabbage', 'Capsicum', 'Carrot', 'Cauliflower', 'Pumpkin']
|
16 |
+
|
17 |
+
# Preprocess the image to match the model's input requirements
|
18 |
+
def preprocess_image(image):
|
19 |
+
image = image.resize((224, 224)) # Resize to the correct dimensions
|
20 |
+
image = np.array(image)
|
21 |
+
image = image / 255.0 # Normalize the image
|
22 |
+
image = np.expand_dims(image, axis=0) # Add batch dimension
|
23 |
+
return image
|
24 |
+
|
25 |
+
def run():
|
26 |
+
# Streamlit interface
|
27 |
+
st.title('Vegetable Image Classification')
|
28 |
+
st.write("Upload an image to classify it as Cabbage, Capsicum, Carrot, Cauliflower, or Pumpkin.")
|
29 |
+
|
30 |
+
uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"], help='Allowed file types: .jpg, .jpeg, .png')
|
31 |
+
|
32 |
+
if uploaded_file is not None:
|
33 |
+
# Display the uploaded image
|
34 |
+
image = Image.open(uploaded_file)
|
35 |
+
st.image(image, caption='Uploaded Image.', use_column_width=True)
|
36 |
+
|
37 |
+
# Preprocess the image
|
38 |
+
processed_image = preprocess_image(image)
|
39 |
+
|
40 |
+
# Make a prediction
|
41 |
+
prediction = model.predict(processed_image)
|
42 |
+
predicted_class = np.argmax(prediction, axis=1)[0]
|
43 |
+
predicted_label = labels[predicted_class]
|
44 |
+
probability = np.max(prediction) * 100
|
45 |
+
|
46 |
+
# Add progression
|
47 |
+
bar = st.progress(0)
|
48 |
+
for percent_complete in range(101):
|
49 |
+
sleep(0.005)
|
50 |
+
bar.progress(percent_complete)
|
51 |
+
st.success('Prediction Completed!')
|
52 |
+
|
53 |
+
# Display the prediction and probability
|
54 |
+
st.write(f"**Result: {predicted_label}**")
|
55 |
+
st.write(f"**Confidence: {probability:.2f}%**")
|
56 |
+
|
57 |
+
# Interpret the prediction
|
58 |
+
if predicted_label == 'Cabbage':
|
59 |
+
st.write("The image is classified as Cabbage. It has a dense-leaved head and is commonly used in various dishes.")
|
60 |
+
elif predicted_label == 'Capsicum':
|
61 |
+
st.write("The image is classified as Capsicum, known for its various colors and shapes, including bell peppers and chili peppers.")
|
62 |
+
elif predicted_label == 'Carrot':
|
63 |
+
st.write("The image is classified as Carrot, the familiar long, orange root vegetable.")
|
64 |
+
elif predicted_label == 'Cauliflower':
|
65 |
+
st.write("The image is classified as Cauliflower, depicted by its white, compact head surrounded by green leaves.")
|
66 |
+
elif predicted_label == 'Pumpkin':
|
67 |
+
st.write("The image is classified as Pumpkin, recognized by its round, orange fruit with a thick shell.")
|
68 |
+
|
69 |
+
if __name__ == "__main__":
|
70 |
+
run()
|
requirements.txt
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
pandas
|
3 |
+
seaborn
|
4 |
+
matplotlib
|
5 |
+
scikit-learn
|
6 |
+
plotly
|
7 |
+
tensorflow
|
8 |
+
opencv-python
|