chariscait commited on
Commit
7f331f4
·
verified ·
1 Parent(s): 3e2a599

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +97 -4
app.py CHANGED
@@ -36,6 +36,7 @@ except ImportError:
36
  from models import EmotionLabel, EMOTION_LABELS, CulturalRegion, EMOTION_EMOJI
37
  from face_detector import FaceEmotionDetector
38
  from text_detector import TextEmotionDetector
 
39
  from auth import (
40
  validate_email,
41
  is_email_used,
@@ -268,6 +269,12 @@ def load_text_detector():
268
  det.load()
269
  return det
270
 
 
 
 
 
 
 
271
 
272
  # =====================================================================
273
  # Helper: Render Functions
@@ -564,13 +571,14 @@ def show_demo():
564
  )
565
 
566
  st.markdown("# EMOSPHERE")
567
- st.markdown("*Real-time multimodal emotion detection -- face & text*")
568
 
569
  face_det = load_face_detector()
570
  text_det = load_text_detector()
 
571
 
572
- tab_camera, tab_text, tab_history = st.tabs([
573
- "Camera / Image", "Text Analysis", "History",
574
  ])
575
 
576
  # -- Camera / Image Tab --
@@ -721,6 +729,91 @@ def show_demo():
721
  "text": text_input[:100],
722
  })
723
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
724
  # -- History Tab --
725
  with tab_history:
726
  st.markdown("### Emotion History")
@@ -754,7 +847,7 @@ def show_demo():
754
  for h in reversed(history[-10:]):
755
  emo = EMOTION_EMOJI.get(EmotionLabel(h["dominant"]), "")
756
  color = EMOTION_COLORS.get(EmotionLabel(h["dominant"]), "#94A3B8")
757
- modality_icon = {"face": "📷", "text": "💬"}.get(
758
  h["modality"], "🔮"
759
  )
760
  snippet = ""
 
36
  from models import EmotionLabel, EMOTION_LABELS, CulturalRegion, EMOTION_EMOJI
37
  from face_detector import FaceEmotionDetector
38
  from text_detector import TextEmotionDetector
39
+ from posture_detector import PostureEmotionDetector
40
  from auth import (
41
  validate_email,
42
  is_email_used,
 
269
  det.load()
270
  return det
271
 
272
+ @st.cache_resource
273
+ def load_posture_detector():
274
+ det = PostureEmotionDetector()
275
+ det.load()
276
+ return det
277
+
278
 
279
  # =====================================================================
280
  # Helper: Render Functions
 
571
  )
572
 
573
  st.markdown("# EMOSPHERE")
574
+ st.markdown("*Real-time multimodal emotion detection -- face, text, posture & gesture*")
575
 
576
  face_det = load_face_detector()
577
  text_det = load_text_detector()
578
+ posture_det = load_posture_detector()
579
 
580
+ tab_camera, tab_text, tab_posture, tab_history = st.tabs([
581
+ "Camera / Image", "Text Analysis", "Posture & Gesture", "History",
582
  ])
583
 
584
  # -- Camera / Image Tab --
 
729
  "text": text_input[:100],
730
  })
731
 
732
+ # -- Posture & Gesture Tab --
733
+ with tab_posture:
734
+ st.markdown("### Posture & Gesture Emotion Detection")
735
+ st.markdown(
736
+ '<p style="color: #6B7B9D; font-size: 13px;">'
737
+ 'Upload a full-body or upper-body image to analyze emotional cues from posture, '
738
+ 'gestures, arm position, shoulder tension, and body language.</p>',
739
+ unsafe_allow_html=True,
740
+ )
741
+
742
+ col_posture_in, col_posture_out = st.columns([1, 1])
743
+
744
+ with col_posture_in:
745
+ posture_method = st.radio(
746
+ "Input method",
747
+ ["Upload Image", "Webcam Snapshot"],
748
+ horizontal=True,
749
+ key="posture_method",
750
+ )
751
+
752
+ posture_data = None
753
+
754
+ if posture_method == "Upload Image":
755
+ posture_uploaded = st.file_uploader(
756
+ "Upload a body image",
757
+ type=["jpg", "jpeg", "png", "webp"],
758
+ key="posture_upload",
759
+ )
760
+ if posture_uploaded:
761
+ posture_data = posture_uploaded.read()
762
+ st.image(posture_data, caption="Uploaded image", use_container_width=True)
763
+ else:
764
+ posture_photo = st.camera_input("Take a photo", key="posture_cam")
765
+ if posture_photo:
766
+ posture_data = posture_photo.read()
767
+
768
+ with col_posture_out:
769
+ if posture_data:
770
+ if is_trial_expired(start):
771
+ st.session_state.auth_stage = "ended"
772
+ st.rerun()
773
+ return
774
+
775
+ with st.spinner("Analyzing posture & gestures..."):
776
+ posture_result = posture_det.detect(
777
+ posture_data,
778
+ CulturalRegion(cultural_region),
779
+ )
780
+
781
+ render_emotion_bubble(posture_result.dominant, posture_result.dominant_score)
782
+ st.markdown(
783
+ '<div class="glass-card">'
784
+ '<div style="color: #6B7B9D; font-size: 12px;">'
785
+ 'Processed in {:.0f}ms'
786
+ ' &bull; Confidence: {:.1f}%'
787
+ ' &bull; Cultural: {}'
788
+ '</div></div>'.format(
789
+ posture_result.processing_time_ms,
790
+ posture_result.confidence * 100,
791
+ CULTURAL_OPTIONS.get(cultural_region, "Universal"),
792
+ ),
793
+ unsafe_allow_html=True,
794
+ )
795
+
796
+ p_scores = {s.label: s.score for s in posture_result.scores}
797
+ render_emotion_bars(p_scores)
798
+
799
+ st.session_state.history.append({
800
+ "time": datetime.now(),
801
+ "modality": "posture",
802
+ "dominant": posture_result.dominant.value,
803
+ "score": posture_result.dominant_score,
804
+ "scores": p_scores,
805
+ })
806
+ else:
807
+ st.markdown(
808
+ '<div class="glass-card" style="text-align: center; padding: 40px;">'
809
+ '<span style="font-size: 48px;">&#129497;</span>'
810
+ '<p style="color: #6B7B9D; margin-top: 12px;">'
811
+ 'Upload a body image or take a webcam snapshot<br/>'
812
+ 'to detect emotions from posture &amp; gestures'
813
+ '</p></div>',
814
+ unsafe_allow_html=True,
815
+ )
816
+
817
  # -- History Tab --
818
  with tab_history:
819
  st.markdown("### Emotion History")
 
847
  for h in reversed(history[-10:]):
848
  emo = EMOTION_EMOJI.get(EmotionLabel(h["dominant"]), "")
849
  color = EMOTION_COLORS.get(EmotionLabel(h["dominant"]), "#94A3B8")
850
+ modality_icon = {"face": "&#128247;", "text": "&#128172;", "posture": "&#129497;"}.get(
851
  h["modality"], "&#128302;"
852
  )
853
  snippet = ""