Spaces:
Running
Running
File size: 3,285 Bytes
b72c906 a76bb3d 9d31a14 976fba6 a76bb3d 9d31a14 180a7d9 9d31a14 180a7d9 9d31a14 a76bb3d 75ef24f a76bb3d 9d31a14 422e9a8 a76bb3d 75ef24f a4b10d7 75ef24f b5d1004 b8a9903 75ef24f b72c906 75ef24f 9d31a14 b8a9903 75ef24f 9d31a14 a76bb3d 9d31a14 a76bb3d 9d31a14 a76bb3d 9d31a14 a76bb3d ccfd95d a76bb3d |
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 |
import { env, AutoProcessor, AutoModel, RawImage } from 'https://cdn.jsdelivr.net/npm/@xenova/transformers@2.15.1';
// Since we will download the model from the Hugging Face Hub, we can skip the local model check
env.allowLocalModels = false;
// Reference the elements that we will need
const status = document.getElementById('status');
const fileUpload = document.getElementById('upload');
const imageContainer = document.getElementById('container');
const example = document.getElementById('example');
const EXAMPLE_URL = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/city-streets.jpg';
const THRESHOLD = 0.25;
// Create a new object detection pipeline
status.textContent = 'Loading model...';
const processor = await AutoProcessor.from_pretrained('Xenova/yolov9-c_all');
// For this demo, we resize the image so that its shortest edge is 256px
processor.feature_extractor.size = { shortest_edge: 256 }
const model = await AutoModel.from_pretrained('Xenova/yolov9-c_all');
status.textContent = 'Ready';
example.addEventListener('click', (e) => {
e.preventDefault();
detect(EXAMPLE_URL);
});
fileUpload.addEventListener('change', function (e) {
const file = e.target.files[0];
if (!file) {
return;
}
const reader = new FileReader();
// Set up a callback when the file is loaded
reader.onload = e2 => detect(e2.target.result);
reader.readAsDataURL(file);
});
// Detect objects in the image
async function detect(url) {
// Update UI
imageContainer.innerHTML = '';
// Read image
const image = await RawImage.fromURL(url);
// Set container width and height depending on the image aspect ratio
const ar = image.width / image.height;
const [cw, ch] = (ar > 1) ? [640, 640 / ar] : [640 * ar, 640];
imageContainer.style.width = `${cw}px`;
imageContainer.style.height = `${ch}px`;
imageContainer.style.backgroundImage = `url(${url})`;
status.textContent = 'Analysing...';
// Preprocess image
const inputs = await processor(image);
// Predict bounding boxes
const { outputs } = await model(inputs);
status.textContent = '';
const sizes = inputs.reshaped_input_sizes[0].reverse();
outputs.tolist().forEach(x => renderBox(x, sizes));
}
// Render a bounding box and label on the image
function renderBox([xmin, ymin, xmax, ymax, score, id], [w, h]) {
if (score < THRESHOLD) return; // Skip boxes with low confidence
// Generate a random color for the box
const color = '#' + Math.floor(Math.random() * 0xFFFFFF).toString(16).padStart(6, 0);
// Draw the box
const boxElement = document.createElement('div');
boxElement.className = 'bounding-box';
Object.assign(boxElement.style, {
borderColor: color,
left: 100 * xmin / w + '%',
top: 100 * ymin / h + '%',
width: 100 * (xmax - xmin) / w + '%',
height: 100 * (ymax - ymin) / h + '%',
})
// Draw label
const labelElement = document.createElement('span');
labelElement.textContent = model.config.id2label[id];
labelElement.className = 'bounding-box-label';
labelElement.style.backgroundColor = color;
boxElement.appendChild(labelElement);
imageContainer.appendChild(boxElement);
}
|