Spaces:
Sleeping
Sleeping
Commit
·
ca3fb9c
1
Parent(s):
e289f8d
add: usecase 2(Image describer, streamlit frontend)
Browse files- app.py +79 -20
- requirements.txt +2 -1
- src/pipeline/main.py +9 -0
- src/services/use_case_two/image_describer.py +63 -0
app.py
CHANGED
@@ -1,37 +1,96 @@
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
|
3 |
from src.pipeline.main import LearnableAI
|
4 |
|
5 |
|
6 |
def main():
|
7 |
-
st.title("LearnableAI
|
8 |
|
9 |
learnable_ai = LearnableAI()
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
"
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
17 |
)
|
18 |
|
19 |
-
if
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
-
|
29 |
-
|
30 |
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
else:
|
34 |
-
st.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
|
37 |
if __name__ == "__main__":
|
|
|
1 |
+
import os
|
2 |
+
import tempfile
|
3 |
+
|
4 |
import streamlit as st
|
5 |
|
6 |
from src.pipeline.main import LearnableAI
|
7 |
|
8 |
|
9 |
def main():
|
10 |
+
st.title("LearnableAI")
|
11 |
|
12 |
learnable_ai = LearnableAI()
|
13 |
|
14 |
+
st.sidebar.header("Configuration")
|
15 |
+
use_case = st.sidebar.radio(
|
16 |
+
"Select Use Case",
|
17 |
+
["Use Case: 1(Word-Sentences)", "Use Case: 2(Image Describer)"]
|
18 |
+
)
|
19 |
+
|
20 |
+
difficulty = st.sidebar.selectbox(
|
21 |
+
"Select Difficulty Level",
|
22 |
+
["Simple", "Easy", "Challenging", "Advanced"]
|
23 |
)
|
24 |
|
25 |
+
if use_case == "Use Case: 1(Word-Sentences)":
|
26 |
+
st.header("Use Case: 2(Image Describer)")
|
27 |
+
|
28 |
+
words = st.text_area(
|
29 |
+
"Words:",
|
30 |
+
"",
|
31 |
+
help="Enter multiple words separated by commas"
|
32 |
+
)
|
33 |
+
|
34 |
+
interest = st.text_input("Child Interest:", "",
|
35 |
+
help="Enter the interest area for the content ie. Superheroes, Animals, etc.")
|
36 |
+
|
37 |
+
if st.button("Generate Content", key="text_process"):
|
38 |
+
if words and interest:
|
39 |
+
try:
|
40 |
+
word_list = [w.strip() for w in words.split(",")] if "," in words else [words.strip()]
|
41 |
+
result = learnable_ai.word_to_sentence(
|
42 |
+
words=word_list,
|
43 |
+
interest=interest,
|
44 |
+
difficulties=difficulty
|
45 |
+
)
|
46 |
+
|
47 |
+
st.success("Content Generated Successfully!")
|
48 |
+
st.write("### Results")
|
49 |
+
st.write(result)
|
50 |
+
|
51 |
+
except Exception as e:
|
52 |
+
st.error(f"An error occurred: {str(e)}")
|
53 |
+
else:
|
54 |
+
st.warning("Please fill in both words and interest fields!")
|
55 |
|
56 |
+
else: # Image Description
|
57 |
+
st.header("Image Description")
|
58 |
|
59 |
+
upload_method = st.radio(
|
60 |
+
"Choose Upload Method",
|
61 |
+
["Upload File", "Capture from Camera"]
|
62 |
+
)
|
63 |
+
|
64 |
+
if upload_method == "Upload File":
|
65 |
+
image_file = st.file_uploader(
|
66 |
+
"Upload an image",
|
67 |
+
type=["jpg", "jpeg", "png"]
|
68 |
+
)
|
69 |
else:
|
70 |
+
image_file = st.camera_input("Take a picture")
|
71 |
+
|
72 |
+
if image_file is not None:
|
73 |
+
st.image(image_file, caption="Uploaded Image", use_column_width=True)
|
74 |
+
|
75 |
+
if st.button("Generate Description", key="image_process"):
|
76 |
+
try: # temp image file
|
77 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as temp_file:
|
78 |
+
temp_file.write(image_file.read())
|
79 |
+
temp_image_path = temp_file.name
|
80 |
+
|
81 |
+
result = learnable_ai.image_describer(
|
82 |
+
image_path=temp_image_path,
|
83 |
+
difficulties=difficulty
|
84 |
+
)
|
85 |
+
|
86 |
+
st.success("Image Processed Successfully!")
|
87 |
+
st.write("### Image Description Results")
|
88 |
+
st.write(result)
|
89 |
+
|
90 |
+
os.remove(temp_image_path) # remove temp image file
|
91 |
+
|
92 |
+
except Exception as e:
|
93 |
+
st.error(f"An error occurred while processing the image: {str(e)}")
|
94 |
|
95 |
|
96 |
if __name__ == "__main__":
|
requirements.txt
CHANGED
@@ -1,2 +1,3 @@
|
|
1 |
groq
|
2 |
-
streamlit
|
|
|
|
1 |
groq
|
2 |
+
streamlit
|
3 |
+
google-generativeai
|
src/pipeline/main.py
CHANGED
@@ -5,15 +5,24 @@ author @ github.com/ishworrsubedii
|
|
5 |
"""
|
6 |
import os
|
7 |
|
|
|
8 |
from groq import Groq
|
9 |
|
10 |
from src.services.use_case_one.word_to_sentence import UseCaseOne
|
|
|
11 |
|
12 |
|
13 |
class LearnableAI:
|
14 |
def __init__(self):
|
15 |
self.groq_client = Groq(api_key=os.getenv('GROQ_API_KEY'))
|
|
|
|
|
16 |
self.use_case_one = UseCaseOne(client=self.groq_client)
|
17 |
|
|
|
|
|
18 |
def word_to_sentence(self, interest: str, difficulties: str, words: list):
|
19 |
return self.use_case_one.generate_educational_content(interest, difficulties, words)
|
|
|
|
|
|
|
|
5 |
"""
|
6 |
import os
|
7 |
|
8 |
+
import google.generativeai as genai
|
9 |
from groq import Groq
|
10 |
|
11 |
from src.services.use_case_one.word_to_sentence import UseCaseOne
|
12 |
+
from src.services.use_case_two.image_describer import ImageDescriptionGenerator
|
13 |
|
14 |
|
15 |
class LearnableAI:
|
16 |
def __init__(self):
|
17 |
self.groq_client = Groq(api_key=os.getenv('GROQ_API_KEY'))
|
18 |
+
self.genai = genai.configure(api_key=os.getenv('GENAI_API_KEY'))
|
19 |
+
|
20 |
self.use_case_one = UseCaseOne(client=self.groq_client)
|
21 |
|
22 |
+
self.use_case_two = ImageDescriptionGenerator()
|
23 |
+
|
24 |
def word_to_sentence(self, interest: str, difficulties: str, words: list):
|
25 |
return self.use_case_one.generate_educational_content(interest, difficulties, words)
|
26 |
+
|
27 |
+
def image_describer(self, image_path: str, difficulties):
|
28 |
+
return self.use_case_two.process_image(image_path, difficulty_level=difficulties)
|
src/services/use_case_two/image_describer.py
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
project @ LearnableAI
|
3 |
+
created @ 2025-01-17
|
4 |
+
author @ github.com/ishworrsubedii
|
5 |
+
"""
|
6 |
+
import google.generativeai as genai
|
7 |
+
from PIL import Image
|
8 |
+
|
9 |
+
|
10 |
+
class ImageDescriptionGenerator:
|
11 |
+
def __init__(self):
|
12 |
+
self.model = genai.GenerativeModel('gemini-1.5-flash')
|
13 |
+
|
14 |
+
def process_image(self, image_path, difficulty_level, ):
|
15 |
+
try:
|
16 |
+
img = Image.open(image_path)
|
17 |
+
|
18 |
+
prompt = self._create_analysis_prompt(difficulty_level)
|
19 |
+
|
20 |
+
response = self.model.generate_content([prompt, img])
|
21 |
+
|
22 |
+
return response.text
|
23 |
+
|
24 |
+
except Exception as e:
|
25 |
+
return f"Error processing image: {str(e)}"
|
26 |
+
|
27 |
+
def _create_analysis_prompt(self, difficulty_level):
|
28 |
+
return f"""
|
29 |
+
# Image Analysis for Children
|
30 |
+
|
31 |
+
Please analyze this image and create child-friendly content based on these parameters:
|
32 |
+
- Difficulty Level: {difficulty_level}
|
33 |
+
|
34 |
+
Generate the following:
|
35 |
+
1. Simple description of the image (2-3 sentences)
|
36 |
+
2. Three interesting details about what you see
|
37 |
+
3. Four age-appropriate questions about the image
|
38 |
+
4. One interactive activity related to the image
|
39 |
+
|
40 |
+
Requirements:
|
41 |
+
- Use simple, clear language appropriate for {difficulty_level} level
|
42 |
+
- Questions should encourage observation and critical thinking
|
43 |
+
- Include both easy and slightly challenging questions
|
44 |
+
- Activity should be engaging and educational
|
45 |
+
|
46 |
+
Format the response exactly like this:
|
47 |
+
DESCRIPTION:
|
48 |
+
[Image description]
|
49 |
+
|
50 |
+
INTERESTING DETAILS:
|
51 |
+
1. [Detail 1]
|
52 |
+
2. [Detail 2]
|
53 |
+
3. [Detail 3]
|
54 |
+
|
55 |
+
QUESTIONS:
|
56 |
+
Q1: [Question 1]
|
57 |
+
Q2: [Question 2]
|
58 |
+
Q3: [Question 3]
|
59 |
+
Q4: [Question 4]
|
60 |
+
|
61 |
+
ACTIVITY:
|
62 |
+
[Activity description]
|
63 |
+
"""
|