Clemenz88 commited on
Commit
cbd7eaa
·
verified ·
1 Parent(s): 34733a7

Upload 5 files

Browse files
Files changed (5) hide show
  1. app.py +27 -36
  2. utils/image_utils.py +13 -0
  3. utils/matcher.py +2 -11
  4. utils/model.py +19 -0
  5. utils/placeholder.py +1 -0
app.py CHANGED
@@ -1,50 +1,41 @@
1
 
2
  import streamlit as st
3
- from PIL import Image
4
- from transformers import AutoImageProcessor, AutoModelForImageClassification
5
- import torch
6
- import requests
7
- from utils.matcher import oversaet_fuzzy
8
 
9
  @st.cache_resource
10
- def load_model():
11
- processor = AutoImageProcessor.from_pretrained("timm/food101-vit-base-patch16-224")
12
- model = AutoModelForImageClassification.from_pretrained("timm/food101-vit-base-patch16-224")
13
- return processor, model
14
 
15
- processor, model = load_model()
16
 
17
- st.title("Kalorieestimat og Fødevareklassificering")
18
  uploaded_file = st.file_uploader("Upload et billede", type=["jpg", "jpeg", "png"])
19
- confidence_threshold = 0.7
 
 
20
 
21
- if uploaded_file is not None:
22
- image = Image.open(uploaded_file).convert("RGB")
23
- st.image(image, caption="Uploadet billede", use_column_width=True)
 
24
 
25
- inputs = processor(images=image, return_tensors="pt")
26
- with torch.no_grad():
27
- outputs = model(**inputs)
28
- logits = outputs.logits
29
- predicted_class_idx = logits.argmax(-1).item()
30
- confidence = torch.softmax(logits, dim=-1)[0][predicted_class_idx].item()
31
 
32
- label = model.config.id2label[predicted_class_idx]
33
- label_dk = oversaet_fuzzy(label)
34
 
35
- st.markdown(f"**Modelgæt:** {label} ({confidence*100:.1f}%)")
36
- st.markdown(f"**Oversat (fuzzy):** {label_dk}")
 
37
 
38
- if confidence < confidence_threshold:
39
- manual = st.selectbox("Modellen er usikker – vælg manuelt fødevaretype:", options=["æg", "kartofler", "smør", "broccoli"])
40
- st.markdown(f"**Manuelt valg:** {manual}")
 
41
 
42
- feedback = st.text_input("Har du feedback eller en mere præcis betegnelse?")
43
- if feedback:
44
  st.success("Tak for din feedback!")
45
-
46
- st.subheader("Eksempel på fødevareanalyse:")
47
- st.markdown("- 100 g æg
48
- - 200 g kartofler
49
- - 50 g smør
50
- - 25 g broccoli")
 
1
 
2
  import streamlit as st
3
+ from utils.image_utils import load_image, detect_hand_and_food_area
4
+ from utils.model import load_model, classify_food
5
+ from utils.matcher import oversæt_fuzzy
 
 
6
 
7
  @st.cache_resource
8
+ def load_model_cached():
9
+ return load_model()
 
 
10
 
11
+ st.title("Kalorieestimering fra billede")
12
 
 
13
  uploaded_file = st.file_uploader("Upload et billede", type=["jpg", "jpeg", "png"])
14
+ if uploaded_file:
15
+ image = load_image(uploaded_file)
16
+ st.image(image, caption="Dit billede", use_column_width=True)
17
 
18
+ with st.spinner("Analyserer billede..."):
19
+ hand_img, food_area = detect_hand_and_food_area(image)
20
+ processor, model = load_model_cached()
21
+ prediction, confidence = classify_food(food_area, processor, model)
22
 
23
+ if confidence < 0.7:
24
+ st.warning("Modelen er ikke sikker – vælg manuelt:")
25
+ prediction = st.selectbox("Vælg fødevare", ["æg", "kartoffel", "smør", "broccoli"])
26
+ else:
27
+ st.success(f"Modelen gættede: {prediction} ({confidence*100:.1f}%)")
 
28
 
29
+ gram = st.number_input(f"Hvor mange gram {prediction}?", min_value=1, max_value=1000, value=100)
 
30
 
31
+ # Analyse
32
+ st.markdown("### Analyse af måltid:")
33
+ st.markdown(f"- {gram} g {prediction}")
34
 
35
+ # Feedback
36
+ st.markdown("### Giv feedback")
37
+ feedback = st.radio("Er gættet korrekt?", ["Ja", "Nej"])
38
+ kommentar = st.text_input("Evt. kommentar")
39
 
40
+ if st.button("Send feedback"):
 
41
  st.success("Tak for din feedback!")
 
 
 
 
 
 
utils/image_utils.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import cv2
3
+ import numpy as np
4
+ from PIL import Image
5
+
6
+ def load_image(uploaded_file):
7
+ image = Image.open(uploaded_file).convert("RGB")
8
+ return np.array(image)
9
+
10
+ def detect_hand_and_food_area(image_np):
11
+ # Dummy crop for demo
12
+ height, width, _ = image_np.shape
13
+ return image_np[0:height//2, :], image_np[height//2:, :]
utils/matcher.py CHANGED
@@ -1,12 +1,3 @@
1
 
2
- def oversaet_fuzzy(label):
3
- oversaettelser = {
4
- "mashed_potato": "kartoffelmos",
5
- "omelette": "æg",
6
- "broccoli": "broccoli",
7
- "butter": "smør",
8
- "french_fries": "pommes frites",
9
- "pizza": "pizza",
10
- "sushi": "sushi"
11
- }
12
- return oversaettelser.get(label.lower(), f"(ukendt: {label})")
 
1
 
2
+ def oversæt_fuzzy(tekst):
3
+ return tekst # dummy placeholder
 
 
 
 
 
 
 
 
 
utils/model.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from transformers import AutoImageProcessor, AutoModelForImageClassification
3
+ import torch
4
+
5
+ def load_model():
6
+ processor = AutoImageProcessor.from_pretrained("microsoft/beit-base-patch16-224")
7
+ model = AutoModelForImageClassification.from_pretrained("microsoft/beit-base-patch16-224")
8
+ return processor, model
9
+
10
+ def classify_food(image, processor, model):
11
+ from PIL import Image
12
+ import numpy as np
13
+ inputs = processor(images=Image.fromarray(np.array(image)), return_tensors="pt")
14
+ with torch.no_grad():
15
+ logits = model(**inputs).logits
16
+ predicted_class_idx = logits.argmax(-1).item()
17
+ label = model.config.id2label[predicted_class_idx]
18
+ confidence = logits.softmax(dim=-1)[0, predicted_class_idx].item()
19
+ return label, confidence
utils/placeholder.py ADDED
@@ -0,0 +1 @@
 
 
1
+ # Placeholder for utils