SURESHBEEKHANI commited on
Commit
626a37c
Β·
verified Β·
1 Parent(s): 868abbe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -52
app.py CHANGED
@@ -12,12 +12,12 @@ from reportlab.lib.styles import getSampleStyleSheet
12
  # ======================
13
  # CONFIGURATION SETTINGS
14
  # ======================
15
- st.set_page_config(
16
- page_title="Rice Quality Analyzer",
17
- page_icon="🌾",
18
- layout="wide",
19
- initial_sidebar_state="expanded"
20
- )
21
 
22
  ALLOWED_FILE_TYPES = ['png', 'jpg', 'jpeg']
23
 
@@ -26,11 +26,11 @@ CSS_STYLES = """
26
  .main { background-color: #f4f9f9; color: #000000; }
27
  .sidebar .sidebar-content { background-color: #d1e7dd; }
28
  .stTextInput textarea { color: #000000 !important; }
29
- .stButton>button {
30
- background-color: #21eeef;
31
- color: white;
32
- font-size: 16px;
33
- border-radius: 5px;
34
  }
35
  .report-container {
36
  background-color: #ffffff;
@@ -48,22 +48,28 @@ CSS_STYLES = """
48
  }
49
  </style>
50
  """
51
- st.markdown(CSS_STYLES, unsafe_allow_html=True)
52
 
53
  # ======================
54
  # CORE FUNCTIONS
55
  # ======================
 
 
 
 
 
56
  def initialize_api_client():
57
- """Initialize and validate the Groq API client."""
58
  load_dotenv()
59
  api_key = os.getenv("GROQ_API_KEY")
 
60
  if not api_key:
61
- st.error("API key not found. Please check .env configuration.")
62
  st.stop()
 
63
  return Groq(api_key=api_key)
64
 
65
  def process_image_data(uploaded_file):
66
- """Convert image to base64 encoded string."""
67
  try:
68
  image = Image.open(uploaded_file)
69
  buffer = io.BytesIO()
@@ -74,49 +80,46 @@ def process_image_data(uploaded_file):
74
  return None, None
75
 
76
  def generate_pdf_report(report_text):
77
- """Generate a PDF report from the analysis text."""
78
  buffer = io.BytesIO()
79
  doc = SimpleDocTemplate(buffer, pagesize=letter)
80
  styles = getSampleStyleSheet()
81
- story = [
82
- Paragraph("<b>Rice Quality Report</b>", styles['Title']),
83
- Spacer(1, 12),
84
- Paragraph(report_text.replace('\n', '<br/>'), styles['BodyText'])
85
- ]
 
 
 
 
86
  doc.build(story)
87
  buffer.seek(0)
88
  return buffer
89
 
90
  def generate_rice_report(uploaded_file, client):
91
- """Generate AI-powered rice quality analysis."""
92
  base64_image, img_format = process_image_data(uploaded_file)
 
93
  if not base64_image:
94
  return None
95
-
96
  image_url = f"data:image/{img_format.lower()};base64,{base64_image}"
97
-
98
  try:
99
  response = client.chat.completions.create(
100
  model="llama-3.2-11b-vision-preview",
101
- messages=[
102
- {"role": "user", "content": [
 
103
  {"type": "text", "text": (
104
  "Analyze the rice grain image and provide a detailed report including:\n"
105
  "1. Rice type classification\n2. Quality assessment (broken grains %, discoloration %, impurities %)\n"
106
- "3. Foreign object detection\n4. Size and shape consistency\n5. Recommendations for processing or improvement\n"
107
- "6. Additional metrics:\n"
108
- " - % Broken kernel (Accuracy < 0.5%)\n"
109
- " - Size analysis per each kernel (Accuracy < 50 micron):\n"
110
- " - Length, Width, Area, Length to Width Ratio\n"
111
- " - Abnormal color and damage kernel recognition:\n"
112
- " - Chalky, Black spots, Yellow (Heat damage), Red (Heat damage), Green kernels\n"
113
- " - Kernel count\n"
114
- " - 1,000 kernels weight\n"
115
- " - Group sizing information"
116
  )},
117
  {"type": "image_url", "image_url": {"url": image_url}},
118
- ]}
119
- ],
120
  temperature=0.2,
121
  max_tokens=400,
122
  top_p=0.5
@@ -130,23 +133,16 @@ def generate_rice_report(uploaded_file, client):
130
  # UI COMPONENTS
131
  # ======================
132
  def display_main_interface():
133
- """Render primary application interface."""
134
  st.title("🌾 Rice Quality Analyzer")
135
  st.subheader("AI-Powered Rice Grain Inspection")
136
  st.markdown("---")
137
 
138
- st.markdown("### Key Benefits:")
139
- st.markdown("- Reduces inspection time by a factor of 10")
140
- st.markdown("- Simple 3-step process: Load sample β†’ Click start β†’ Get results")
141
- st.markdown("- Results stored in a database for traceability and further analysis")
142
- st.markdown("- Integration with 3rd party instruments for higher-level data analysis")
143
- st.markdown("- No minimum sample size required")
144
- st.markdown("- No complicated sample preparation needed")
145
-
146
- if 'analysis_result' in st.session_state:
147
  st.markdown("### πŸ“‹ Analysis Report")
148
  st.markdown(
149
- f'<div class="report-container"><div class="report-text">{st.session_state.analysis_result}</div></div>',
150
  unsafe_allow_html=True
151
  )
152
  pdf_report = generate_pdf_report(st.session_state.analysis_result)
@@ -156,15 +152,48 @@ def display_main_interface():
156
  file_name="rice_quality_report.pdf",
157
  mime="application/pdf"
158
  )
159
-
160
  if st.button("Clear Analysis πŸ—‘οΈ"):
161
  st.session_state.pop('analysis_result', None)
162
  st.rerun()
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  def main():
165
- """Primary application controller."""
 
166
  groq_client = initialize_api_client()
 
167
  display_main_interface()
 
168
 
169
  if __name__ == "__main__":
170
- main()
 
12
  # ======================
13
  # CONFIGURATION SETTINGS
14
  # ======================
15
+ PAGE_CONFIG = {
16
+ "page_title": "Rice Quality Analyzer",
17
+ "page_icon": "🌾",
18
+ "layout": "wide",
19
+ "initial_sidebar_state": "expanded"
20
+ }
21
 
22
  ALLOWED_FILE_TYPES = ['png', 'jpg', 'jpeg']
23
 
 
26
  .main { background-color: #f4f9f9; color: #000000; }
27
  .sidebar .sidebar-content { background-color: #d1e7dd; }
28
  .stTextInput textarea { color: #000000 !important; }
29
+ .stButton>button {
30
+ background-color: #21eeef;
31
+ color: white;
32
+ font-size: 16px;
33
+ border-radius: 5px;
34
  }
35
  .report-container {
36
  background-color: #ffffff;
 
48
  }
49
  </style>
50
  """
 
51
 
52
  # ======================
53
  # CORE FUNCTIONS
54
  # ======================
55
+ def configure_application():
56
+ """Initialize application settings and styling"""
57
+ st.set_page_config(**PAGE_CONFIG)
58
+ st.markdown(CSS_STYLES, unsafe_allow_html=True)
59
+
60
  def initialize_api_client():
61
+ """Create and validate Groq API client"""
62
  load_dotenv()
63
  api_key = os.getenv("GROQ_API_KEY")
64
+
65
  if not api_key:
66
+ st.error("API key not found. Please verify .env configuration.")
67
  st.stop()
68
+
69
  return Groq(api_key=api_key)
70
 
71
  def process_image_data(uploaded_file):
72
+ """Convert image to base64 encoded string"""
73
  try:
74
  image = Image.open(uploaded_file)
75
  buffer = io.BytesIO()
 
80
  return None, None
81
 
82
  def generate_pdf_report(report_text):
83
+ """Generate PDF document from report text"""
84
  buffer = io.BytesIO()
85
  doc = SimpleDocTemplate(buffer, pagesize=letter)
86
  styles = getSampleStyleSheet()
87
+ story = []
88
+
89
+ title = Paragraph("<b>Rice Quality Report</b>", styles['Title'])
90
+ story.append(title)
91
+ story.append(Spacer(1, 12))
92
+
93
+ content = Paragraph(report_text.replace('\n', '<br/>'), styles['BodyText'])
94
+ story.append(content)
95
+
96
  doc.build(story)
97
  buffer.seek(0)
98
  return buffer
99
 
100
  def generate_rice_report(uploaded_file, client):
101
+ """Generate AI-powered rice quality analysis"""
102
  base64_image, img_format = process_image_data(uploaded_file)
103
+
104
  if not base64_image:
105
  return None
106
+
107
  image_url = f"data:image/{img_format.lower()};base64,{base64_image}"
108
+
109
  try:
110
  response = client.chat.completions.create(
111
  model="llama-3.2-11b-vision-preview",
112
+ messages=[{
113
+ "role": "user",
114
+ "content": [
115
  {"type": "text", "text": (
116
  "Analyze the rice grain image and provide a detailed report including:\n"
117
  "1. Rice type classification\n2. Quality assessment (broken grains %, discoloration %, impurities %)\n"
118
+ "3. Foreign object detection\n4. Size and shape consistency\n5. Recommendations for processing or improvement"
 
 
 
 
 
 
 
 
 
119
  )},
120
  {"type": "image_url", "image_url": {"url": image_url}},
121
+ ]
122
+ }],
123
  temperature=0.2,
124
  max_tokens=400,
125
  top_p=0.5
 
133
  # UI COMPONENTS
134
  # ======================
135
  def display_main_interface():
136
+ """Render primary application interface"""
137
  st.title("🌾 Rice Quality Analyzer")
138
  st.subheader("AI-Powered Rice Grain Inspection")
139
  st.markdown("---")
140
 
141
+ # Display analysis results
142
+ if st.session_state.get('analysis_result'):
 
 
 
 
 
 
 
143
  st.markdown("### πŸ“‹ Analysis Report")
144
  st.markdown(
145
+ f'<div class="report-container"><div class="report-text">{st.session_state.analysis_result}</div></div>',
146
  unsafe_allow_html=True
147
  )
148
  pdf_report = generate_pdf_report(st.session_state.analysis_result)
 
152
  file_name="rice_quality_report.pdf",
153
  mime="application/pdf"
154
  )
155
+
156
  if st.button("Clear Analysis πŸ—‘οΈ"):
157
  st.session_state.pop('analysis_result', None)
158
  st.rerun()
159
 
160
+ def render_sidebar(client):
161
+ """Create sidebar interface elements"""
162
+ with st.sidebar:
163
+ st.markdown("### Features")
164
+ st.markdown("""
165
+ - **Rice Type Classification** (e.g., Basmati, Jasmine, Indica)
166
+ - **Quality Check** (Broken grains %, impurities %, discoloration %)
167
+ - **Foreign Object Detection** (Husks, stones, debris)
168
+ - **Grain Size & Shape Analysis**
169
+ - **Processing Recommendations**
170
+ """)
171
+ st.markdown("---")
172
+
173
+ st.subheader("Upload Rice Image")
174
+ uploaded_file = st.file_uploader(
175
+ "Select an image of rice grains",
176
+ type=ALLOWED_FILE_TYPES
177
+ )
178
+
179
+ if uploaded_file:
180
+ st.image(Image.open(uploaded_file), caption="Uploaded Image", use_column_width=True)
181
+ if st.button("Analyze Rice Quality πŸ”"):
182
+ with st.spinner("Processing image... This may take a few seconds."):
183
+ report = generate_rice_report(uploaded_file, client)
184
+ st.session_state.analysis_result = report
185
+ st.rerun()
186
+
187
+ # ======================
188
+ # APPLICATION ENTRYPOINT
189
+ # ======================
190
  def main():
191
+ """Primary application controller"""
192
+ configure_application()
193
  groq_client = initialize_api_client()
194
+
195
  display_main_interface()
196
+ render_sidebar(groq_client)
197
 
198
  if __name__ == "__main__":
199
+ main()