Commit
·
c87ad69
1
Parent(s):
2cdb0fa
Full feature upload.
Browse files- .gitignore +2 -0
- app.py +89 -2
- model/labels.json +30 -0
- model/labels.txt +7 -0
- model/model.tflite +3 -0
- requirements.txt +8 -0
.gitignore
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
.venv
|
2 |
+
.env
|
app.py
CHANGED
@@ -1,4 +1,91 @@
|
|
1 |
import streamlit as st
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
+
import tempfile
|
3 |
+
from PIL import Image
|
4 |
+
import os
|
5 |
+
import tensorflow as tf
|
6 |
+
import numpy as np
|
7 |
+
import io
|
8 |
+
import json
|
9 |
+
from google import genai
|
10 |
+
from dotenv import dotenv_values, load_dotenv
|
11 |
|
12 |
+
load_dotenv()
|
13 |
+
|
14 |
+
config = dotenv_values(".env")
|
15 |
+
|
16 |
+
MODEL_ID = "gemini-2.0-flash"
|
17 |
+
model_id = MODEL_ID
|
18 |
+
client = genai.Client(api_key = config["GEMINI_API_KEY"])
|
19 |
+
|
20 |
+
# Load labels from JSON file
|
21 |
+
with open('model/labels.json', 'r') as f:
|
22 |
+
labels = json.load(f)
|
23 |
+
|
24 |
+
# Load TensorFlow Lite model
|
25 |
+
def load_tflite_model():
|
26 |
+
interpreter = tf.lite.Interpreter(model_path="model/model.tflite")
|
27 |
+
interpreter.allocate_tensors()
|
28 |
+
return interpreter
|
29 |
+
|
30 |
+
# Get input and output details
|
31 |
+
interpreter = load_tflite_model()
|
32 |
+
input_details = interpreter.get_input_details()
|
33 |
+
output_details = interpreter.get_output_details()
|
34 |
+
|
35 |
+
def main():
|
36 |
+
st.title("Skin Cancer Classifier")
|
37 |
+
img_file = None
|
38 |
+
image_path = ""
|
39 |
+
|
40 |
+
# Upload an image
|
41 |
+
img_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
|
42 |
+
|
43 |
+
if img_file is not None:
|
44 |
+
# Save the image to a temporary file
|
45 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file:
|
46 |
+
temp_file.write(img_file.read())
|
47 |
+
image_path = temp_file.name
|
48 |
+
st.write("Image saved to:", image_path)
|
49 |
+
st.image(image_path, use_container_width=True)
|
50 |
+
|
51 |
+
if st.button("Classify"):
|
52 |
+
with st.spinner("Processing..."):
|
53 |
+
image = Image.open(io.BytesIO(img_file.getbuffer())).convert('RGB')
|
54 |
+
|
55 |
+
# Get model input shape
|
56 |
+
input_shape = input_details[0]['shape']
|
57 |
+
|
58 |
+
# Preprocess the image
|
59 |
+
image = image.resize((input_shape[1], input_shape[2]))
|
60 |
+
image_array = np.array(image, dtype=np.float32)
|
61 |
+
image_array = image_array / 255.0
|
62 |
+
image_array = np.expand_dims(image_array, axis=0)
|
63 |
+
|
64 |
+
# Make prediction
|
65 |
+
interpreter.set_tensor(input_details[0]['index'], image_array)
|
66 |
+
interpreter.invoke()
|
67 |
+
|
68 |
+
# Get prediction results
|
69 |
+
prediction = interpreter.get_tensor(output_details[0]['index'])
|
70 |
+
|
71 |
+
# Get the predicted class index
|
72 |
+
predicted_class_index = np.argmax(prediction[0])
|
73 |
+
|
74 |
+
# Get the corresponding label information
|
75 |
+
predicted_label = labels[predicted_class_index]
|
76 |
+
|
77 |
+
genai_response = client.models.generate_content(
|
78 |
+
model=MODEL_ID,
|
79 |
+
contents=[
|
80 |
+
"You are a medical encyclopedia. You are given a skin cancer image and you need to provide a detailed explanation of the disease and its treatment.",
|
81 |
+
f"The predicted class is {predicted_label['name']}. Provide a detailed explanation of the disease, its treatment, and prevention.",
|
82 |
+
"Start with the title: Classfification of Skin Cancer",
|
83 |
+
]
|
84 |
+
)
|
85 |
+
|
86 |
+
# Display Gemini response
|
87 |
+
st.markdown(genai_response.text)
|
88 |
+
|
89 |
+
|
90 |
+
if __name__ == "__main__":
|
91 |
+
main()
|
model/labels.json
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"label": "akiec",
|
4 |
+
"name": "Actinic Keratoses and Intraepithelial Carcinomae"
|
5 |
+
},
|
6 |
+
{
|
7 |
+
"label": "bcc",
|
8 |
+
"name": "Basal Cell Carcinoma"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"label": "bkl",
|
12 |
+
"name": "Benign Keratosis"
|
13 |
+
},
|
14 |
+
{
|
15 |
+
"label": "df",
|
16 |
+
"name": "Dermatofibroma"
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"label": "mel",
|
20 |
+
"name": "Melanoma"
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"label": "nv",
|
24 |
+
"name": "Melanocytic Nevi"
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"label": "vasc",
|
28 |
+
"name": "Vascular Skin Lesions"
|
29 |
+
}
|
30 |
+
]
|
model/labels.txt
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
akiec
|
2 |
+
bcc
|
3 |
+
bkl
|
4 |
+
df
|
5 |
+
mel
|
6 |
+
nv
|
7 |
+
vasc
|
model/model.tflite
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:247b237b98b121939ec335d716b2bf9bc36d8c4e34d86729b7fb676a2ea6a590
|
3 |
+
size 10336348
|
requirements.txt
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
flask
|
2 |
+
tensorflow
|
3 |
+
numpy
|
4 |
+
pillow
|
5 |
+
python-dotenv
|
6 |
+
google-genai
|
7 |
+
streamlit
|
8 |
+
python-dotenv
|