Arsala Grey commited on
Commit
3529c31
1 Parent(s): 7e2f64e

added loading and sorted detected objects

Browse files
Files changed (2) hide show
  1. index.html +26 -16
  2. index.js +35 -9
index.html CHANGED
@@ -1,34 +1,44 @@
1
-
2
  <!DOCTYPE html>
3
  <html>
4
  <head>
5
  <meta charset="utf-8" />
6
  <meta name="viewport" content="width=device-width" />
7
  <title>Image Object Detection - HuggingFace.js Live Examples</title>
8
- <link rel="stylesheet" href="/utils.css" />
9
  <link rel="stylesheet" href="/pico.classless.min.css" />
 
10
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
11
  </head>
12
  <body>
13
  <div id="generate-text-stream-app" class="container">
14
  <h1>Detect Objects In Images</h1>
15
- <label for="hf-token">Hugging Face Token</label>
16
- <input id="hf-token" v-model="token" placeholder="HF-TOKEN" type="password" />
17
- <label for="model-select">Select a model</label>
18
- <select id="model-select" v-model="selectedModel" >
19
- <option v-for="model in models" :value="model">
20
- {{ model }}
21
- </option>
22
- </select>
23
- <label for="current-image">Current Image</label>
24
- <div class="image-container">
25
- <img :src="imageUrl" id="current-image" />
26
- </div>
27
  <div class="grid grid-cols-2 gap-2">
28
- <button class="btn-info" @click="shuffle">SHUFFLE</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  <button class="btn-success" @click="run">DETECT OBJECTS</button>
30
  </div>
31
- <h2>Result</h2>
 
 
 
 
 
32
  </div>
33
  <script type="module" src="./index.js"></script>
34
  </body>
 
 
1
  <!DOCTYPE html>
2
  <html>
3
  <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width" />
6
  <title>Image Object Detection - HuggingFace.js Live Examples</title>
 
7
  <link rel="stylesheet" href="/pico.classless.min.css" />
8
+ <link rel="stylesheet" href="/main.css" />
9
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
10
  </head>
11
  <body>
12
  <div id="generate-text-stream-app" class="container">
13
  <h1>Detect Objects In Images</h1>
 
 
 
 
 
 
 
 
 
 
 
 
14
  <div class="grid grid-cols-2 gap-2">
15
+ <div>
16
+ <label for="hf-token">Hugging Face Token</label>
17
+ <input
18
+ id="hf-token"
19
+ v-model="token"
20
+ placeholder="HF-TOKEN"
21
+ type="password"
22
+ />
23
+ </div>
24
+ <div>
25
+ <label for="model-select">Select a model</label>
26
+ <select id="model-select" v-model="selectedModel">
27
+ <option v-for="model in models" :value="model">{{ model }}</option>
28
+ </select>
29
+ </div>
30
+ </div>
31
+ <div class="grid grid-cols-3 gap-2">
32
+ <button class="btn-info" @click="shuffle">RANDOM IMAGE</button>
33
+ <button class="btn-gray" @click="upload">UPLOAD IMAGE</button>
34
  <button class="btn-success" @click="run">DETECT OBJECTS</button>
35
  </div>
36
+ <h2>{{statusMessage}}</h2>
37
+ <div class="image-container">
38
+ <div id="image-wrapper">
39
+ <img :src="imageUrl" id="current-image" />
40
+ </div>
41
+ </div>
42
  </div>
43
  <script type="module" src="./index.js"></script>
44
  </body>
index.js CHANGED
@@ -1,11 +1,11 @@
1
- const { createApp, ref, onMounted } = Vue;
2
  import { HfInference } from "https://cdn.skypack.dev/@huggingface/inference@latest";
3
 
4
  const getRandomImageUrl = async () => {
5
  const randomImageRequest = await fetch("https://source.unsplash.com/random/640x480")
6
  return randomImageRequest.url
7
  }
8
- const ObjectDatectionModels = ["facebook/detr-resnet-50"]
9
 
10
  const getImageBuffer = async (imageUrl) => {
11
  const imageRequest = await fetch(imageUrl)
@@ -22,6 +22,8 @@ const drawDetectedObjects = (img, detections) => {
22
  container.style.height = `${img.height}px`;
23
  img.parentNode.insertBefore(container, img);
24
 
 
 
25
  detections.forEach(detection => {
26
  const { xmin, ymin, xmax, ymax } = detection.box;
27
  const label = detection.label;
@@ -39,18 +41,33 @@ const drawDetectedObjects = (img, detections) => {
39
  tooltip.innerText = `${label}: ${confidence}`;
40
  box.appendChild(tooltip);
41
 
42
- container.appendChild(box);
43
  });
 
 
 
 
 
 
44
  };
45
  const app = createApp({
46
  setup() {
47
  const token = ref(localStorage.getItem("token") || "");
48
- const models = ref(ObjectDatectionModels);
49
  const selectedModel = ref("");
50
  const imageUrl = ref("");
51
  const detectedObjects = ref([]);
 
 
 
 
 
 
 
 
52
 
53
  const run = async () => {
 
54
  try {
55
  const hf = new HfInference(token.value);
56
  const imageData = await getImageBuffer(imageUrl.value);
@@ -58,18 +75,25 @@ const app = createApp({
58
  data: imageData,
59
  model: selectedModel.value,
60
  });
61
- console.log(result);
62
  detectedObjects.value = result
63
  drawDetectedObjects(document.getElementById('current-image'), result)
 
 
64
  } catch (e) {
65
- console.log(e);
 
66
  }
67
  };
68
 
69
- const shuffle = async () => {
70
- imageUrl.value = await getRandomImageUrl()
71
  document.getElementById('detected-objects-container').remove()
72
  document.getElementsByClassName('bounding-box').forEach(box => box.remove())
 
 
 
 
 
 
73
  };
74
 
75
  onMounted(async () => {
@@ -91,7 +115,9 @@ const app = createApp({
91
  shuffle,
92
  models,
93
  selectedModel,
94
- imageUrl
 
 
95
  };
96
  },
97
  });
 
1
+ const { createApp, ref, onMounted, computed } = Vue;
2
  import { HfInference } from "https://cdn.skypack.dev/@huggingface/inference@latest";
3
 
4
  const getRandomImageUrl = async () => {
5
  const randomImageRequest = await fetch("https://source.unsplash.com/random/640x480")
6
  return randomImageRequest.url
7
  }
8
+ const ObjectDetectionModels = ["facebook/detr-resnet-50", "hustvl/yolos-tiny", "facebook/detr-resnet-101"]
9
 
10
  const getImageBuffer = async (imageUrl) => {
11
  const imageRequest = await fetch(imageUrl)
 
22
  container.style.height = `${img.height}px`;
23
  img.parentNode.insertBefore(container, img);
24
 
25
+ const detectedObjectBoxes = []
26
+
27
  detections.forEach(detection => {
28
  const { xmin, ymin, xmax, ymax } = detection.box;
29
  const label = detection.label;
 
41
  tooltip.innerText = `${label}: ${confidence}`;
42
  box.appendChild(tooltip);
43
 
44
+ detectedObjectBoxes.push(box)
45
  });
46
+
47
+ detectedObjectBoxes.sort((a, b) => {
48
+ const aSize = a.style.width * a.style.height
49
+ const bSize = b.style.width * b.style.height
50
+ return aSize - bSize
51
+ }).forEach(box => container.appendChild(box))
52
  };
53
  const app = createApp({
54
  setup() {
55
  const token = ref(localStorage.getItem("token") || "");
56
+ const models = ref(ObjectDetectionModels);
57
  const selectedModel = ref("");
58
  const imageUrl = ref("");
59
  const detectedObjects = ref([]);
60
+ const loading = ref(false);
61
+
62
+ const statusMessage = computed(() => {
63
+ if (loading.value) return "Loading...";
64
+ if (detectedObjects.value.length === 0) return "No objects detected";
65
+ if (detectedObjects.value.length === 1) return "1 object detected";
66
+ return `${detectedObjects.value.length} objects detected`;
67
+ })
68
 
69
  const run = async () => {
70
+ loading.value = true;
71
  try {
72
  const hf = new HfInference(token.value);
73
  const imageData = await getImageBuffer(imageUrl.value);
 
75
  data: imageData,
76
  model: selectedModel.value,
77
  });
 
78
  detectedObjects.value = result
79
  drawDetectedObjects(document.getElementById('current-image'), result)
80
+ console.log(detectedObjects.value)
81
+ loading.value = false;
82
  } catch (e) {
83
+ console.error(e);
84
+ loading.value = false;
85
  }
86
  };
87
 
88
+ const reset = () => {
 
89
  document.getElementById('detected-objects-container').remove()
90
  document.getElementsByClassName('bounding-box').forEach(box => box.remove())
91
+ detectedObjects.value = []
92
+ }
93
+
94
+ const shuffle = async () => {
95
+ imageUrl.value = await getRandomImageUrl()
96
+ reset()
97
  };
98
 
99
  onMounted(async () => {
 
115
  shuffle,
116
  models,
117
  selectedModel,
118
+ imageUrl,
119
+ loading,
120
+ statusMessage
121
  };
122
  },
123
  });