npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@servantcdh/ez-planet-labeling-sam

v0.6.3

Published

`@servantcdh/ez-planet-labeling` 워크스페이스를 위한 브라우저 전용 Segment Anything 확장.

Readme

@servantcdh/ez-planet-labeling-sam

@servantcdh/ez-planet-labeling 워크스페이스를 위한 브라우저 전용 Segment Anything 확장.

백엔드 서버 없이 브라우저에서 직접 이미지 세그멘테이션과 자동 클래스 분류를 수행합니다.

Models

| 모델 | ID | 용도 | 크기 (q8) | |------|-----|------|-----------| | SlimSAM-77 | Xenova/slimsam-77-uniform | 이미지 세그멘테이션 | ~10-15 MB | | CLIP ViT-B/16 | Xenova/clip-vit-base-patch16 | Zero-shot 클래스 분류 | ~85 MB |

모델은 첫 사용 시 Hugging Face Hub에서 다운로드되며, 브라우저 Cache Storage에 캐시됩니다.

설치

npm install @servantcdh/ez-planet-labeling-sam

Peer Dependencies (호스트 앱에서 설치)

| Package | Version | 용도 | |---------|---------|------| | @servantcdh/ez-planet-labeling | >=1.0.0 | 코어 라벨링 라이브러리 | | react | ^18.0.0 | UI 런타임 | | react-dom | ^18.0.0 | DOM 렌더링 | | fabric | ^5.0.0 | 캔버스 엔진 | | zustand | ^5.0.0 | 상태 관리 |

Bundled Dependencies (자동 설치)

| Package | 용도 | |---------|------| | @huggingface/transformers | ONNX Runtime Web 기반 브라우저 추론 |

기본 사용법

import {
  LabelingWorkspace,
  LabelingProviders,
  useToolbarSubMenuItemsStore,
  useExtensionFloatingPanelStore,
  useImageTypeLabelingToolSelectionStore,
  type ExtensionSubMenuItem,
} from "@servantcdh/ez-planet-labeling";
import { createSamExtension, createSamTool } from "@servantcdh/ez-planet-labeling-sam";

function App() {
  // 1. Extension 등록
  const extensions = useMemo(
    () => [
      createSamExtension({
        policyClasses: [
          { index: 0, name: "Car", color: "#e74c3c" },
          { index: 1, name: "Person", color: "#2ecc71" },
          { index: 2, name: "Building", color: "#8e44ad" },
        ],
      }),
    ],
    []
  );

  // 2. 툴바 서브메뉴 등록
  useEffect(() => {
    const items: ExtensionSubMenuItem[] = [
      {
        id: "demo-sam",
        iconType: "icon-seg-anything",
        name: "Segment Anything",
        shortcut: { key: "s", label: "S" },
        onClick: () => {
          useImageTypeLabelingToolSelectionStore.getState().setTool(createSamTool());
          useExtensionFloatingPanelStore.getState().openPanel("demo-sam");
        },
      },
    ];
    useToolbarSubMenuItemsStore.getState().setItems(items);
    return () => useToolbarSubMenuItemsStore.getState().clearItems();
  }, []);

  // 3. 워크스페이스에 전달
  return (
    <LabelingProviders data={dataCtx} mutations={mutationCtx} dataset={datasetCtx}>
      <LabelingWorkspace extensions={extensions} />
    </LabelingProviders>
  );
}

기능

Interactive Mode

캔버스에서 직접 프롬프트를 입력하여 세그멘테이션을 수행합니다.

| 입력 | 조작 | SAM Label | |------|------|-----------| | Positive point | 좌클릭 | 1 | | Negative point | 우클릭 | 0 | | Bounding box | 좌클릭 드래그 | 2 (좌상단) + 3 (우하단) |

포인트/박스를 추가할 때마다 디코더가 실시간으로 마스크를 생성합니다.

Auto Mode

그리드 포인트 기반 "Segment Everything" 모드.

  1. Grid 크기 선택 (8x8 ~ 32x32)
  2. Run 클릭
  3. Segmenting — 각 그리드 포인트에서 마스크 디코딩 + NMS로 중복 제거
  4. Classifying — CLIP으로 각 세그먼트를 policy 클래스에 자동 분류
  5. 결과 리스트에서 클래스를 드롭다운으로 수정 가능
  6. Apply — fabric 오브젝트에 클래스 정보(labelInsertData) 적용

Auto 모드 실행 중 Stop 버튼으로 중단할 수 있습니다.

Apply / Reset / Close

| 동작 | 설명 | |------|------| | Apply | SAM 오브젝트를 확정 라벨로 승격 (Reset/Close에서 보존) | | Reset | 현재 프롬프트/마스크 초기화 (확정 라벨은 유지) | | Close | SAM 패널 닫기, 미확정 결과가 있으면 confirm 표시 |

Runtime 성능

WebGPU가 사용 가능하면 자동으로 활용하며, 불가 시 WASM으로 폴백합니다.

| 단계 | WebGPU | WASM | |------|--------|------| | 모델 로딩 (첫 실행, 네트워크 포함) | ~3-5s | ~5-10s | | 모델 로딩 (캐시) | ~0.5-1s | ~1-2s | | 이미지 인코딩 | ~2-4s | ~5-10s | | Interactive 디코딩 (클릭당) | ~50-100ms | ~200-500ms | | Auto 세그멘테이션 (16x16) | ~30s | ~60-120s | | CLIP 분류 (세그먼트당) | ~1-2s | ~3-5s |

Exports

Functions

| Export | 설명 | |--------|------| | createSamExtension(options?) | SAM LabelingExtension 생성 | | createSamTool() | SAM 캔버스 도구 생성 (포인트/박스 캡처) |

Hooks

| Export | 설명 | |--------|------| | useSlimSam() | SAM + CLIP 추론 hook (모델 로딩, 인코딩, 디코딩, 자동 분류) | | useSamStore() | SAM UI 상태 Zustand store |

Types

| Export | 설명 | |--------|------| | PolicyClassItem | { index, name, color } — 클래스 정보 | | SamPrompt | { x, y, label } — 포인트/박스 프롬프트 | | DecodedMask | Interactive 디코딩 결과 | | AutoMask | Auto 세그멘테이션 결과 (classInfo 포함) | | ClassInfo | { className, classIndex, confidence } — CLIP 분류 결과 | | SamStatus | 모델 상태 (idle, loading-model, encoding, ready, decoding, auto, error) | | SamMode | "interactive" \| "auto" | | SamState | Zustand store 상태 타입 |

createSamExtension Options

interface CreateSamExtensionOptions {
  policyClasses?: PolicyClassItem[];
}

| Option | 설명 | 기본값 | |--------|------|--------| | policyClasses | Auto 모드에서 CLIP 분류에 사용할 클래스 목록 | [] (분류 비활성) |

policyClasses가 비어있으면 Auto 모드에서 세그멘테이션만 수행하고 분류는 건너뜁니다.

Architecture

@servantcdh/ez-planet-labeling        (코어, peer dependency)
  ├── segmentAnythingTool()           — 캔버스 포인트/박스 캡처
  ├── getCanvasInstance()             — fabric.Canvas 접근
  ├── useExtensionFloatingPanelStore  — 패널 열기/닫기
  └── TOOL_INFO_SEGMENT_ANYTHING_*   — 오브젝트 식별 상수

@servantcdh/ez-planet-labeling-sam    (이 패키지)
  ├── createSamExtension()            — LabelingExtension 정의
  ├── createSamTool()                 — 콜백 주입 래퍼
  ├── useSlimSam()                    — 추론 엔진 (SlimSAM + CLIP)
  ├── useSamStore()                   — UI 상태 관리
  └── SamFloatingPanel                — 패널 UI (모드 전환, 진행률, 결과)

@huggingface/transformers             (런타임 dependency)
  ├── SamModel                        — SlimSAM 인코더/디코더
  ├── CLIPTextModelWithProjection     — 텍스트 임베딩
  ├── CLIPVisionModelWithProjection   — 이미지 임베딩
  └── AutoProcessor / AutoTokenizer   — 전처리

호스트 앱의 기존 SAM과 공존

호스트가 자체 SAM 구현(예: 백엔드 API 기반)을 가지고 있는 경우, Extension ID가 다르므로 양쪽 모두 등록할 수 있습니다.

import { createSamExtension as createBrowserSam } from "@servantcdh/ez-planet-labeling-sam";
import { createSamExtension as createApiSam } from "./my-api-sam";

const extensions = [
  createBrowserSam({ policyClasses }),  // id: "demo-sam"
  createApiSam(),                       // id: "my-api-sam"
];

License

This software is licensed under a custom license. See LICENSE for the full text.

본 소프트웨어는 커스텀 라이선스가 적용됩니다. 한글 라이선스는 LICENSE.ko를 참조하세요.