File size: 6,640 Bytes
69d8775
4a2ab6a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b25d9f6
4a2ab6a
69d8775
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="theme-color" content="#0d7a62">
  <meta name="description" content="Static browser-side waste image classification with MS-SE-EfficientNet-B0 and ONNX Runtime Web.">
  <title>MS-SE Waste Classifier</title>
  <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <header class="site-header">
    <div class="brand">
      <div class="brand-mark" aria-hidden="true"></div>
      <div>
        <p class="eyebrow">Browser-side waste recognition</p>
        <h1>MS-SE Waste Classifier</h1>
      </div>
    </div>
    <div class="runtime-pill" id="runtimePill" aria-live="polite">
      <span class="status-dot" id="statusDot"></span>
      <span id="runtimeText">Preparing runtime</span>
    </div>
  </header>

  <main class="page-shell">
    <section class="hero-card">
      <div class="hero-copy">
        <p class="kicker">MS-SE-EfficientNet-B0</p>
        <h2>Classify a waste image entirely in your browser.</h2>
        <p>
          Upload one image to obtain a ten-class probability distribution. The model uses
          average, maximum, and standard-deviation channel descriptors with bounded residual attention.
        </p>
        <div class="privacy-note">
          <span aria-hidden="true">🔒</span>
          <span>The selected image remains on this device during inference.</span>
        </div>
      </div>
      <dl class="model-facts" id="modelFacts">
        <div><dt>Input</dt><dd>224 × 224 RGB</dd></div>
        <div><dt>Classes</dt><dd>10</dd></div>
        <div><dt>Parameters</dt><dd>4.234M</dd></div>
        <div><dt>Runtime</dt><dd>WebAssembly</dd></div>
      </dl>
    </section>

    <section class="workspace" aria-label="Image classification workspace">
      <article class="panel upload-panel">
        <div class="panel-heading">
          <div>
            <p class="step-label">Step 1</p>
            <h2>Select an image</h2>
          </div>
          <button class="text-button" id="clearButton" type="button" disabled>Clear</button>
        </div>

        <input id="fileInput" class="visually-hidden" type="file" accept="image/jpeg,image/png,image/webp,image/bmp">
        <label class="drop-zone" id="dropZone" for="fileInput" tabindex="0">
          <div class="upload-icon" aria-hidden="true">
            <svg viewBox="0 0 24 24" role="img">
              <path d="M12 16V4m0 0L7.5 8.5M12 4l4.5 4.5M5 14.5v3A2.5 2.5 0 0 0 7.5 20h9a2.5 2.5 0 0 0 2.5-2.5v-3"/>
            </svg>
          </div>
          <strong>Drop an image here</strong>
          <span>or click to browse</span>
          <small>JPEG, PNG, WebP, or BMP</small>
        </label>

        <div class="preview-wrap hidden" id="previewWrap">
          <img id="imagePreview" alt="Selected waste image preview">
          <div class="image-meta">
            <strong id="fileName"></strong>
            <span id="fileDetails"></span>
          </div>
        </div>

        <button class="primary-button" id="predictButton" type="button" disabled>
          <span id="predictButtonText">Classify image</span>
          <span class="button-spinner hidden" id="buttonSpinner" aria-hidden="true"></span>
        </button>
        <p class="inline-message" id="inputMessage" role="status"></p>
      </article>

      <article class="panel result-panel">
        <div class="panel-heading">
          <div>
            <p class="step-label">Step 2</p>
            <h2>Prediction</h2>
          </div>
          <span class="provider-badge" id="providerBadge">WASM</span>
        </div>

        <div class="empty-result" id="emptyResult">
          <div class="empty-result-icon" aria-hidden="true"></div>
          <h3>Results will appear here</h3>
          <p>Load the model, select an image, and press “Classify image.”</p>
        </div>

        <div class="results hidden" id="results">
          <div class="primary-result">
            <div>
              <p class="result-label">Predicted class</p>
              <h3 id="predictedClass"></h3>
            </div>
            <div class="confidence-ring" id="confidenceRing" aria-label="Prediction confidence">
              <span id="confidenceValue">0%</span>
            </div>
          </div>

          <div class="top-three-wrap">
            <h4>Top three</h4>
            <ol class="top-three" id="topThree"></ol>
          </div>

          <details class="all-probabilities" open>
            <summary>All class probabilities</summary>
            <div class="probability-list" id="probabilityList"></div>
          </details>

          <div class="timing-grid">
            <div><span>Preprocess</span><strong id="preprocessTime"></strong></div>
            <div><span>Inference</span><strong id="inferenceTime"></strong></div>
            <div><span>Total</span><strong id="totalTime"></strong></div>
          </div>
        </div>
      </article>
    </section>

    <section class="status-card" aria-labelledby="modelStatusTitle">
      <div class="status-title-row">
        <div>
          <p class="step-label">Model status</p>
          <h2 id="modelStatusTitle">Runtime initialization</h2>
        </div>
        <strong id="loadPercent">0%</strong>
      </div>
      <div class="progress-track" aria-hidden="true">
        <div class="progress-bar" id="progressBar"></div>
      </div>
      <p id="statusDetail" aria-live="polite">Loading ONNX Runtime Web…</p>
    </section>

    <section class="information-grid">
      <article class="info-card">
        <h2>Supported classes</h2>
        <div class="class-chips" id="classChips"></div>
      </article>
      <article class="info-card">
        <h2>Notebook-matched preprocessing</h2>
        <p>Direct resize to 224 × 224, RGB conversion, scaling to [0,1], and ImageNet normalization.</p>
      </article>
      <article class="info-card caution-card">
        <h2>Research use</h2>
        <p>Visual ambiguity remains possible, especially among related packaging materials and general trash.</p>
      </article>
    </section>
  </main>

  <footer>
    <p>Static ONNX inference · MS-SE-EfficientNet-B0 · Ten waste classes</p>
  </footer>

  <canvas id="preprocessCanvas" width="224" height="224" class="visually-hidden" aria-hidden="true"></canvas>

  <script src="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.27.0/dist/ort.min.js" crossorigin="anonymous"></script>
  <script src="app.js?v=20260802-2"></script>
</body>
</html>