Clemenz88 commited on
Commit
2ad6644
·
verified ·
1 Parent(s): 58c5e94

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +33 -35
  2. kaloriedata.csv +9 -13
  3. requirements.txt +1 -1
  4. utils/matcher.py +4 -4
app.py CHANGED
@@ -1,54 +1,52 @@
1
  import streamlit as st
2
  from PIL import Image
3
- import pandas as pd
4
  import torch
5
  from transformers import AutoFeatureExtractor, AutoModelForImageClassification
6
- from utils.matcher import oversæt_fuzzy
 
7
 
8
  @st.cache_resource
9
  def load_model():
10
- extractor = AutoFeatureExtractor.from_pretrained("nateraw/food101")
11
- model = AutoModelForImageClassification.from_pretrained("nateraw/food101")
12
  return extractor, model
13
 
14
  extractor, model = load_model()
15
- df = pd.read_csv("kaloriedata.csv")
16
- food_list = df["navn"].tolist()
 
 
17
 
18
- st.title("🥗 Kalorieestimering via billede")
19
 
20
- uploaded_file = st.file_uploader("Upload billede", type=["jpg", "jpeg", "png"])
21
- if uploaded_file:
22
- img = Image.open(uploaded_file).convert("RGB")
23
- st.image(img, caption="Dit billede", use_container_width=True)
24
 
25
  inputs = extractor(images=img, return_tensors="pt")
26
  with torch.no_grad():
27
  logits = model(**inputs).logits
28
  probs = torch.nn.functional.softmax(logits, dim=-1)
29
- confidence, pred_class = torch.max(probs, dim=1)
30
- label = model.config.id2label[pred_class.item()]
31
- conf_value = confidence.item()
32
 
33
- st.markdown(f"🔍 Modelgæt: `{label}` ({conf_value:.0%} sikkerhed)")
34
- if conf_value < 0.7:
35
- selected = st.selectbox("Modellen er usikker – vælg korrekt fødevare:", food_list)
36
- else:
37
- selected = oversæt_fuzzy(label.replace("_", " "), food_list)
38
-
39
- st.write(f"✅ Bruges som: **{selected}**")
40
- row = df[df["navn"] == selected]
41
- if not row.empty:
42
- kcal_100 = row["kcal_pr_100g"].values[0]
43
- vægt = 150 # dummy estimeret vægt
44
- kcal = vægt * kcal_100 / 100
45
- st.success(f"{vægt} g {selected} → {kcal:.0f} kcal")
46
-
47
- # Feedback
48
- user_feedback = st.text_input("Tilføj kommentar eller rettelse (valgfrit)")
49
- if st.button("Send feedback"):
50
- with open("feedback_log.csv", "a") as f:
51
- f.write(f"{label},{selected},{conf_value:.2f},{user_feedback}\n")
52
- st.info("✅ Feedback sendt. Tak!")
53
  else:
54
- st.warning("⚠️ Ukendt fødevare.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  from PIL import Image
 
3
  import torch
4
  from transformers import AutoFeatureExtractor, AutoModelForImageClassification
5
+ import pandas as pd
6
+ from utils.matcher import fuzzy_match
7
 
8
  @st.cache_resource
9
  def load_model():
10
+ extractor = AutoFeatureExtractor.from_pretrained("nateraw/food-classification")
11
+ model = AutoModelForImageClassification.from_pretrained("nateraw/food-classification")
12
  return extractor, model
13
 
14
  extractor, model = load_model()
15
+ data = pd.read_csv("kaloriedata.csv")
16
+ madliste = data["navn"].tolist()
17
+
18
+ st.title("🍽️ WebKalorier – Madanalyse")
19
 
20
+ uploaded = st.file_uploader("Upload et billede", type=["jpg", "jpeg", "png"])
21
 
22
+ if uploaded:
23
+ img = Image.open(uploaded).convert("RGB")
24
+ st.image(img, caption="Uploadet billede", use_container_width=True)
 
25
 
26
  inputs = extractor(images=img, return_tensors="pt")
27
  with torch.no_grad():
28
  logits = model(**inputs).logits
29
  probs = torch.nn.functional.softmax(logits, dim=-1)
30
+ score, class_id = torch.max(probs, dim=1)
31
+ label = model.config.id2label[class_id.item()]
32
+ confidence = score.item()
33
 
34
+ st.markdown(f"🤖 Modelgæt: `{label}` med {confidence:.0%} sikkerhed")
35
+
36
+ if confidence < 0.7:
37
+ valgt = st.selectbox("Vælg fødevare manuelt:", madliste)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  else:
39
+ valgt = fuzzy_match(label, madliste)
40
+
41
+ gram = st.number_input("Estimeret mængde (g):", 1, 1000, 150)
42
+ række = data[data["navn"] == valgt]
43
+ if not række.empty:
44
+ kcal100 = række["kcal_pr_100g"].values[0]
45
+ samlet = round(kcal100 * gram / 100)
46
+ st.success(f"{gram} g {valgt} = {samlet} kcal")
47
+
48
+ feedback = st.text_input("Feedback / korrektion:")
49
+ if st.button("Send feedback"):
50
+ with open("feedback_log.txt", "a") as f:
51
+ f.write(f"{label},{valgt},{confidence:.2f},{feedback}\n")
52
+ st.info("Tak for din feedback! 🙏")
kaloriedata.csv CHANGED
@@ -1,20 +1,16 @@
1
  navn,kcal_pr_100g
2
  salat,15
3
  tomat,18
 
4
  pasta,131
5
- ost,350
6
- kød,250
7
- laks,210
8
- burger,280
9
  æg,155
10
- ris,130
11
- brød,260
12
- pizza,270
13
- gulerod,41
14
- æble,52
15
- appelsin,47
16
- pommes frites,290
17
  smør,717
18
- kartofler,77
19
  broccoli,35
20
- kylling,239
 
 
 
 
 
 
1
  navn,kcal_pr_100g
2
  salat,15
3
  tomat,18
4
+ ris,130
5
  pasta,131
6
+ kylling,239
 
 
 
7
  æg,155
 
 
 
 
 
 
 
8
  smør,717
9
+ kartoffel,77
10
  broccoli,35
11
+ laks,210
12
+ oksekød,250
13
+ gulerod,41
14
+ pizza,270
15
+ burger,280
16
+ brød,260
requirements.txt CHANGED
@@ -1,7 +1,7 @@
1
  streamlit
 
2
  torch
3
  transformers
4
- pillow
5
  pandas
6
  fuzzywuzzy
7
  python-Levenshtein
 
1
  streamlit
2
+ pillow
3
  torch
4
  transformers
 
5
  pandas
6
  fuzzywuzzy
7
  python-Levenshtein
utils/matcher.py CHANGED
@@ -1,6 +1,6 @@
1
  from fuzzywuzzy import process
2
 
3
- def oversæt_fuzzy(navn, kandidater):
4
- navn = navn.lower()
5
- result = process.extractOne(navn, kandidater, score_cutoff=70)
6
- return result[0] if result else navn
 
1
  from fuzzywuzzy import process
2
 
3
+ def fuzzy_match(label, liste):
4
+ label = label.replace("_", " ").lower()
5
+ match, score = process.extractOne(label, liste)
6
+ return match if score > 70 else label