perborgen commited on
Commit
065fc14
1 Parent(s): c7f04d5

Add project files

Browse files
Files changed (3) hide show
  1. index.html +23 -18
  2. index.js +73 -0
  3. style.css +47 -18
index.html CHANGED
@@ -1,19 +1,24 @@
1
  <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
1
  <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.css">
5
+ <meta charset="UTF-8" />
6
+ <link rel="stylesheet" href="style.css" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <title>Transformers.js - Object Detection demo</title>
9
+ </head>
10
+
11
+ <body>
12
+ <main class="container">
13
+ <label class="custom-file-upload">
14
+ <input id="file-upload" type="file" accept="image/*" />
15
+ <img class="upload-icon" src="https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/upload-icon.png" />
16
+ Upload image
17
+ </label>
18
+ <div id="image-container"></div>
19
+ <p id="status"></p>
20
+ </main>
21
+ <script src="./index.js" type="module"></script>
22
+ </body>
23
+
24
+ </html>
index.js ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { pipeline, env } from 'https://cdn.jsdelivr.net/npm/@xenova/[email protected]';
2
+
3
+ // Since we will download the model from the Hugging Face Hub, we can skip the local model check
4
+ env.allowLocalModels = false;
5
+
6
+ // Reference the elements that we will need
7
+ const status = document.getElementById('status');
8
+ const fileUpload = document.getElementById('file-upload');
9
+ const imageContainer = document.getElementById('image-container');
10
+
11
+ // Create a new object detection pipeline
12
+ status.textContent = 'Loading model...';
13
+ const detector = await pipeline('object-detection', 'Xenova/detr-resnet-50');
14
+ status.textContent = 'Ready';
15
+
16
+ fileUpload.addEventListener('change', function (e) {
17
+ const file = e.target.files[0];
18
+ if (!file) {
19
+ return;
20
+ }
21
+
22
+ const reader = new FileReader();
23
+
24
+ // Set up a callback when the file is loaded
25
+ reader.onload = function (e2) {
26
+ imageContainer.innerHTML = '';
27
+ const image = document.createElement('img');
28
+ image.src = e2.target.result;
29
+ imageContainer.appendChild(image);
30
+ detect(image);
31
+ };
32
+ reader.readAsDataURL(file);
33
+ });
34
+
35
+
36
+ // Detect objects in the image
37
+ async function detect(img) {
38
+ status.textContent = 'Analysing...';
39
+ const output = await detector(img.src, {
40
+ threshold: 0.5,
41
+ percentage: true,
42
+ });
43
+ status.textContent = '';
44
+ output.forEach(renderBox);
45
+ }
46
+
47
+ // Render a bounding box and label on the image
48
+ function renderBox({ box, label }) {
49
+ const { xmax, xmin, ymax, ymin } = box;
50
+
51
+ // Generate a random color for the box
52
+ const color = '#' + Math.floor(Math.random() * 0xFFFFFF).toString(16).padStart(6, 0);
53
+
54
+ // Draw the box
55
+ const boxElement = document.createElement('div');
56
+ boxElement.className = 'bounding-box';
57
+ Object.assign(boxElement.style, {
58
+ borderColor: color,
59
+ left: 100 * xmin + '%',
60
+ top: 100 * ymin + '%',
61
+ width: 100 * (xmax - xmin) + '%',
62
+ height: 100 * (ymax - ymin) + '%',
63
+ });
64
+
65
+ // Draw label
66
+ const labelElement = document.createElement('span');
67
+ labelElement.textContent = label;
68
+ labelElement.className = 'bounding-box-label';
69
+ labelElement.style.backgroundColor = color;
70
+
71
+ boxElement.appendChild(labelElement);
72
+ imageContainer.appendChild(boxElement);
73
+ }
style.css CHANGED
@@ -1,28 +1,57 @@
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
 
 
 
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ html,
2
  body {
3
+ font-family: Arial, Helvetica, sans-serif;
 
4
  }
5
 
6
+ .container {
7
+ margin: 40px auto;
8
+ width: max(50vw, 400px);
9
+ display: flex;
10
+ flex-direction: column;
11
+ align-items: center;
12
  }
13
 
14
+ .custom-file-upload {
15
+ display: flex;
16
+ align-items: center;
17
+ cursor: pointer;
18
+ gap: 10px;
19
+ border: 2px solid black;
20
+ padding: 8px 16px;
21
+ cursor: pointer;
22
+ border-radius: 6px;
23
  }
24
 
25
+ #file-upload {
26
+ display: none;
 
 
 
 
27
  }
28
 
29
+ .upload-icon {
30
+ width: 30px;
31
  }
32
+
33
+ #image-container {
34
+ width: 100%;
35
+ margin-top: 20px;
36
+ position: relative;
37
+ }
38
+
39
+ #image-container>img {
40
+ width: 100%;
41
+ }
42
+
43
+ .bounding-box {
44
+ position: absolute;
45
+ box-sizing: border-box;
46
+ border-width: 2px;
47
+ border-style: solid;
48
+ }
49
+
50
+ .bounding-box-label {
51
+ color: white;
52
+ position: absolute;
53
+ font-size: 12px;
54
+ margin-top: -16px;
55
+ margin-left: -2px;
56
+ padding: 1px;
57
+ }