prakman commited on
Commit
f5cd4fd
·
verified ·
1 Parent(s): 56b7911

Upload 5 files

Browse files
Files changed (5) hide show
  1. README.md +5 -13
  2. app.py +103 -0
  3. final_rfc.joblib +3 -0
  4. final_rfr.joblib +3 -0
  5. requirements.txt +7 -0
README.md CHANGED
@@ -1,14 +1,6 @@
1
- ---
2
- title: Smartpack Freshness Detector
3
- emoji: 🏆
4
- colorFrom: gray
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.49.1
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- short_description: An AI-powered SmartPack system that detects fish freshness a
12
- ---
13
 
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
1
+ # SmartPack - Mackerel Freshness Detector (Hugging Face Space)
 
 
 
 
 
 
 
 
 
 
 
2
 
3
+ Upload an indicator image get freshness class and TVB-N (demo-level).
4
+
5
+ NOTE:
6
+ TVB-N regressor uses literature/synthetic data → demonstration-only.
app.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os, joblib, numpy as np, pandas as pd, cv2
3
+ from PIL import Image
4
+
5
+ CLASSIFIER_PATH = "models/final_rfc.joblib"
6
+ REGRESSOR_PATH = "models/final_rfr.joblib"
7
+
8
+ FEATURE_COLS = [
9
+ 'mean_R','mean_G','mean_B',
10
+ 'std_R','std_G','std_B',
11
+ 'mean_H','mean_S','mean_V',
12
+ 'std_H','std_S','std_V',
13
+ 'brightness','ratio_R_G','ratio_R_B'
14
+ ]
15
+
16
+ def autocrop(img_pil):
17
+ arr = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
18
+ gray = cv2.cvtColor(arr, cv2.COLOR_BGR2GRAY)
19
+ th = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,21,10)
20
+ kernel = np.ones((5,5), np.uint8)
21
+ th = cv2.morphologyEx(th, cv2.MORPH_CLOSE, kernel)
22
+ cnts,_ = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
23
+ if not cnts:
24
+ return img_pil
25
+ c = max(cnts, key=cv2.contourArea)
26
+ x,y,w,h = cv2.boundingRect(c)
27
+ crop = arr[y:y+h, x:x+w]
28
+ crop = cv2.cvtColor(crop, cv2.COLOR_BGR2RGB)
29
+ return Image.fromarray(crop)
30
+
31
+ def extract_features(pil):
32
+ arr = np.array(pil.convert('RGB'))
33
+ mean_rgb = arr.mean(axis=(0,1))
34
+ std_rgb = arr.std(axis=(0,1))
35
+ hsv = cv2.cvtColor(arr, cv2.COLOR_RGB2HSV)
36
+ mean_hsv = hsv.mean(axis=(0,1))
37
+ std_hsv = hsv.std(axis=(0,1))
38
+ R,G,B = mean_rgb
39
+ brightness = 0.299*R + 0.587*G + 0.114*B
40
+ ratio_R_G = R/(G+1e-6)
41
+ ratio_R_B = R/(B+1e-6)
42
+ feats = {
43
+ 'mean_R': float(R), 'mean_G': float(G), 'mean_B': float(B),
44
+ 'std_R': float(std_rgb[0]), 'std_G': float(std_rgb[1]), 'std_B': float(std_rgb[2]),
45
+ 'mean_H': float(mean_hsv[0]), 'mean_S': float(mean_hsv[1]), 'mean_V': float(mean_hsv[2]),
46
+ 'std_H': float(std_hsv[0]), 'std_S': float(std_hsv[1]), 'std_V': float(std_hsv[2]),
47
+ 'brightness': float(brightness),
48
+ 'ratio_R_G': float(ratio_R_G), 'ratio_R_B': float(ratio_R_B)
49
+ }
50
+ return feats
51
+
52
+ clf = None
53
+ rfr = None
54
+ try:
55
+ if os.path.exists(CLASSIFIER_PATH):
56
+ clf = joblib.load(CLASSIFIER_PATH)
57
+ except Exception as e:
58
+ print('Error loading classifier:', e)
59
+
60
+ try:
61
+ if os.path.exists(REGRESSOR_PATH):
62
+ rfr = joblib.load(REGRESSOR_PATH)
63
+ except Exception as e:
64
+ print('Error loading regressor:', e)
65
+
66
+ def predict(img):
67
+ if img is None:
68
+ return "No image uploaded", None, None
69
+ cropped = autocrop(img)
70
+ feats = extract_features(cropped)
71
+ X = pd.DataFrame([feats])[FEATURE_COLS]
72
+
73
+ cls_pred = "Classifier not found"
74
+ tvb = None
75
+
76
+ try:
77
+ if clf is not None:
78
+ cls_pred = str(clf.predict(X)[0])
79
+ except Exception as e:
80
+ cls_pred = f"Error: {e}"
81
+
82
+ try:
83
+ if rfr is not None:
84
+ tvb = float(rfr.predict(X)[0])
85
+ except:
86
+ tvb = None
87
+
88
+ return cls_pred, tvb, cropped
89
+
90
+ demo = gr.Interface(
91
+ fn=predict,
92
+ inputs=gr.Image(type="pil", label="Upload indicator image"),
93
+ outputs=[
94
+ gr.Textbox(label="Freshness class"),
95
+ gr.Number(label="Estimated TVB-N (mg/100g)"),
96
+ gr.Image(label="Cropped indicator")
97
+ ],
98
+ title="SmartPack — Mackerel Freshness Detector",
99
+ description="Upload an indicator image to classify freshness and estimate amine concentration."
100
+ )
101
+
102
+ if __name__ == "__main__":
103
+ demo.launch(server_name="0.0.0.0", server_port=7860)
final_rfc.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ff7da957060eb606316334da5fcd8ea99cf85f1f5ffc3b08dbd73c65194b6e26
3
+ size 577969
final_rfr.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:11d3b924e716d419c863ff7aec6cf88795423deac3efd8997a2978e5c2e01cbf
3
+ size 128625
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio==3.40.1
2
+ opencv-python-headless
3
+ numpy
4
+ pandas
5
+ joblib
6
+ Pillow
7
+ scikit-learn