LEGO 盒組搜尋器
使用者拍攝積木堆中的特殊零件:人偶、動物、印刷磚、車輛、奇特形狀。每張照片中的各個零件會被裁切出來,並由 Brickognize(一個免費的圖片辨識服務)識別,然後離線查詢 Rebrickable 的公開目錄。盒組會根據有多少獨立特殊零件指向它來進行排名。一般的磚塊和底板無法有效區分盒組,因此不要拍攝它們,它們也不被納入證據中。
所有指令都是透過一個腳本執行。每個步驟都會在同一個執行資料夾(下文以 RUN 表示,例如 ./lego-run)中讀取和寫入檔案:
python3 ${CLAUDE_SKILL_DIR}/scripts/lsf.py <步驟> RUN ...
以下,lsf.py 代表上述完整指令。執行 lsf.py <步驟> -h 可列出所有選項。如果找不到 python3(在 Windows 上常發生,但未經測試),請改用 py。檔案格式、評分方式以及常見問題的解決方法請參閱 reference.md;當某個步驟出錯,或在你手動編輯檔案之前,請先閱讀它。
1. 與使用者確認任務
用一則訊息詢問:
- 是 Duplo 還是一般 LEGO?(此技能僅在 Duplo 上測試過。如果使用者回答是一般 LEGO,請告知此情況。)
- 照片在哪裡?如果還沒有照片,請提供下方的拍攝技巧。
- 是否允許此技能將每個單一零件的裁切圖片傳送給免費的第三方辨識服務 Brickognize?只有這些裁切圖片會離開您的電腦,原始照片絕不會傳送,且這些裁切圖片不帶任何中繼資料(沒有相機、時間或位置資料)。Brickognize 的服務條款賦予其永久、免版稅的權利來使用上傳的圖片,包括用於訓練機器學習模型;使用者可以要求 Brickognize 刪除這些圖片。如果不同意,請在此停止。
- 使用者是否已經懷疑某些盒組(例如有盒子、說明書或訂單記錄)?這些資訊有助於驗證結果,但不能取代證據。
拍攝技巧(請原文照貼給使用者):
- 只挑出特殊零件:人偶、動物、印刷磚、車輛、奇特形狀。一般的磚塊和底板對區分盒組沒有幫助。
- 將盡量多的特殊零件散開放在一大張純白色床單上,每個零件周圍留約 2 公分的空隙,印刷面朝上。空隙大小比零件數量更重要:相鄰的零件在裁切時會被當成一個。如果積木堆很大,可以拍攝多張照片;技能在單次執行中累計約 300 個零件時會先詢問。白色、灰色和透明零件在深色床單上會更突出。
- 從正上方以充足光線拍攝,確保整張床單都在畫面內。
- 對於一般 LEGO(較小的零件),每張照片放少一點,並靠近拍攝。
- 人偶和印刷零件提供最多證據。
- JPEG 或 PNG 照片可直接使用。HEIC 照片(iPhone 拍攝)需要 pillow-heif 套件,或先將其匯出為 JPEG。
當你知道了積木的種類、照片檔案,並且獲得使用 Brickognize 的同意後,此步驟即完成。
2. 安裝檢查與目錄
lsf.py selftest # 離線執行,需時數秒;必須以 "0 failed" 結尾
lsf.py data --info # exit 0:表示目錄已安裝,可進行步驟 3
如果缺少 Pillow,腳本會顯示如何安裝。
Rebrickable 的目錄需要使用者手動下載一次,因為 Rebrickable 的條款禁止自動下載,所以絕對不要自行或使用任何工具下載這些檔案。執行 lsf.py data:它會列印出下載頁面和所需檔案的確切名稱(它會以 exit 1 結束)。將該清單提供給使用者,告訴他們將檔案儲存到同一個資料夾(下載資料夾即可),並等待他們告知已完成。然後:
lsf.py data --from ~/Downloads # 或使用者使用的資料夾路徑;會列出任何仍缺少的檔案
當 lsf.py data --info 以 exit 0 結束時,此步驟即完成。下載檔案約 17 MB;索引檔約佔用 ~/.cache/lego-set-finder(或 $LEGO_SET_FINDER_DATA 環境變數指定的路徑)中約 115 MB 的空間。未來若要更新目錄,使用者需重新下載檔案,然後再次執行 data --from。
3. 尋找零件
lsf.py detect RUN <照片或資料夾>
此指令會產生 RUN/overview/<photo>.jpg:這張照片上會標示編號的方框和每隔 100 像素的網格。打開每一張概覽圖並判斷每個方框:
- 保留恰好包含一個特殊零件的方框;
- 丟棄框住普通磚塊、底板、背景、陰影、床單邊緣或零件碎片的方框;
- 替換框住兩個相連零件的方框,改為每個零件一個方框;
- 為每個沒有被框到的特殊零件新增一個方框(特別是在淺色背景上的淺色零件常被遺漏)。
lsf.py boxes RUN <photo> --only 3,7,12 # 只保留這些自動產生的方框,丟棄其餘的
lsf.py boxes RUN <photo> --drop 9 --add 405,225,515,385:figure --add 395,380,500,500
座標為概覽圖的像素座標(x0,y0,x1,y1),可從網格上讀取。每次呼叫都會以僅保留的方框重新繪製概覽圖:自動產生的方框為洋紅色,你新增的為青色。每次修正後都要再次檢查。如果零件較小或靠得很近,可以使用 lsf.py zoom RUN <photo> x0,y0,x1,y1 以兩倍大小顯示該區域,座標系統相同,但網格改為每隔 50 像素;從放大圖上讀取方框的四角座標。
當所有概覽圖中的每個特殊零件都恰好位於一個保留的方框內,且每個保留的方框內也只有該零件時,此步驟即完成。
4. 裁切並檢查裁切圖
lsf.py crop RUN
打開每一張 RUN/sheets/crops_<photo>.jpg。每個裁切圖必須顯示一個完整的零件。如果發現問題,請使用 lsf.py boxes 修正方框,然後再次裁切,直到所有裁切圖都符合此標準。
5. 辨識
lsf.py identify RUN
將每個裁切圖傳送給 Brickognize,預設一次最多傳送 3 個(可透過 --workers 調整,最多 4 個)。答案會根據圖片和端點進行快取,因此重新執行時,已傳送過的裁切圖不會花費任何成本。此指令在累計 300 次新呼叫時會停止(exit code 2):請先詢問使用者,再以更高的 --max-calls 值重新執行。
沒有得到答案的裁切圖會被列出。Brickognize 對於大型或軟質零件(車身、車廂、布料)常常無法辨識。可以嘗試使用 --endpoint predict/parts/ --only <crops> 再執行一次。對於仍然失敗的零件,你將在步驟 6 中自行為其命名。
6. 對應並檢查每個零件
lsf.py match RUN --kind duplo # 或 --kind lego
此指令會寫入 RUN/pieces.tsv,每個裁切圖一行:包含 Brickognize 的答案、其對應的 Rebrickable 零件或人偶編號(rb,若不確定則會有多個)、顏色以及信心度。它會先印出所有行供檢查,特別是其中的人偶:人偶的比對結果會保留明顯錯誤的次佳選項(例如將女生誤認為男生)。打開每一張 RUN/sheets/review_<photo>.jpg(包含裁切圖、信心度、Brickognize 的名稱、Rebrickable 編號和顏色),並將每個裁切圖與其說明文字進行比較。
使用目錄輔助工具修正錯誤:
lsf.py lookup yellow truck flatbed grille --duplo --colour Yellow # 依名稱或零件編號搜尋
lsf.py fix RUN p10-m1 --rb 15454pr0006 --colour Yellow
lsf.py fix RUN p08-27 --colour "Neon Yellow" # 你的眼睛在顏色判斷上比 Brickognize 準確
lsf.py fix RUN p08-m3 --use n # 無法辨識:將其排除
lsf.py set 10931 # 列出某個盒組的所有零件,用於驗證猜測
lsf.py sets-of 14094 --colour "Medium Azure" # 顯示哪些盒組包含某種顏色的某個零件
對於 Brickognize 未辨識出的零件,根據你所看到的來命名它,然後使用 lookup 搜尋;挑選名稱和顏色都符合的候選項。如果有兩個或三個候選項同樣符合,請全部列出(--rb a;b;c):演算法處理多個選項的效果比處理一個錯誤猜測更好。一個 Duplo 積木堆的答案如果是一個非 Duplo 的零件,通常是錯誤的。
當每個 use 欄位為 y 的列都有了你從裁切圖上確認的 rb 和顏色,且所有你無法確認的列都設為 use = n 時,此步驟即完成。
7. 為盒組排名
lsf.py rank RUN
閱讀 RUN/sets.md。其中會為每個盒組顯示其等級(可能、有可能、微弱)、排名分數、有多少零件指向它、其中有多少是其他盒組沒有的零件、在照片中看到的該盒組特有物品比例,以及逐項的證據。
以表格形式向使用者呈現「可能」等級的盒組(包含盒組編號、名稱、年份、零件數、僅此盒組擁有的零件數、已見比例),然後以一行一個的方式呈現「有可能」等級的盒組。請指出:
- 列於「與以下盒組共享證據」下方的盒組:它們競爭相同的零件,請詢問使用者他們擁有哪一個;
- 分數高但僅顯示少量其特有零件(低「已見比例」)的大型盒組:這些通常是誤判;
- 清單中未包含的、你所拍攝的特殊零件:可能還有其他盒組在積木堆中。
詢問使用者他們認得哪些盒組,或是想將哪些盒組加入核對清單。核對清單中的 Rebrickable 連結會顯示每個盒組的盒子圖片。
8. 建立核對清單頁面
lsf.py page RUN --sets 10906,10931,10963 [--confirmed] [--title "我們的 Duplo"]
如果沒有指定 --sets,則會採用「可能」等級的盒組。使用 --confirmed 會將每個盒組標記為已確認(在使用者檢查過後使用)。結果會輸出為 RUN/checklist.html,是一個可直接從本機磁碟開啟的獨立檔案。請告知使用者如何使用:選擇一個盒組或切換到「按顏色分類」模式,在將每個零件放入對應的堆中時點擊零件計數,使用「隱藏已找到」查看剩餘零件,「缺少零件清單」可複製仍缺少的零件資訊,使用「儲存或重設勾選」可將勾選狀態儲存到檔案中。勾選狀態僅保存在該瀏覽器中。零件圖片從 Rebrickable 的圖片伺服器載入,因此需要網路連線。
9. 說明缺少哪些零件
在使用者開始分類之前,告知他們每個所選盒組中,哪些特殊零件沒有出現在照片中:
lsf.py missing RUN --sets 10906,10931
請清楚地說明「不在照片中」不代表「缺少」:因為只拍攝了特殊零件。當它指出某個被你排除(use = n)的裁切圖符合一個缺少的零件時,請再次查看該裁切圖,如果確實符合,則使用 lsf.py fix RUN <crop> --use y 將其恢復,然後重新排名。分類完成後,使用頁面複製的清單,或使用頁面儲存的勾選檔案(lsf.py missing RUN --sets ... --ticks <file>),來提供每個盒組缺少的零件清單。
需告知使用者的限制
- 此技能僅在 macOS 上對一個混合的 Duplo 收藏(12 個盒組)進行過測試。一般 LEGO 和 Windows 系統尚未測試。
- Brickognize 是一個免費的第三方服務;零件的裁切圖片會上傳至該服務,且其可能會保留和使用這些圖片(步驟 1)。其 predict 端點在其 API 說明中被標記為「legacy」,因此可能會變更或停止服務。
- Rebrickable 目錄需要一次性手動下載(11 個檔案,約 17 MB;索引約佔 115 MB),且會逐漸過時;要更新它,請重新下載檔案並再次執行
lsf.py data --from。 - Rebrickable 和 BrickLink 對某些零件的編號方式不同,特別是 Duplo 人偶。對應的人偶和印刷零件帶有自信度;請用肉眼檢查可疑的比對結果。