thicken について
thickenは実物の写真から、実寸のGLBモデルとJSONメタデータを生成します。書籍やカードなどをデジタル化する人向けで、フォトグラメトリではなく、オブジェクトプロファイルに基づいて形状や記録項目を定めます。
主な機能
- 01写真から実寸のGLBモデルを生成
- 02オブジェクトのJSONメタデータを出力
- 03コードやビジョンモデルで種類を識別
- 04書籍、カード、バッジ、箱に対応
- 05独自のオブジェクトプロファイルを追加
活用シーン
- 01書籍の写真から3Dモデルを作成
- 02鑑定済みカードとラベル情報を記録
- 03バッジの画像を押し出しモデルに変換
MCP 対応
thickenはMCPサーバーとして動作し、MCPクライアントから写真に基づくモデルとメタデータの生成に利用できます。利用方法を案内するAgent Skillもあります。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y thickenTHICKEN_VISION_URLAn OpenAI-compatible vision endpoint (optional): photos needn't be croppedTHICKEN_VISION_KEYシークレットThe vision endpoint's keyTHICKEN_VISION_MODELSThe endpoint's model names, comma-separated, primary firstGOOGLE_BOOKS_API_KEYシークレットYour own Google Books quota, for book sizesローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
2掲載時のツール一覧 · 3 日前に更新
このツールにパラメーターはありません。
詳細
写真を入力すると、オブジェクトが出力されます。3Dモデルとメタデータです。
thicken は実物の写真を、実際のサイズの GLB モデルと、JSON 形式の メタデータに変換します。メタデータは、ビジョンモデルがオブジェクトを読み取り、 公開カタログを検索して取得します。種類ごとのオブジェクトについて thicken が把握していることは、 プロファイルにまとめられています。いくつかは thicken に付属しており、 独自のプロファイルを追加することもできます。
それぞれ、入力した写真と出力されたモデル、およびそのメタデータを示しています。メタデータの例は下にあります。上のロゴも、文字プロファイルで作成されたthickenモデルです。thicken lettering thicken
もう一つの出力は、メタデータです。 1つ目の例の一部である、鑑定済みGiannis Antetokounmpoカードのメタデータです。
{
"profile": "slab",
"holder": "cgc",
"grader": "cgc",
"cert": "6072896005",
"widthMm": 80.5, "heightMm": 135, "depthMm": 7.5,
"read": {
"grade": "9", "gradeName": "MINT",
"autoGrade": "10", "autoGradeName": "AUTO",
"signed": "G. ANTETOKOUNMPO, 8/2/25",
"name": "Giannis Antetokounmpo", "year": "2024-25", "maker": "Panini",
"set": "Court Kings Basketball", "number": "#5", "variant": "Blank Slate"
},
"readBy": { "grade": "agreed", "autoGrade": "agreed", "set": "disputed" },
"inside": {
"card": { "widthMm": 63.5, "heightMm": 88.9, "corners": "square", "foil": "none" },
"label": { "widthMm": 66.4, "heightMm": 26.9 }
}
}
鑑定会社と証明書番号はラベルのQRコードから取得し、残りはビジョン モデルがスラブから読み取ります。各プロファイルに記録される内容は プロファイルの表に、各フィールドの説明は USAGE.mdに記載されています。
目次
- 試してみる · AI エージェントから使う · 仕組み · thicken オブジェクト · 作成されるもの
- 詳細(USAGE.md):バッチ処理 · 写真 · ビジョン · 動画 · トレーニングモード · レビュー · サイドカー · プレビュー · 入力 · サイズ
- マシンの外部に送信されるもの · プロファイルの追加 · セキュリティ · 構築に使用したもの · 開発 · ライセンス
試してみる
npm install -g thicken # Node 22.18 or later; or npx thicken …
thicken photo.jpg # it works out what it is: a code on it, or the vision models
thicken book cover.heic back.heic spine.heic
thicken --isbn 9780061120084 # no photo: the cover and size from Open Library
thicken slab front.jpg back.jpg
thicken card front.jpg back.jpg --pt 130 # a thick patch card
thicken badge badge.png --width 50 # cut-out artwork, extruded
thicken lettering thicken # the logo
thicken batch ~/Pictures/books --preview # a model per photo, PDF, video or folder
実行するたびに、最初の写真と同じ場所に<name>.glbと<name>.jsonが
書き出されます。また、--previewを指定すると両面の画像も出力されます。真正面から撮影して
トリミングした写真はそのまま使えます。トリミングしていない写真、斜めから撮影した写真、動画には、
ビジョン用の設定が必要です。OpenAI互換の任意のエンドポイントが使えます(ビジョン)。
ライブラリとして使う場合は、import { thicken } from 'thicken'のあと、
thicken(files, options)でGLBのバイトデータとサイドカーが返されます。
AI エージェントから使う
thicken はMCP サーバー(thicken mcp)としても動作し、エージェントに使用するタイミングと方法を伝える
Agent Skillも備えています。机の上にある本のモデルを依頼すると、
エージェントが作成します。Claude Codeの場合:
/plugin marketplace add bikemeardsley/thicken
/plugin install thicken@thicken
または、任意のMCP クライアントで、stdioを使ってnpx -y thicken mcpを実行します。Codex、Copilot、
Cursor、Antigravity、Gemini CLIなどについては、USAGE.mdをご覧ください。
仕組み
thicken がオブジェクトの種類について把握している情報は、そのプロフィールに保存されています。認識方法、各面、読み取る内容、実寸大での構築方法などです。オブジェクトにあるコード(ISBN バーコードや鑑定会社の QR コード)でプロフィールを選ぶか、ビジョンモデルが種類を判定します。thicken はフォトグラメトリーツールではありません。対応するオブジェクトは箱に近い形か平らな輪郭をしているため、既知の寸法から形状を構築し、写真を貼り付けます。
thicken オブジェクト
thicken が作るのは、単なる 3D 形状ではありません。実行するたびにthicken オブジェクトが書き出されます。オブジェクトの実寸(ミリメートル単位)のモデル(GLB)と、その横に、オブジェクトの種類をプロフィール固有の情報で記録したメタデータ(JSON サイドカー)が作成されます。たとえば、thicken に付属するプロフィールでは次の情報を記録します。
- 本: ISBN、カタログ情報(タイトル、著者、出版社、日付、主題、デューイ十進分類法と米国議会図書館分類法、ページ数)、およびタイトルから照合した場合の一致確度。
- 鑑定済みカードスラブ: 鑑定会社、認証番号と確認リンク、ホルダー、内部のカードとラベル(それぞれのサイズと配置)。ビジョンモデルを使うと、ラベルの読み取り結果も記録します。カードの評価(数字と「9 MINT」などの語句、修飾語、サブグレード)、ラベル上でカードとは別の評価が付けられた場合のサインの評価(「AUTO 10」)、サインした人物と時期、鑑定会社が付けたカード名などです。
- 未鑑定カード: サイズ、厚手のカードの場合はポイント単位の厚さ、角、箔。ビジョンモデルを使うと、印刷された内容(選手またはキャラクター、チーム、年、メーカー、セット、番号、パラレル)も記録します。
- ボックス: ビジョンモデルを使うと、名称、ブランド、エディション、レーティング、年を記録します。
- バッジ: ビジョンモデルを使うと、記載されている資格や名称、発行者、レベル、主題、日付、資格番号、その他すべての記載内容を記録します。
- すべてのオブジェクト: ビジョンモデルが読み取った内容とその確度、写真を使った面と代替画像を使った面の区別、各情報の取得方法、追加撮影が望ましい箇所、各ビジョンモデルの回答。
アプリはモデルを表示し、サイドカーを読み取ります。たとえば、本を並べた書棚や、スラブを収めた保管庫を表示します。各フィールドについてはサイドカーに記録される内容をご覧ください。
作成するもの
thicken は 3D オブジェクトを作成します。オブジェクトの種類に関する情報はプロフィールに保存され、src/profiles に種類ごとに 1 つのファイルがあります。誰でもプロフィールを追加できます
(CONTRIBUTING.md)。現在、ここにある各プロフィールは次のとおりです。
| プロファイル | 内容 | 入力 | 生成されるもの | ビジョンモデルが読み取る項目 |
|---|---|---|---|---|
badge | 切り抜き型のデジタルアートワーク:認定バッジ、ロゴ、ステッカーのデザイン | 形状の周囲が透過したアートワーク(--width、--depth は mm 単位) | アートワーク自体の輪郭を押し出したものです。正面にはアートワーク、側面と背面には縁の色が使われます | name、issuer、level、subject、date、id、text |
book | ハードカバーまたはペーパーバックの本 | 表紙、裏表紙、背表紙、ページ側面の一部または全部(順不同)、あるいは ISBN のみ | ISBN のカタログレコードに基づき、実寸で作られます。ペーパーバックは柔らかく丸みを帯び、ハードカバーはページより板紙が少し大きくなります | title、subtitle、authors、series、publisher、edition |
card | プラスチックホルダーに封入されていない、単体のトレーディングカード | 表面と裏面 | --size で指定されない限り 63.5 × 88.9 mm の薄いプレートです。厚みのあるカードのポイント数が --pt で指定されない限り、厚さは 0.35 mm です。ビジョンモデルが認識した角のカットや、きらめく箔も反映されます | name、team、year、maker、set、number、variant |
lettering | ぷっくりした 3D のバブル文字で表現された言葉 | 画像の代わりに入力する言葉(幅は --width mm、厚みは --depth mm) | Titan One フォントを使った、断面が風船のように丸い、ぷっくりした金色のバブル文字です | – |
slab | 鑑定済みのトレーディングカードが、ラベル付きの透明なプラスチックホルダーに密封されたもの | 表面と裏面 | 鑑定機関のサイズに合わせた透明なプラスチックホルダーです。カードとグレードラベルが写真から切り出され、内部に収められます | grader、grade、gradeName、qualifier、subgrades、autoGrade、autoGradeName、autograph、signed、cert、name、team、year、maker、set、number、variant |
box | 箱型の物体(ゲームケース、携帯電話、カードのデッキ、パッケージなど) | 正面と、裏面や側面のいずれか。またはサイズ(--size)、あるいはビジョンモデルによる推定値 | 各面に写真を貼り付けた、柔らかく丸みのある箱です | title、brand、edition、rating、year |
各モデルに共通する項目(サイズとその出典、各面と画像、コード、ビジョンモデルの読み取り内容と確信度、再確認が必要な項目。詳しくはUSAGE.mdを参照)に加えて、それぞれのサイドカーに記録される内容:
badge:edge、regions
| フィールド | 記録内容 |
|---|---|
edge | 輪郭のすぐ内側の色。側面と背面に使われます(#rrggbb) |
regions | アートワークがいくつの独立した形状で構成されているか(メダルとリボンは 2 つです) |
book:isbn、catalog、match、pages、binding、bindingBy、measuredBy、depthEstimates、coverUrl、sticker、lookups
| フィールド | 記録内容 |
|---|---|
isbn | ISBN。指定されたもの、バーコードから読み取ったもの、またはタイトルの照合で版が特定されたものです |
catalog | Open Library の版とその作品に関するレコード:タイトル、著者、出版社、日付、版、形式、シリーズ、言語、主題、Dewey 分類と LC 分類、目次、すべての ID、リンク、表紙 |
match | 読み取ったタイトルから見つかった場合、読み取った内容、照合の確信度、作品とその各版 |
pages | ページ数 |
binding | ハードカバーまたはペーパーバック |
bindingBy | 装丁の判定方法:vision、catalog、または assumed |
measuredBy | 各サイズの出典:measured、openlibrary、loc、googlebooks、pages、photos、cover、または trim |
depthEstimates | 写真からの推定とページ数からの推定を含む、すべての厚みの推定値 |
coverUrl | 正面が撮影されていない場合に代わりに使われる、Open Library の表紙 |
sticker | 表紙の箔押しシールまたはステッカーの位置 |
lookups | カタログへのすべてのリクエスト:ホスト、パス、ステータス、時刻 |
card:corners、cornersBy、foil、foilBy、pictureBox、pictureBoxBy、pt、measuredBy
| フィールド | 内容 |
| --- | --- |
| `corners` | 角の形状:square、slight、round |
| `cornersBy` | 判定方法:vision または assumed |
| `foil` | 箔の種類:none、holo(絵柄が光ります)、reverse(絵柄以外がすべて光ります)、full |
| `foilBy` | 判定方法:vision または assumed |
| `pictureBox` | holo および reverse の箔加工の場合、表面に対する割合で示した絵柄部分の位置 |
| `pictureBoxBy` | 判定方法:vision または標準レイアウト |
| `pt` | 厚手カードの厚さ(ポイント単位、指定されている場合) |
| `measuredBy` | サイズの由来:standard または given。厚さの由来:standard、given または pt |
lettering:text、font、fontLicense、color、measuredBy
| フィールド | 内容 |
|---|---|
text | レタリングされた文字 |
font | 文字の描画に使われたフォント |
fontLicense | ライセンス(OFL-1.1) |
color | 文字の色 |
measuredBy | 幅と奥行きの由来:given、デフォルト、または断面の丸み |
slab:grader、cert、verifyUrl、holder、inside、measuredBy
| フィールド | 内容 |
|---|---|
grader | QR コードまたはラベルから判定した鑑定機関:psa、bgs、cgc、sgc または tag |
cert | 認証番号 |
verifyUrl | QR コードから取得した、この認証番号に対応する鑑定機関のページ |
holder | 収納ケースの形状(psa、cgc-tall…) |
inside | ケース内のカードとラベル:それぞれのサイズ、中央位置、配置方法。カードの角と箔加工、ラベル上のホログラムの位置 |
measuredBy | サイズの由来:ケースの表、または実測 |
box:barcode、measuredBy
| フィールド | 内容 |
|---|---|
barcode | 写真に写っている場合の製品バーコード(UPC または EAN)とその種類 |
measuredBy | 各サイズの由来:実測、またはビジョンモデルによる推定 |
プロファイルを指定してください。省略すると、thicken が選択します。
- 写真に ISBN バーコードがある場合、または
--isbnを指定した場合は、書籍です。 - 鑑定機関のサイト(psacard.com、beckett.com、
cgccards.com、gosgc.com、taggrading.com)を指す QR コードがある場合は、
slabです。どの鑑定機関かも判定されます。
サイドカーには鑑定機関、リンクから取得した認証番号、リンク自体
(
verifyUrl)が保持されます。 - 古いラベルの Code 128 認証バーコードも同様ですが、ケースに見える形状の写真の場合に限ります。 この場合、鑑定機関はビジョンモデルがラベルから読み取ります。ビジョンを使わない場合は、 PSA サイズのケースと仮定し、警告を出します。
- 透明部分のあるアートワークで、その形状が単なる長方形ではない場合は、 バッジです。
- それ以外の場合、vision を使うと、モデルにプロファイルを提示して、
該当するものとおおよそのサイズを判定します。顔の判定と同様に、2 つのモデルの判定が一致すれば確定し、
他のプロファイルで扱わない箱形のものは
boxが受け持ちます。 - それでも特定できないものは、プロファイルを指定するよう求めて処理を拒否します。 それ以外のバーコードは判定に使いません。書籍には UPC、QR コード、図書館のシールが付いているためです。
サイドカーの identifiedBy.profile には、選択方法として given、
recognized(コードまたはアートワークによる認識)、または vision が記録されます。
プロファイルの追加は、src/profiles にファイルを 1 つ追加するだけです。ほかに変更は不要です。ファイルには、プロファイル名、その種類と各面についての簡単な説明(ビジョンモデルに伝える情報です)、読み取る項目(多いほど便利です。サイドカーからアプリが必要な情報を取り出せるようになっています)、任意でコードや写真から自動判定する方法、そして各面に配置した写真から組み立てる方法を記述します。汎用プロファイルには、unknown ではなく、組み立てる形状の名前(box、将来的には flat や cylinder など)を付けます。thicken で組み立てられない形状は、無理に当てはめず処理を拒否します。貢献を歓迎します。方法については
CONTRIBUTING.md をご覧ください。
画像は、写っている内容に応じて各面に配置されます(
Photosを参照)。表紙がない場合は、Open Library の表紙が代わりに使われ、要確認としてマークされるため、裏面の写真が1枚あれば本を作り始められます。
マシンの外部に送信されるもの
THICKEN_VISION_URL を設定すると、写真そのもの(EXIF を除去するために再エンコードされます)がそのホストに送信されます。自分で管理する LAN サーバーを使っても、各写真はモデルのプロバイダーに転送されます。ホスト型エンドポイントにはすべての写真が送信されます。ほかに外部へ送信されるのは、本のカタログ検索(Open Library、Library of Congress、Google Books)のみです。送信されるのは ISBN、またはモデルが読み取ったタイトルと著者であり、写真は送信されません。
それ以外に何かが送信されることはなく、実行時に取得されるのもこれらの検索結果だけです。プレビューは、自分のディスクから配信される model-viewer を使って描画されます。
プロファイルの追加
プロファイルは、単独で置く1つのファイルです。対象物、その面、読み取る内容、組み立て方を記述します。thicken を使いながら独自のプロファイルを作成したり、付属のプロファイルを改善したりして、提供してください。
thicken profile new vinyl # from the template, in ~/.thicken/profiles: used at once
thicken profile check vinyl # what thicken's CI will check
thicken profile contribute vinyl # forks, branches, checks and opens the pull request
テンプレートの templates/profile.ts は、そのまま使えます(指定したサイズの箱として機能します)。各フィールドに何を記入するかが説明されており、書き込まれるレコードについても記載されています。詳細は CONTRIBUTING.md をご覧ください。上の表はプロファイル自体から作成されています。
セキュリティ
脆弱性は SECURITY.md の説明に従って非公開で報告してください。また、thicken が扱うファイル、ネットワーク、実行するプログラムも記載されています。
使用技術
| 項目 | 方法 | 選択 |
|---|---|---|
| バッジの輪郭の三角形分割 | 依存関係 | mapbox/earcut (ISC) |
| GLB の書き出し | 依存関係 | donmccurdy/glTF-Transform (MIT) |
| HEIC のデコード | 依存関係 | catdad-experiments/libheif-js (LGPL-3.0、変更せずに使用)。sharp のバイナリには HEVC が含まれていません。 |
| バーコードの読み取り | 依存関係 | Sec-ant/zxing-wasm (MIT)。.wasm はデフォルトの CDN ではなく、node_modules から読み込みます。 |
| スキャナーで作成した PDF の画像 | 依存関係 | unjs/unpdf (MIT、内部で pdf.js を使用) |
| 動画からのフレーム抽出 | プログラム外 | FFmpeg を PATH から実行し、同梱はしません。GPL は MIT をより制約の厳しいものにします。eugeneware/ffmpeg-static (GPL-3.0) を使うと、動画の有無にかかわらず、すべてのインストールに GPL バイナリが含まれてしまいます。ffmpegwasm/ffmpeg.wasm はブラウザー向けに作られています。フレームの選択は独自に行います。 |
| カメラの詳細情報(EXIF)の読み取り | 依存関係 | devongovett/exif-reader (MIT):sharp が返す EXIF ブロックを解析します |
| プレビューの描画 | 依存関係 | google/model-viewer (Apache-2.0):GLB にフレームとライトを設定します。内部で three.js を使用します |
| プレビュー用ブラウザーの実行 | 依存関係 | microsoft/playwright (playwright-core、Apache-2.0):インストール済みの Chrome または Edge を操作し、ブラウザーをダウンロードしません |
| MCP サーバー | 依存関係 | modelcontextprotocol/typescript-sdk (MIT)、公式 SDK。ツールの入力には colinhacks/zod (MIT) を使用します |
| 書籍の寸法情報源 | 独自実装 | palmerabollo/node-isbn のプロバイダー切り替えを参考にしました。こちらは最初のプロバイダーを採用するのではなく、寸法ごとに取得します。米国議会図書館の単一フィールド(MARC 300)は、MARC ライブラリではなく正規表現で読み取ります。 |
| ハードカバー | 独自実装 | src/glb.ts の4つの角丸ボックスと、カードの角のようにビジョンモデルに指定する綴じ方です。 |
| ホロフォイル | 独自実装 | 各種フォイルで光る領域は simeydotme/pokemon-cards-css から読み取りました(GPL-3.0:事実のみを参照し、何もコピーしていません)。フィルムの値には KHR_materials_iridescence のデフォルト値を使用します。KhronosGroup/glTF-Sample-Assets も同じ値を使用しています。すでに依存関係にある glTF-Transform が拡張機能を書き出します。 |
| プロファイル、ボックス、分類器、CLI | 独自実装 | |
| スラブホルダー、カード、ラベル | 独自実装 | 透明なホルダーには、すでに依存関係にある glTF-Transform のマテリアルを使用します。カードとラベルのプレート、それらの配置、および組み立ては独自実装です。透明なマテリアルの参考には、Khronos の glTF-Sample-Assets を使用しました。 |
| 写真内の顔の検出 | 独自実装 | OpenAI 互換エンドポイント上のビジョンモデルをプライマリとピアで使用します(src/vision.ts):各エンドポイントに POST を1回ずつ行い、SDK は使いません。 |
| 顔の傾き補正 | 依存せずに適応 | jlouthan/perspective-transform (MIT):4点ホモグラフィーを使用します。sharp のピクセルに対するリサンプリングは独自実装です。sharp にはパースペクティブ変換がなく、1つの機能のためだけに OpenCV.js を使うと数メガバイトになります。 |
| 角を辺に合わせる | 独自実装 | src/image.ts の snap は、モデルの角(約1%ずれています)を実際の辺に合わせます。各辺に沿って輝度の変化をサンプリングし、モデルの辺に最も近い変化を示す線を選び、最小二乗法で当てはめます。1つの面につき約70 ms です。puffinsoft/jscanify の角の順位付けを参考にしましたが、モデルの角に近い線を当てはめるだけで十分でした。 |
| レタリング用フォント | 依存関係 | opentypejs/opentype.js (MIT) で、単語のアウトラインとカーニングを読み取ります。フォントは Rodrigo Fuenzalida による Titan One で、SIL Open Font License 1.1 (fonts/OFL.txt) に基づき、変更せずに同梱しています(「Titan」は予約済みフォント名です)。 |
| 文字の立体化 | 依存せずに適応 | アウトラインからの各ピクセルの距離には、mapbox/tiny-sdf (BSD-2-Clause) の正確な距離変換を移植して使用し、アウトラインをピクセル未満の精度で配置します。立ち上がり部分は独自実装です。√u(文字内部で ∇²u = −2)を使い、どのストロークでも断面が丸くなるようにします。 |
ビューアーのレフラクター効果とホロ効果については、simeydotme/pokemon-cards-cssを参考資料としてのみ使用してください。GPL-3.0のため、内容を確認し、コピーしないでください。 |
開発
Node 22.18+上のTypeScriptを使用し、画像処理にはsharpを使います。クローンしたリポジトリから直接実行できます(Nodeが型を削除します)。npmパッケージはJavaScriptとしてdistにビルドされます(npm run build。npm packとnpm publishで実行されます)。Nodeはnode_modules内の型を削除しないためです。プッシュするたびに、Windows、macOS、Linuxでパッケージをインストールして実行します。
クローンしたリポジトリでは、npm installを実行してから、thicken …の代わりにnode src/cli.ts …を実行してください。プロファイルを変更した後は、npm test、npm run check、npm run readmeを実行してください。
ライセンス
MITです。LICENSEを参照してください。
レタリング用フォントのTitan Oneは、SIL Open Font License 1.1に基づいています(fonts/OFL.txt)。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。