遮蔽
入框瞬間球被籃框、網子、甚至自己的身體擋住。這時候「沒看到」不等於「沒進」,也不等於「進了」。
數字取自本專案原始碼靜態統計(src/**,152 個測試檔)。
為什麼難
手機只有一顆鏡頭。球飛過籃框的那一瞬間,球被籃框和網子擋住、 從側面看會產生錯視、戶外球場甚至沒有網子。 大部分做法會在這裡「猜一個進球」—— 使用者當下很爽,回頭看數據全是假的。
入框瞬間球被籃框、網子、甚至自己的身體擋住。這時候「沒看到」不等於「沒進」,也不等於「進了」。
從側面拍,球從籃框「後方」飛過,在畫面上看起來完全穿過籃框。單靠 2D 位置無法分辨。
戶外球場常見。網子晃動這條訊號直接消失,只剩幾何軌跡可以用。
第一鐵則
當證據不足以證明球穿過籃框,Hoopilot 回報的是 不確定,而不是猜一個好聽的答案。 判定核心裡每一條會產生「進球」的路徑,都必須通過同一張融合真值表,下面你可以自己操作它。
最常見的誤解
網子是佐證,不是判定進球的必要條件。
多數人以為這種系統是靠「看網子有沒有被打動」來判定進球。它不是。網子在系統內部不是一個是非題,而是三值的:有網子且向下運動、有網子但沒動、這個籃框根本沒有網子。三種狀態走三條不同的路,不會被壓成兩種。
在戶外那種空框上,判定完全由幾何決定:球的軌跡、穿過籃框平面的位置、以及球相對籃框的深度關係。網子存在時它的角色是佐證,向下運動會加強進球的判斷;而一張靜止不動的網子是反向證據,它會把這一球往沒進的方向推。
如果把「沒有網子」直接當成「網子沒動」,系統就會把每一顆戶外空框的進球判成沒進。二值化在這裡不是簡化,是系統性偏誤,它讓錯誤全部集中在同一種球場、同一群使用者身上。保留第三個值,等於讓系統承認「這條線索在這個籃框上不存在」,然後改用還在的線索去判。
net = true
入框窗口內量到向下的網子運動。它是佐證,會和幾何或分類一起把判定推向進球。
net = false
這是反向證據。球擦過框邊卻沒帶動網子,幾何就算看到穿越也判沒進。
net = null
戶外球場常見。這條線索不存在,系統改用純幾何判定,照樣可以判進球。
if (net === null) {
if (geo === true) return 'make'; // 沒有網子也能判進球
if (cls && occludedAtRim) return 'make';
return 'unsure';
}
取自 src/core/shotFsm.ts 的 fuse()。
運作方式
每一格對應原始碼裡真實存在的模組。點一下看它負責什麼。
相機 frame processor 在原生執行緒抓幀,縮放到 416×416、轉成模型要的 BGR 通道順序。JS 執行緒完全不碰像素。
VisionCamera worklet
自訓練的 YOLOX-nano 一次輸出四類:ball、rim、ball_in_basket、person。解碼已折進模型,輸出 [1, 3549, 9]。
TFLite · yoloParser
籃框用 RimLock 鎖定並持續微調(相機被撞到會自動重鎖);球用 Kalman 追蹤,遮蔽時標記為 predicted 繼續滑行,並用全域拋物線預測落點。
rimLock · ballTracker · flightArc
狀態機收集三條獨立訊號(幾何穿越、網子晃動、入框分類),深度比例閘門先否決錯視,再交給融合真值表輸出 進 / 沒進 / 不確定。
shotFsm · depthRatioGate · fuse()
同一段畫面同時做姿勢分析:出手角度、放球高度、身體方向。收工後自動挑一球成功出手,產出完整教練報告。
formAnalysis · coachEngine · shotOfSession
判定邏輯
下面的輸出不是寫死的說明文字 —— 它是把 App 裡
src/core/shotFsm.ts 的 fuse() 原封不動搬過來執行的結果。
切換訊號,看它怎麼決定。
注意第一條就是 if (geo === false) return 'miss' ——
幾何看到球明確落在框外時,任何其他訊號都不能把它變成進球。
這是「不可以發明進球」在程式碼裡的形狀。
單鏡頭,擺了就用
籃框是被偵測出來並鎖定的,不是被假設的。
系統不假設手機該擺在哪裡。它先在畫面中找出籃框,鎖定之後持續追蹤,所有後續判定都掛在這個實際位置上。籃框在畫面上的視寬同時是尺度基準:真實籃框直徑是已知的固定值,所以畫面像素能換算成場上的相對長度,不需要事先做相機校正,也不需要你輸入站在幾公尺外。
深度則靠比值處理:把球在畫面上的視大小除以籃框的視寬。焦距、解析度、鏡頭與機型差異會同時作用在分子和分母上,相除之後互相抵消。剩下的比值只反映一件事,球此刻離籃框平面是近還是遠。
從側面拍和從底線拍,同一顆球在二維畫面上留下的是真正不同的圖像:側面看得到弧線但看不出左右偏差,底線看得到左右偏差但看不出前後深淺。深度閘門存在的理由就是補上這個從單一畫面看不出來的維度。極端角度確實會讓證據品質下降,例如幾乎正對籃框背面、或籃框在畫面裡小到只剩幾十個像素,這種時候系統回報不確定,不會硬猜一個答案。
邊界在哪裡
進球判定的幾何假設手機是直立、沒有翻轉,而且鏡頭看得到籃框 —— 從側面、斜角或球員後方都可以。真正與擺放完全無關的只有球場定位那一段, 它靠四點註冊決定兩分或三分。
超出這個範圍的擺法(例如從籃板正後方拍、手機側倒、或籃框在畫面裡只剩幾十個像素), 證據品質會下降,這時系統回報不確定,不會硬猜。
示範畫面右上角有五個相機位置,也可以直接用滑鼠拖曳畫面繞著籃框轉。 同一顆球在不同角度會產生不同的二維證據,判定邏輯完全沒有改變。
實際輸出
不是示意圖。以下畫面由本專案的偵測管線對真實影片逐幀跑出來後標註輸出。
ball_in_basket 觸發。但它只是三條訊號之一,單靠它不足以判定進球。
早期模型嚴重依賴「橘色」這個特徵:橘球辨識率高,換成其他顏色的球就大幅下滑。 這不是猜的,是把同一段影片的球做色相位移後逐幀量出來的。
解法是在訓練時加入全色環色相增強,並保留原始橘球樣本,讓模型改用形狀與紋理判斷。
不只是計數器
收工後自動挑一次成功出手做完整拆解:出手角度、放球高度、身體方向、與參考動作的差距。
球場定位換算成落點分布,兩分/三分自動判斷,看得出來哪個位置是你的真實強項。
用罰球線做一次錨定,系統就能把畫面座標換算成球場實際距離。手機隨便放都能用。
訓練量會被記住。連續天數、每週目標、可分享的成績卡。
畫面太暗、鏡頭被擋、籃框跑掉,App 會直接告訴你,而不是安靜地開始亂記。
裝置溫度上升時自動降低推論頻率,長時間練習不會因為過熱被系統掐死。
市場與定位
籃球不缺人打。缺的是一條「不用買硬體、不用裝東西、不用換一顆球」就能開始記錄的路。
市面上的方案大致分成四類。它們都能用,但每一類都先跟使用者收一筆「開始的成本」。
| 類型 | 代表 | 公開價格 | 開始之前要先做的事 |
|---|---|---|---|
| 固定式硬體 | Noah Basketball、RSPCT、ShotTracker | Noah Backboard 每框啟用 US$1,750 + 年費 US$1,500;Noah Instant US$4,599。RSPCT 與 ShotTracker 未公開價格。 | 把感測器鎖在籃板或吊在屋樑上,要場館權限、電源、安裝人員。綁定那一座球場,離開就沒有資料。 |
| 智慧球 | SIQ / Spalding TF DNA、DribbleUp | Spalding TF DNA 球 + 一年訂閱 US$199.99;DribbleUp 球 US$59.99 + 會員 US$19.99/月。 | 必須用他們那一顆球。球隊練習用隊上的球、街頭撿到誰的球都不算。球會磨損、要充電。 |
| 穿戴式 | Apple Watch 類投籃計數 app | app 多為免費或低價,但需要一支手錶。 | 手腕的慣性訊號知道你「出手了」,不知道球有沒有進,也沒有位置,做不出熱區圖。 |
| 純手機 | HomeCourt、篮迹 | HomeCourt 個人 US$7.99/月 或 US$69.99/年;篮迹 US$9.99/年。 | 門檻最低的一類,也是 Hoopilot 的直接戰場。差別在於裝置端的判定是否誠實,以及不理想的球場條件下還能不能用。 |
價格為各家官方頁面公開資訊,擷取於 2026 年 8 月;未公開者已標示。列出的是使用門檻,不是產品優劣評比。
綁定硬體的風險不是理論
這兩顆智慧籃球當年都要價約 US$200。廠商停止維護 app 之後,球上的感測器再也連不上任何東西, 買過的人手上剩下一顆很貴的普通球。任何把資料鎖在專屬硬體裡的方案,都帶著同一個風險。
手機就是感測器。沒有要鎖在籃板上的裝置,沒有指定的球,沒有會沒電的東西。
戶外沒有網子的框、任何顏色的球、下午刺眼的側光。這些不是邊緣情況,是台灣多數人真正在打球的地方。
推論全部在裝置上完成,影像不上傳。服務終止也不會讓你的紀錄變成一顆磚。
硬體路線圖
軟體端已經跑通。剩下的問題是實體的:一個人到球場,手機沒地方放。 下面三件東西都刻意做成被動、無電池、無韌體的結構件, 因為這個產品最不該做的事,就是變成另一個廠商停止維護就報廢的硬體。
一個人也架得起來的球場支點
一個人到球場,手機沒地方放。水壺靠著、書包墊著、鐵絲網縫裡硬卡——角度偏一點整段就作廢,球打到就是一支摔在水泥地上的手機。這是所有純手機方案(HomeCourt、篮迹)共同的死穴:軟體再準,拍不到就是零。而且就算擺好了,鏡頭離地多高仍然是未知數。
純被動結構,無電子零件。三種扣法覆蓋真實球場:鐵絲網勾扣、圓桿與籃球架支柱綁帶、可灌沙或掛背包配重的地樁。手機夾以橫向為優先(app 的畫面映射在橫向才精確),夾臂做後仰洩力,被球擊中時是整顆雲台後倒卸力,而不是把手機彈出去。關鍵設計是離地高度做成少數幾個實體卡榫段位(例如 0.9 / 1.3 / 1.7 公尺),開拍前在 app 點一下用哪一段。
這支軟體的定位鏈(籃框鎖定、court homography、罰球線 4.19 公尺錨定)全都在解同一組未知數:比例、俯仰、偏航。俯仰手機自己的重力感測器就能給,偏航可從球場線反推,唯獨「鏡頭離地多高」沒有任何手機感測器能給。定樁把高度變成一個點一下就成立的離散已知值,等於白送軟體一個約束條件,可以省掉走到罰球線的校正儀式;固定段位也讓同一個人每次來都是同一組外參,跨 session 的落點資料才真的可比。
三個真的沒把握的點。第一是責任:一個幾百塊的塑膠件上掛著兩三萬的手機,球場上被球正面打中是必然事件,要做到不掉機需要真實落球衝擊測試與材料迭代,目前連一次撞擊測試都還沒做過,只要有一支手機因為我們的夾具摔壞,這條產品線就結束了。第二是這個賣點可能自己蒸發:如果實測發現 app 靠 IMU 加籃框成像幾何自己反推高度就夠準,那「已知高度」的價值歸零,剩下的就只是一支比較貴的三腳架,而網購泛用三腳架不到三百塊,對多數人已經夠用,貨架上也講不清楚差在哪。
一片扣片,換回公制真尺度
要判斷這球是 2 分還 3 分、出手距離幾公尺,現在得靠使用者手動點球場地標算 homography,或走到罰球線用 4.19 公尺反解。戶外球場的線常常褪到看不見、被落葉蓋住,或根本沒畫三分線;室內從側面架機時地標又容易被人擋住。
一片扣在籃框前緣的被動標記帶,工程塑膠或矽膠射出,無電池、無配對、無韌體。表面是已知實體尺寸的非對稱高對比圖案(概念近似 AprilTag / ArUco,但為 3.05 公尺遠距與強光重新設計:模組加粗、啞光面避免反光、底色不用白以免過曝)。因為圖案的尺寸與形狀已知且非對稱,單一影格就能解出籃框平面的完整位姿——距離、偏航、俯仰,不需要球場線、不需要走位、不需要使用者點螢幕。
這支軟體已經在鎖籃框,也已經拿籃框成像的長寬比當相機角度的代理值,但那是一個很粗的代理。尺標把代理換成量測:籃框位姿一旦是量測值,球的成像直徑(男子 7 號球直徑約 24.3 公分,已知)就能反推球到鏡頭的距離,而這正是融合真值表目前唯一補不上的一軸——深度。
第一是像素預算:偵測器吃 416 或 640 的方形輸入,籃框在 3.05 公尺高、鏡頭常在 6 到 10 公尺外,標記落進模型輸入時可能只剩幾個像素,幾乎確定得在全解析度影格上另跑一次專屬的標記偵測。專案有過 ROI 二次偵測的經驗,也踩過不少坑,額外的延遲成本完全沒測過。第二是精度未證:位姿解只要有 1 度角度誤差,外推到 7 公尺外的三分線就是十幾公分,尺標能不能穩到足以支撐「角落 3 分也算得準」這種宣稱,沒有實測資料前不該承諾。
讓籃網說得出進了沒
融合真值表最強的非幾何證據是籃網的爆發式晃動,但真實球場的網不是為機器視覺做的:白色尼龍在陽光下過曝、很多戶外框根本沒有網或只剩兩三條、鐵鏈網幾乎不晃。證據一薄,設計上寧可誠實輸出不確定也不硬判進球,結果使用者看到的就是一堆 unsure。這一段軟體無能為力,因為它只能觀察現場有什麼。
一張純被動的替換籃網,為視覺辨識重新設計三件事。其一是色相:採用球場上罕見的高彩度洋紅或紫,與橘球、木地板、水泥、樹、天空都分得開,擺脫目前以綠通道取樣的脆弱做法。其二是分段:沿網身做深淺相間,讓晃動在時間軸上產生高對比的條紋位移,而不是一團白色糊影。其三是動力學:網尾加重、網目略緊,使空心穿越產生更短更陡的爆發特徵,與風吹或擦網而過的緩慢晃動在頻譜上分得開。無電池、無配對,壽命就是一張網的壽命。
這支軟體的核心承諾是不確定就不編造進球,而這個承諾的代價全部由 unsure 承擔。要在不放寬真值表的前提下把 unsure 壓下來,唯一的路是提高證據品質。訊號籃網就是直接拉高 net 這一路訊號的訊噪比,判定規則一行都不用鬆。它也順便補上「球場沒有網」時走的 netless 分支,而內部檢討顯示,假進球風險最集中的地方正是那條分支。
第一,效果完全未證。「重新設計的網會讓 net 訊號明顯變好」目前純屬推論,要成立必須在同一個籃框、同一批投籃上做換網前後的標註 A/B,而這批資料還不存在;也很可能現行以幾何為主的判定根本吃不到多少增益。第二,裝設門檻跟尺標一樣要搆到 3.05 公尺,而且掛網比扣一片標記更費事,掛上去多半得留在原地,等於送給球場,也可能被管理方拆掉。第三,戶外環境會反咬:風讓網持續晃動,製造沒有投籃的網訊號;染料在紫外線下會褪色,褪到什麼程度就失去色相優勢也沒人知道。
立場
以上三件全部都是「有會更好」,不是「沒有就不能用」。App 本身現在就能在 一支手機、一個沒有網子的戶外框、一顆不是橘色的球上運作。 任何一件硬體如果實測證明沒有帶來真實增益,它就不該存在 —— 上面每一張卡片的未知數欄位寫的是我們自己最擔心的事,不是行銷風險聲明。
產品承諾
證據不足時,系統回報不確定,並指出缺的是哪一條訊號。
每一次判定背後有幾條各自獨立的訊號:球的軌跡、穿過籃框平面的位置、深度比值,以及網子(如果這個籃框有的話)。當這些訊號彼此矛盾,或其中關鍵的一條根本沒取得,系統不會拿剩下的湊一個答案,而是標記為不確定。畫面上會直接寫出缺的是哪一條,而不是丟一個沒有內容的低信心分數給你。
對認真練球的人來說,一顆被憑空發明出來的進球,比一個誠實的不確定更糟。命中率是拿來調整訓練內容的,你會依據它決定今天多投哪個點、改哪個出手習慣。假進球把數字推向好看的方向,而你根據灌水數字做的每一個訓練決定都是錯的,錯誤還會一路往後累積。
不確定則是可以處理的。它告訴你哪一球需要自己回看,也告訴你這次的拍攝條件缺了什麼,下一次把手機往旁邊挪兩公尺就補得回來。一個肯說自己不知道的系統,它說知道的那些部分才值得被相信。
技術細節
完整的邏輯流程圖 —— 從相機幀到教練報告的每一個模組、每一條訊號、每一個否決閘門,放在受密碼保護的頁面。