Spaces:
Running
Running
Download index.html from sh5959/Photo_classifier: direct link, hf CLI and curl.
- Browser
- Download file 11.6 kB
-
https://huggingface.co/spaces/sh5959/Photo_classifier/resolve/main/index.html
- Command line
-
hf download hf://spaces/sh5959/Photo_classifier/index.html
-
curl -L -o index.html https://huggingface.co/spaces/sh5959/Photo_classifier/resolve/main/index.html
11.6 kB
| <html lang="ko"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <!-- โ ์์ ํ ๋ถ๋ถ: ๋ด ๋ฐ๋ชจ์ ์ ๋ชฉ --> | |
| <title>StreetCLIP ์ฌ์ง์ผ๋ก ๊ตญ๊ฐ ๋งํ๊ธฐ</title> | |
| <style> | |
| body { | |
| font-family: "๋ง์ ๊ณ ๋", sans-serif; | |
| max-width: 720px; | |
| margin: 24px auto; | |
| padding: 0 16px; | |
| color: #202124; | |
| } | |
| h1 { font-size: 24px; margin-bottom: 4px; } | |
| .sub { color: #5f6368; margin-top: 0; } | |
| #status { | |
| display: block; | |
| margin: 12px 0; | |
| padding: 8px 12px; | |
| background: #f1f3f4; | |
| border-radius: 6px; | |
| } | |
| #preview { | |
| max-width: 100%; | |
| max-height: 320px; | |
| display: none; | |
| margin: 12px 0; | |
| border-radius: 6px; | |
| } | |
| .row { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| margin: 4px 0; | |
| } | |
| .name { | |
| width: 90px; | |
| flex-shrink: 0; | |
| font-size: 14px; | |
| } | |
| .track { | |
| flex: 1; | |
| background: #e8edf5; | |
| border-radius: 3px; | |
| } | |
| /* โ ์์ ํ ๋ถ๋ถ: ๋ง๋ ์์์ ํ๋์์ผ๋ก ๋ณ๊ฒฝ */ | |
| .bar { | |
| height: 14px; | |
| background: #2563eb; | |
| border-radius: 3px; | |
| } | |
| .score { font-size: 13px; color: #5f6368; } | |
| button { padding: 6px 14px; } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- โ ์์ ํ ๋ถ๋ถ: ๊ตญ๊ฐ ํ๋ณด๋ฅผ ๋น๊ตํ๋ ๋ฐ๋ชจ๋ก ๋ณ๊ฒฝ --> | |
| <h1>์ฌ์ง์ผ๋ก ๊ตญ๊ฐ ๋งํ๊ธฐ</h1> | |
| <p class="sub"> | |
| ๊ฑฐ๋ฆฌยทํ๊ฒฝ ์ฌ์ง์ ์ฌ๋ฆฌ๊ณ , ์ด๋ ๋๋ผ์ ๊ฐ์ฅ ๋น์ทํ์ง ํ์ธํด ๋ณด์ธ์. | |
| </p> | |
| <p>101๊ฐ ๊ตญ๊ฐยท์ง์ญ์ ๋น๊ตํด ์์ 5๊ฐ ํ๋ณด๋ฅผ ๋ณด์ฌ ์ค๋๋ค.</p> | |
| <p> | |
| ์ ์๋ ์ ์ฒด 101๊ฐ ํ๋ณด ์ฌ์ด์ ์๋์ ์ธ ์์ธก ์ ์์ด๋ฉฐ, | |
| ์์ 5๊ฐ์ ํฉ์ 100%๊ฐ ์๋ ์ ์์ต๋๋ค. | |
| ์ค์ ์ ๋ต๋ฅ ์ด๋ ์ ํํ ์ดฌ์ ์์น๊ฐ ์๋๋๋ค. | |
| </p> | |
| <details> | |
| <summary>๋น๊ต ํ๋ณด 101๊ฐ ๋ณด๊ธฐ</summary> | |
| <p id="countryList"></p> | |
| </details> | |
| <p class="sub"> | |
| ๋ ผ๋ฌธ ๋ถ๋ก์ ๋์ด๋ 92๊ฐ ๊ตญ๊ฐยท์ง์ญ์ 9๊ฐ ๊ตญ๊ฐ๋ฅผ ์ถ๊ฐํ ๋น๊ต ๋ชฉ๋ก์ ๋๋ค. | |
| ์ ํํ ํ์ต ๊ตญ๊ฐ ๋ชฉ๋ก์ ์๋๋ฉฐ, | |
| ํ๋ณด ๋ฐ ์ง์ญ์ ์ฌ์ง๋ ์ด ์ค ํ๋๋ก ๋์ฌ ์ ์์ต๋๋ค. | |
| </p> | |
| <!-- โ ์์ ํ ๋ถ๋ถ: ๋ชจ๋ธ ์ค๋น ์ ์๋ ์ ๋ ฅ์ ๋นํ์ฑํ --> | |
| <input | |
| id="upload" | |
| type="file" | |
| accept="image/*" | |
| aria-label="๋ถ๋ฅํ ์ฌ์ง ์ ํ" | |
| disabled | |
| /> | |
| <button id="example" disabled>์์ ๊ฑฐ๋ฆฌ ์ฌ์ง์ผ๋ก ํด ๋ณด๊ธฐ</button> | |
| <span id="status" role="status"> | |
| ๋ชจ๋ธ ๋ถ๋ฌ์ค๋ ์ค... | |
| ์ฒ์์๋ ์ฝ 434MB์ ๋ชจ๋ธ์ ๋ฐ์ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์์ต๋๋ค. | |
| </span> | |
| <img id="preview" alt="๋ถ๋ฅํ ์ฌ์ง" /> | |
| <div id="result"></div> | |
| <p class="sub"> | |
| ์์ ์ฌ์ง: ๋ชจ๋ธ ์ ์์๊ฐ ๊ณต๊ฐํ ์ํ๋์์ค์ฝ ์ฌ์ง. | |
| ๊ฒฐ๊ณผ๋ ์คํ ํ ํ์ธํ์ธ์. | |
| </p> | |
| <p class="sub"> | |
| ๋ชจ๋ธ: | |
| <a href="https://huggingface.co/onnx-community/StreetCLIP-ONNX"> | |
| StreetCLIP ONNX | |
| </a> | |
| ยท ์๋ณธ: | |
| <a href="https://huggingface.co/geolocal/StreetCLIP"> | |
| geolocal/StreetCLIP | |
| </a> | |
| ยท | |
| <a href="https://creativecommons.org/licenses/by-nc/4.0/"> | |
| CC BY-NC 4.0 | |
| </a> | |
| </p> | |
| <script type="module"> | |
| import { pipeline } from "https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.7.6"; | |
| // โ ์์ ํ ๋ถ๋ถ: ์ฌ์ง๊ณผ ๊ตญ๊ฐ ์ด๋ฆ์ ๋น๊ตํ๋ ๋ชจ๋ธ | |
| const TASK = "zero-shot-image-classification"; | |
| const MODEL_NAME = "onnx-community/StreetCLIP-ONNX"; | |
| const EXAMPLE_URL = "https://huggingface.co/geolocal/StreetCLIP/resolve/main/sanfrancisco.jpeg"; | |
| // โ ์์ ํ ๋ถ๋ถ: ๋ชจ๋ธ์๋ ์์ด ์ด๋ฆ, ํ๋ฉด์๋ ํ๊ตญ์ด ์ด๋ฆ ์ฌ์ฉ | |
| const countries = { | |
| "Albania": "์๋ฐ๋์", | |
| "Andorra": "์๋๋ผ", | |
| "Argentina": "์๋ฅดํจํฐ๋", | |
| "Australia": "ํธ์ฃผ", | |
| "Austria": "์ค์คํธ๋ฆฌ์", | |
| "Bangladesh": "๋ฐฉ๊ธ๋ผ๋ฐ์", | |
| "Belgium": "๋ฒจ๊ธฐ์", | |
| "Bermuda": "๋ฒ๋ฎค๋ค", | |
| "Bhutan": "๋ถํ", | |
| "Bolivia": "๋ณผ๋ฆฌ๋น์", | |
| "Botswana": "๋ณด์ธ ์๋", | |
| "Brazil": "๋ธ๋ผ์ง", | |
| "Bulgaria": "๋ถ๊ฐ๋ฆฌ์", | |
| "Cambodia": "์บ๋ณด๋์", | |
| "Canada": "์บ๋๋ค", | |
| "Chile": "์น ๋ ", | |
| "China": "์ค๊ตญ", | |
| "Colombia": "์ฝ๋กฌ๋น์", | |
| "Croatia": "ํฌ๋ก์ํฐ์", | |
| "Czech Republic": "์ฒด์ฝ", | |
| "Denmark": "๋ด๋งํฌ", | |
| "Dominican Republic": "๋๋ฏธ๋์นด ๊ณตํ๊ตญ", | |
| "Ecuador": "์์ฝฐ๋๋ฅด", | |
| "Estonia": "์์คํ ๋์", | |
| "Finland": "ํ๋๋", | |
| "France": "ํ๋์ค", | |
| "Germany": "๋ ์ผ", | |
| "Ghana": "๊ฐ๋", | |
| "Greece": "๊ทธ๋ฆฌ์ค", | |
| "Greenland": "๊ทธ๋ฆฐ๋๋", | |
| "Guam": "๊ด", | |
| "Guatemala": "๊ณผํ ๋ง๋ผ", | |
| "Hungary": "ํ๊ฐ๋ฆฌ", | |
| "Iceland": "์์ด์ฌ๋๋", | |
| "India": "์ธ๋", | |
| "Indonesia": "์ธ๋๋ค์์", | |
| "Ireland": "์์ผ๋๋", | |
| "Israel": "์ด์ค๋ผ์", | |
| "Italy": "์ดํ๋ฆฌ์", | |
| "Japan": "์ผ๋ณธ", | |
| "Jordan": "์๋ฅด๋จ", | |
| "Kenya": "์ผ๋", | |
| "Kyrgyzstan": "ํค๋ฅด๊ธฐ์ค์คํ", | |
| "Laos": "๋ผ์ค์ค", | |
| "Latvia": "๋ผํธ๋น์", | |
| "Lesotho": "๋ ์ํ ", | |
| "Lithuania": "๋ฆฌํฌ์๋์", | |
| "Luxembourg": "๋ฃฉ์ ๋ถ๋ฅดํฌ", | |
| "North Macedonia": "๋ถ๋ง์ผ๋๋์", | |
| "Madagascar": "๋ง๋ค๊ฐ์ค์นด๋ฅด", | |
| "Malaysia": "๋ง๋ ์ด์์", | |
| "Malta": "๋ชฐํ", | |
| "Mexico": "๋ฉ์์ฝ", | |
| "Monaco": "๋ชจ๋์ฝ", | |
| "Mongolia": "๋ชฝ๊ณจ", | |
| "Montenegro": "๋ชฌํ ๋ค๊ทธ๋ก", | |
| "Netherlands": "๋ค๋๋๋", | |
| "New Zealand": "๋ด์ง๋๋", | |
| "Nigeria": "๋์ด์ง๋ฆฌ์", | |
| "Norway": "๋ ธ๋ฅด์จ์ด", | |
| "Pakistan": "ํํค์คํ", | |
| "Palestine": "ํ๋ ์คํ์ธ", | |
| "Peru": "ํ๋ฃจ", | |
| "Philippines": "ํ๋ฆฌํ", | |
| "Poland": "ํด๋๋", | |
| "Portugal": "ํฌ๋ฅดํฌ๊ฐ", | |
| "Puerto Rico": "ํธ์๋ฅดํ ๋ฆฌ์ฝ", | |
| "Romania": "๋ฃจ๋ง๋์", | |
| "Russia": "๋ฌ์์", | |
| "Rwanda": "๋ฅด์๋ค", | |
| "Senegal": "์ธ๋ค๊ฐ", | |
| "Serbia": "์ธ๋ฅด๋น์", | |
| "Singapore": "์ฑ๊ฐํฌ๋ฅด", | |
| "Slovakia": "์ฌ๋ก๋ฐํค์", | |
| "Slovenia": "์ฌ๋ก๋ฒ ๋์", | |
| "South Africa": "๋จ์ํ๋ฆฌ์นด ๊ณตํ๊ตญ", | |
| "South Korea": "ํ๊ตญ", | |
| "Spain": "์คํ์ธ", | |
| "Sri Lanka": "์ค๋ฆฌ๋์นด", | |
| "Eswatini": "์์ค์ํฐ๋", | |
| "Sweden": "์ค์จ๋ด", | |
| "Switzerland": "์ค์์ค", | |
| "Taiwan": "๋๋ง", | |
| "Thailand": "ํ๊ตญ", | |
| "Tunisia": "ํ๋์ง", | |
| "Turkey": "ํ๋ฅดํค์", | |
| "Uganda": "์ฐ๊ฐ๋ค", | |
| "Ukraine": "์ฐํฌ๋ผ์ด๋", | |
| "United Arab Emirates": "์๋์๋ฏธ๋ฆฌํธ", | |
| "United Kingdom": "์๊ตญ", | |
| "United States": "๋ฏธ๊ตญ", | |
| "Uruguay": "์ฐ๋ฃจ๊ณผ์ด", | |
| "Vietnam": "๋ฒ ํธ๋จ", | |
| "Nepal": "๋คํ", | |
| "Kazakhstan": "์นด์ํ์คํ", | |
| "Costa Rica": "์ฝ์คํ๋ฆฌ์นด", | |
| "Panama": "ํ๋๋ง", | |
| "Morocco": "๋ชจ๋ก์ฝ", | |
| "Egypt": "์ด์งํธ", | |
| "Saudi Arabia": "์ฌ์ฐ๋์๋ผ๋น์", | |
| "Tanzania": "ํ์๋์" | |
| }; | |
| const candidateLabels = Object.keys(countries); | |
| // โ ์์ ํ ๋ถ๋ถ: ๊ตญ๊ฐยท์ง์ญ 101๊ฐ๋ฅผ ๋น๊ตํ๊ณ ๊ฒฐ๊ณผ๋ ์์ 5๊ฐ๋ง ํ์ | |
| document.getElementById("countryList").textContent = | |
| Object.values(countries).join(" ยท "); | |
| const statusBox = document.getElementById("status"); | |
| const uploadInput = document.getElementById("upload"); | |
| const exampleButton = document.getElementById("example"); | |
| const previewImage = document.getElementById("preview"); | |
| const resultBox = document.getElementById("result"); | |
| let classifier = null; | |
| let loadSeconds = ""; | |
| try { | |
| const loadStart = performance.now(); | |
| // โ ์์ ํ ๋ถ๋ถ: ์๋ณธ๋ณด๋ค ์์ q8 ONNX ํ์ผ ์ฌ์ฉ, ํ์ผ๋ณ ์งํ๋ฅ ํ์ | |
| classifier = await pipeline(TASK, MODEL_NAME, { | |
| dtype: "q8", | |
| progress_callback: (data) => { | |
| if (data.status === "progress") { | |
| statusBox.textContent = | |
| `ํ์ผ ๋ฐ๋ ์ค: ${data.file} ${Math.round(data.progress)}%`; | |
| } | |
| if (data.status === "done") { | |
| statusBox.textContent = | |
| "ํ์ผ ๋ค์ด๋ก๋ ์๋ฃ ยท ๋ชจ๋ธ ์ค๋น ์ค..."; | |
| } | |
| } | |
| }); | |
| loadSeconds = | |
| ((performance.now() - loadStart) / 1000).toFixed(1); | |
| statusBox.textContent = | |
| `์ค๋น ์๋ฃ ยท ๋ชจ๋ธ ๋ถ๋ฌ์ค๊ธฐ ${loadSeconds}์ด`; | |
| uploadInput.disabled = false; | |
| exampleButton.disabled = false; | |
| } catch (error) { | |
| statusBox.textContent = | |
| `๋ชจ๋ธ์ ๋ถ๋ฌ์ค์ง ๋ชปํ์ต๋๋ค. ์ธํฐ๋ท ์ฐ๊ฒฐ์ ํ์ธํ๊ณ ์๋ก ๊ณ ์นจํ์ธ์. (${error.message})`; | |
| } | |
| async function classifyImage(imageUrl) { | |
| if (classifier === null) return; | |
| previewImage.src = imageUrl; | |
| previewImage.style.display = "block"; | |
| resultBox.innerHTML = ""; | |
| statusBox.textContent = | |
| "101๊ฐ ๊ตญ๊ฐยท์ง์ญ์ ๋น๊ตํ๋ ์ค... ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์์ต๋๋ค."; | |
| // โ ์์ ํ ๋ถ๋ถ: ๋ถ๋ฅ ์ค์๋ ์ค๋ณต ์คํ ๋ฐฉ์ง | |
| uploadInput.disabled = true; | |
| exampleButton.disabled = true; | |
| // โ ์์ ํ ๋ถ๋ถ: ๋ถ๋ฅ ์คํจ๋ ํ๋ฉด์ ์๋ด | |
| try { | |
| const start = performance.now(); | |
| // โ ์์ ํ ๋ถ๋ถ: ์ฌ์ง๊ณผ ํจ๊ป ๋น๊ตํ ๊ตญ๊ฐ ํ๋ณด๋ฅผ ์ ๋ฌ | |
| const results = await classifier(imageUrl, candidateLabels, { | |
| hypothesis_template: "A street view photo taken in {}." | |
| }); | |
| const seconds = | |
| ((performance.now() - start) / 1000).toFixed(1); | |
| statusBox.textContent = | |
| `๋ถ๋ฅ ${seconds}์ด ยท (๋ชจ๋ธ ๋ถ๋ฌ์ค๊ธฐ ${loadSeconds}์ด)`; | |
| // ์ ์ฒด ํ๋ณด ์ ์๋ฅผ ์ ์งํ ์ฑ ์ ์์์ผ๋ก ์ ๋ ฌํด 5๊ฐ๋ง ํ์ | |
| results.sort((a, b) => b.score - a.score); | |
| results.slice(0, 5).forEach(({ label, score }) => { | |
| resultBox.innerHTML += ` | |
| <div class="row"> | |
| <span class="name">${countries[label]}</span> | |
| <div class="track"> | |
| <div | |
| class="bar" | |
| style="width:${(score * 100).toFixed(1)}%" | |
| ></div> | |
| </div> | |
| <span class="score"> | |
| ${(score * 100).toFixed(1)}% | |
| </span> | |
| </div>`; | |
| }); | |
| } catch (error) { | |
| statusBox.textContent = | |
| `๋ถ๋ฅํ์ง ๋ชปํ์ต๋๋ค. ๋ค๋ฅธ ์ฌ์ง์ผ๋ก ๋ค์ ์๋ํ์ธ์. (${error.message})`; | |
| } | |
| uploadInput.disabled = false; | |
| exampleButton.disabled = false; | |
| } | |
| exampleButton.addEventListener( | |
| "click", | |
| () => classifyImage(EXAMPLE_URL) | |
| ); | |
| uploadInput.addEventListener("change", (event) => { | |
| const file = event.target.files[0]; | |
| // ํ์ผ ์ ํ์ ์ทจ์ํ๋ฉด ์ข ๋ฃ | |
| if (!file) return; | |
| // โ ์์ ํ ๋ถ๋ถ: ์ด๋ฏธ์ง๊ฐ ์๋ ํ์ผ์ ๊ณ ๋ฅธ ๊ฒฝ์ฐ ์๋ด | |
| if (!file.type.startsWith("image/")) { | |
| statusBox.textContent = | |
| "JPG ๋๋ PNG ๊ฐ์ ์ฌ์ง ํ์ผ์ ์ ํํ์ธ์."; | |
| return; | |
| } | |
| const reader = new FileReader(); | |
| reader.onload = (e) => classifyImage(e.target.result); | |
| // โ ์์ ํ ๋ถ๋ถ: ํ์ผ ์ฝ๊ธฐ ์คํจ ์๋ด | |
| reader.onerror = () => { | |
| statusBox.textContent = | |
| "ํ์ผ์ ์ฝ์ง ๋ชปํ์ต๋๋ค. ์ฌ์ง์ ๋ค์ ์ ํํ์ธ์."; | |
| }; | |
| reader.readAsDataURL(file); | |
| }); | |
| </script> | |
| </body> | |
| </html> |