2026-04-07 14:37:04 +08:00

626 lines
25 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# KNEO AcademyInnovedus AI Playgroundv2.0 — 產品需求文件PRD
> **文件性質說明**:本 PRD 為從既有程式碼與文件反向整理而成,已對照 README.md、flowchart.md、主要 controller、view 和 service 原始碼推導。標注「⚠️ 待確認」的項目為推斷內容,請產品負責人核實。
---
## 1. 產品概述
### 1.1 產品定位
**KNEO Academy**(對外名稱:**Innovedus AI Playground**)是一款 Windows 桌面應用程式,讓擁有 Kneron NPU USB Dongle 硬體的客戶能夠在本機端執行 AI 推論,無需雲端服務、無需自行撰寫程式碼。
**核心價值主張**
- 即插即用的 Edge AI 體驗——插上 Kneron dongle 即可執行 AI 模型
- 支援多種推論模式(即時攝影機、圖片上傳、自定義模型)
- 透過 Plugin 系統讓第三方或 Kneron 官方模型能被彈性載入
- 提供硬體管理工具(韌體更新、驅動安裝、裝置授權)
### 1.2 目標使用者
**主要使用者Persona A企業/研發客戶**
- 角色:使用 Kneron NPU 硬體進行 AI PoC 或產品評估的工程師、研究人員
- 目標:快速驗證 Kneron NPU 在特定任務上的推論效果
- 技術素養:中等(懂 AI 概念,不一定熟悉 SDK 整合)
- 痛點Kneron SDK 入門門檻高,想要一個能快速展示能力的工具
**次要使用者Persona B內部 Demo / 業務展示**
- 角色Kneron / Innovedus 業務或技術支援人員
- 目標:向潛在客戶展示 Kneron NPU 的 AI 推論能力
- 技術素養:低至中等
- 痛點:需要一個無需開發、開箱即用的展示工具
**⚠️ 待確認**:上述 Persona 定義是從產品功能推斷。實際目標客群請與產品負責人確認。
### 1.3 應用名稱對照
| 名稱 | 用途 |
|------|------|
| KNEO Academy | 專案內部/開發用名稱 |
| Innovedus AI Playground | 對外正式名稱(`APP_NAME` 常數定義) |
---
## 2. 支援的硬體裝置
應用程式目前支援以下 Kneron NPU Dongle 型號(來自 `config.py``DeviceType` Enum
| 裝置型號 | Product IDHex | 支援狀態 |
|---------|-----------------|---------|
| KL520 | 0x100 | ✅ 已支援(有 icon、model map |
| KL720 | 0x720 | ✅ 已支援(有 icon、model map |
| KL720_L | 0x200 | ⚠️ Enum 有定義,但無 DongleModelMap 對應,**可能不完整** |
| KL530 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 |
| KL832 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 |
| KL730 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 |
| KL630 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 |
| KL540 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 |
**⚠️ 待確認**KL520 和 KL720 以外的裝置是否已在計畫中支援?`DongleModelMap` 僅有這兩型。
---
## 3. 應用程式頁面架構
### 3.1 頁面流程圖
```
應用程式啟動
SelectionScreen首頁 / 入口選擇畫面)
├── [Demo App 按鈕] ──────────────────→ MainWindowAI Demo 推論主視窗)
└── [Utilities 按鈕] → LoginScreen登入畫面
├── [登入成功] → UtilitiesScreen裝置管理工具
└── [返回] → SelectionScreen
```
### 3.2 各頁面功能摘要
| 頁面 | Class 名稱 | 主要用途 | 需要登入 |
|------|-----------|---------|---------|
| 首頁 | `SelectionScreen` | 選擇進入 Demo App 或 Utilities 工具 | 否 |
| 登入畫面 | `LoginScreen` | Server 驗證,作為進入 Utilities 的門禁 | — |
| 裝置管理工具 | `UtilitiesScreen` | 裝置掃描、韌體更新、驅動安裝、已購項目 | 是 |
| AI Demo 主視窗 | `MainWindow` | AI 推論執行、攝影機顯示、工具選擇 | 否 |
---
## 4. 功能需求
### 4.1 SelectionScreen首頁選擇畫面
**功能描述**:應用程式的入口,提供兩個主要路徑。
**功能清單**
- 顯示應用程式 Logo 與名稱
- 「Demo App」按鈕直接進入 AI 推論主視窗(不需登入)
- 「Utilities」按鈕跳轉到登入畫面登入後才能進入裝置管理工具
**⚠️ 待確認**:首頁是否有其他 UI 元素(介紹文字、版本號等)?
---
### 4.2 LoginScreen登入畫面
**功能描述**:透過 Server 驗證機制保護 Utilities 功能的存取。
**功能清單**
- 帳號密碼輸入欄位
- 登入按鈕 → 觸發 Server 驗證
- 返回按鈕 → 回到 SelectionScreen
**登入結果處理**
| 情境 | 行為 |
|------|------|
| 驗證成功 | 發出 `login_success` signal → 進入 UtilitiesScreen |
| 帳密錯誤 | 顯示「無效用戶名或密碼」提示 |
| 多次錯誤 | Server 停止服務,顯示提示訊息 |
| 返回 | 發出 `back_to_selection` signal → 回到 SelectionScreen |
**⚠️ 待確認**
- 登入 Server 的端點 URL 在哪裡設定?(程式碼中未見明確設定)
- 是否有記住密碼/Token 快取機制?
---
### 4.3 UtilitiesScreen裝置管理工具頁面
**功能描述**:登入後才能存取的裝置管理介面,包含兩個子頁面。
#### 4.3.1 Utilities 子頁面(裝置管理)
**功能清單**
**裝置掃描與列表**
- 掃描當前連接的 Kneron dongle 裝置(呼叫 `check_available_device()`,含 5 秒 timeout
- 以表格(`QTableWidget`顯示裝置清單欄位包含裝置型號、KN Number、狀態
- 「Refresh」按鈕重新掃描裝置
- 未偵測到裝置時顯示提示
**裝置連接操作**
- 選擇裝置後可執行連接(透過 `DeviceController.connect_device()`
- 連接過程:
1. 驗證 firmware 檔案是否存在(`%LOCALAPPDATA%/Kneron_Academy/firmware/{device}/`
2. 呼叫 `kp.core.connect_devices()`
3. 上傳 firmware`fw_scpu.bin` + `fw_ncpu.bin`
- 中斷連接按鈕(`DeviceController.disconnect_device()`
**Firmware 管理**
- 顯示目前 Firmware 版本
- 偵測到版本需要更新時,提示使用者是否更新
- 支援從本機載入 firmware 檔案進行更新
**Driver 管理**(⚠️ 設計中,尚未完整實作)
- 偵測 Kneron USB driver 是否已安裝
- 尚未安裝時:提示安裝,詢問使用者是否執行安裝程序
- 安裝失敗處理:顯示錯誤訊息
**Dongle 授權管理**(⚠️ 設計中,尚未完整實作)
- 查詢 KN NumberDongle 唯一識別號)
- 授權卡Authorization Card驗證流程
- 已授權裝置:顯示已授權提示
- 未授權裝置:詢問是否啟動授權,執行授權流程
- **詳細流程見 `flowchart.md`**
**狀態顯示**
- `QProgressBar`:顯示操作進度(連接、韌體上傳等)
- `QLabel`status_label顯示目前狀態訊息
#### 4.3.2 Purchased Items 子頁面(已購項目)
**功能描述**:顯示用戶已購買的 AI 模型,可以下載到本機。
**功能清單**
- 表格顯示已購買項目欄位Select勾選、Product產品名、Model模型名、Current Version版本、Compatible Dongles相容裝置
- 多選Checkbox功能
- 「Refresh Items」按鈕重新從 Server 取得已購列表
- 「Download Selected」按鈕下載所選項目到本機
**⚠️ 待確認**
- 目前程式碼中有 `populate_mock_purchased_items()` 方法,顯示此功能使用 Mock 資料,**尚未對接真實 API**
- 下載後的模型存放路徑?(推斷為 `%LOCALAPPDATA%/Kneron_Academy/utils/`
- 購買平台/Store 是否已確定?
---
### 4.4 MainWindowAI Demo 推論主視窗)
**功能描述**:核心的 AI 推論展示視窗,整合攝影機顯示、工具選擇與推論結果呈現。
#### 4.4.1 畫面布局組件
| 組件 | Class 名稱 | 功能 |
|------|-----------|------|
| 攝影機顯示區 | `CanvasArea` | 顯示攝影機畫面和推論結果Bounding Box 等) |
| 裝置清單 | `DeviceList` | 顯示可連接的 dongle讓使用者選擇 |
| 裝置連接彈窗 | `DevicePopup` | 彈出式裝置連接確認介面 |
| 媒體控制面板 | `MediaPanel` | 攝影機開啟/暫停、圖片上傳按鈕 |
| AI 工具箱 | `Toolbox` | 顯示可選擇的 AI 模型(來自 config.json |
| 自定義模型上傳 | `CustomModelBlock` | 上傳自定義 .nef 模型的 UI |
#### 4.4.2 AI 推論模式
##### 模式一Video 模式(即時攝影機推論)
**流程**
1. 使用者選擇 Video 類型的 AI 工具
2. 呼叫 `MediaController.start_camera()` 啟動相機
3. `VideoThread` 持續擷取影像幀640×480, 30fps轉為 QImage 發出 signal
4. 影像幀轉為 NumPy 陣列後,透過 `InferenceController.add_frame_to_queue()` 放入推論 queue最大容量5 幀)
5. `InferenceWorkerThread` 從 queue 取出影像幀,呼叫對應的 `script.py` 執行推論
6. 推論結果透過 `inference_result_signal` 傳回主視窗
7. 主視窗在 `CanvasArea` 上繪製 Bounding Box 等視覺化結果
**效能優化機制**
- MSEMean Squared Error幀差異偵測若連續幀的 MSE 低於 `mse_threshold=500`,沿用上一次推論結果(避免重複計算靜止畫面)
- 最短推論間隔:`min_interval=2` 秒(標準模式)
- 模型超時設定:`MODEL_TIMEOUT = 5000` ms`config.py`
##### 模式二Image 模式(上傳圖片單次推論)
**流程**
1. 使用者選擇 Image 類型的 AI 工具
2. 使用者透過 `MediaPanel` 上傳圖片(存入 `%LOCALAPPDATA%/Kneron_Academy/uploads/`
3. 使用 `cv2.imread()` 讀取圖片,放入推論 queue`once_mode=True`,只推論一次)
4. `InferenceWorkerThread` 執行推論並回傳結果
5. 切換到 Image 模式時,相機信號會暫時斷開(非停止),以避免 Video 模式的幀繼續進入 queue
**注意**:切回 Video 工具時,相機信號會重新連接,無需重新開啟相機。
##### 模式三Custom Model使用者自定義模型
**流程**
1. 使用者透過 `CustomModelBlock` 上傳以下三個檔案:
- `.nef` 模型檔
- `fw_scpu.bin`SCPU firmware
- `fw_ncpu.bin`NCPU firmware
- 可選自定義標籤清單class labels
2. `InferenceController.select_custom_tool()` 被呼叫
3. 啟動 `CustomInferenceWorkerThread`(與標準 worker 不同的實作)
4. Custom worker 會在首次推論時自行完成:
- 連接裝置(`kp.core.connect_devices()`
- 上傳 firmware
- 上傳模型(`kp.core.load_model_from_file()`
5. 預處理:影像縮放至 640×640轉為 BGR565 格式
6. 後處理:使用 YOLOv5 演算法NMS threshold=0.5)解析輸出
7. 若有提供自定義標籤,使用自定義標籤;否則使用預設 COCO 80 類別
**Custom Model 預設行為**
- 輸入類型Video即時攝影機
- 後處理演算法:固定使用 YOLOv5**⚠️ 待確認**:是否計畫支援其他後處理演算法?)
- 預設偵測閾值:`thresh=0.2`
- 推論間隔:`min_interval=0.5` 秒(比標準模式更頻繁)
#### 4.4.3 裝置相容性檢查
當使用者選擇 AI 工具時:
- 讀取 `config.json` 中的 `compatible_devices` 欄位
- 比對目前選中的 dongle 型號
- 若不相容,彈出警告對話框並阻止推論啟動
---
### 4.5 Plugin 系統Script & Model 配置)
**功能描述**:透過設定檔驅動的 Plugin 架構,讓 AI 模型能被動態載入,無需修改應用程式原始碼。
#### 4.5.1 檔案結構
```
%LOCALAPPDATA%/Kneron_Academy/
├── uploads/ # 使用者上傳的圖片/影片
├── utils/
│ ├── config.json # 全域 plugin 設定(必要)
│ └── {mode}/ # 推論模式資料夾e.g., face_recognition
│ └── {model}/ # 模型資料夾e.g., face_detection
│ ├── config.json # 模型設定(必要)
│ ├── script.py # 推論腳本(必要)
│ └── *.nef # 模型檔(必要)
└── firmware/
└── {device}/ # 裝置型號資料夾e.g., KL520
├── fw_scpu.bin
└── fw_ncpu.bin
```
#### 4.5.2 全域 config.json 格式
```json
{
"plugins": [
{
"mode": "face_recognition",
"display_name": "人臉辨識",
"models": [
{
"name": "face_detection",
"display_name": "人臉偵測 (ResNet-18)",
"description": "基於ResNet-18的高精度人臉偵測",
"compatible_devices": ["KL520", "KL720"]
}
]
}
]
}
```
#### 4.5.3 模型 config.json 格式
```json
{
"display_name": "人臉偵測 (ResNet-18)",
"description": "使用ResNet-18架構的高精度人臉偵測模型",
"model_file": "face_detection.nef",
"input_info": {
"type": "video",
"supported_formats": ["mp4", "avi", "webm"]
},
"input_parameters": {
"threshold": 0.75,
"max_faces": 10,
"tracking": true
},
"compatible_devices": ["KL520", "KL720"]
}
```
**`input_info.type` 的有效值**
- `"video"` — 啟動攝影機進行即時推論
- `"image"` — 使用者上傳圖片進行單次推論
- `"voice"` — 音訊輸入模式(⚠️ **程式碼中有對應處理路徑但未見完整實作**
#### 4.5.4 script.py 介面規範
`InferenceWorkerThread` 會動態 import 各模型的 `script.py`
**⚠️ 待確認(重要)**`script.py` 的標準介面(函數名稱、參數格式、回傳格式)目前無正式文件。
`InferenceWorkerThread` 的呼叫方式推斷:
- `script.py` 應提供一個可被 worker 呼叫的推論函數
- 接收 `input_params` 字典(包含 `usb_port_id``device_group``model``scpu_path``ncpu_path``file_path` 等)
- 回傳 Bounding Box 結果,格式為:
```json
{
"num_boxes": 2,
"bounding boxes": [[x1, y1, x2, y2], [x3, y3, x4, y4]],
"results": ["label1", "label2"]
}
```
---
## 5. 非功能需求
### 5.1 效能需求
| 項目 | 規格 | 來源 |
|------|------|------|
| 推論 Queue 大小 | 最大 5 幀 | `InferenceController.__init__` |
| 標準模式最短推論間隔 | 2 秒 | `InferenceController.select_tool()` |
| Custom Model 最短推論間隔 | 0.5 秒 | `InferenceController.select_custom_tool()` |
| 模型推論超時 | 5,000 ms | `config.py MODEL_TIMEOUT` |
| 裝置掃描超時 | 5 秒 | `device_service.check_available_device()` |
| 攝影機開啟超時 | 5 秒 / 最多 3 次嘗試 | `VideoThread._camera_timeout` |
| 攝影機解析度 | 640×480 | `VideoThread.run()` |
| 攝影機目標幀率 | 30 fps | `VideoThread.run()` |
| Custom Model 輸入大小 | 640×640 | `custom_inference_worker.preprocess_frame()` |
| 模型推論設備超時Custom | 5,000 ms | `CustomInferenceWorkerThread.initialize_device()` |
### 5.2 平台相容性
| 項目 | 規格 |
|------|------|
| 作業系統 | Windows使用 `%LOCALAPPDATA%`PowerInstaller 打包) |
| Python 版本 | Python 3.12 |
| 視窗尺寸 | 1200×900 像素(固定,`WINDOW_SIZE` 常數) |
**⚠️ 待確認**:是否計畫支援 macOS 或 Linux目前路徑處理和打包設定為 Windows 專屬。
### 5.3 應用程式打包
| 項目 | 工具 | 狀態 |
|------|------|------|
| 打包工具 | PyInstaller 6.12.0 | ✅ 已設定 |
| 安裝包製作 | Inno Setup`dist/test.iss` | ✅ 有設定檔 |
| 程式碼加密 | PyArmor | ⚠️ 計畫中 |
**打包注意事項**
- 需要包含 KneronPLUS SDK 的 `kp/lib` 資料夾
- 需包含 `uxui/` 資源目錄和 `src/` 目錄
### 5.4 資料儲存
所有執行期資料存放於 `%LOCALAPPDATA%/Kneron_Academy/`
- **uploads/**:使用者上傳的圖片/影片
- **utils/**Plugin 設定與模型檔案
- **firmware/**:裝置韌體檔案
**⚠️ 待確認**:安裝包是否會預先建立這些目錄,或由應用程式首次執行時自動建立?
---
## 6. 裝置連接與授權流程(詳細)
根據 `flowchart.md` 的設計(⚠️ 此流程尚未完整實作於程式碼中,為設計規格):
```
登入畫面
Server 驗證(帳密驗證)
├── 成功 → 進入 Dongle 模組畫面
└── 失敗 → 顯示錯誤(帳密錯誤 / 服務被暫停)
Dongle 模組畫面
連接 Dongle
├── 未偵測到 → 顯示「未偵測到裝置」提示
└── 偵測到 → 檢查 Driver 是否安裝
Driver 檢查
├── 已安裝 → 檢查 FW 版本
└── 未安裝 → 詢問是否安裝 Driver
├── 使用者同意 → 執行安裝(可能失敗)
└── 失敗 → 顯示錯誤
FW 版本檢查
├── 版本符合 → 取得 Dongle KN Number
└── 需要更新 → 詢問是否更新 FW
├── 使用者同意 → 下載並安裝 FW
└── 失敗 → 顯示錯誤
取得 KN Number
└── 成功 → 檢查授權狀態
授權狀態檢查
├── 已授權 → 顯示已授權提示 → 回到 App 主頁
└── 未授權 → 詢問是否啟動授權
├── 使用者同意 → 執行授權流程
│ ├── 成功 → 顯示成功提示 → 回到主頁
│ └── 失敗 → 顯示失敗提示
└── 使用者不重試 → 顯示提示 → 回到主頁
```
---
## 7. 已知限制與未完成功能
以下為從程式碼分析發現的限制與尚未完成的功能:
### 7.1 尚未完整實作
| 功能 | 狀態 | 說明 |
|------|------|------|
| 登入 Server 驗證 | 🔄 部分實作 | `LoginScreen` 存在,但 Server 端點設定不明確 |
| Driver 自動安裝 | 🔄 設計中 | `flowchart.md` 有設計,程式碼中未見完整實作 |
| Dongle 授權管理 | 🔄 設計中 | `flowchart.md` 有設計,程式碼中未見完整實作 |
| 音訊voice推論模式 | 🔄 設計中 | `config.py` 有引入 `librosa`、`sounddevice`,但推論路徑不完整 |
| Purchased Items API 對接 | 🔄 Mock 資料 | `utilities_screen.py` 有 `populate_mock_purchased_items()` 方法,使用假資料 |
| 程式碼加密PyArmor | ⏳ 計畫中 | 僅列在 `env.txt`,尚未見到具體加密流程 |
| KL520/KL720 以外裝置支援 | ⏳ 計畫中 | `DeviceType` enum 有定義,但 `DongleModelMap` 僅有這兩型 |
### 7.2 已知技術問題
| 問題 | 嚴重度 | 說明 |
|------|--------|------|
| Debug print 語句殘留 | 低 | 多個 controller 中有大量 `print()` debug 訊息 |
| 錯誤處理不完整 | 中 | 部分 try/except 只 print 不處理(如 `device_controller.py` |
| 測試覆蓋率為零 | 高 | 完全沒有自動化測試 |
| UI 更新 Thread 安全性 | 中 | 待確認推論結果回傳到主線程的路徑是否完全使用 Qt Signal |
| `custom_inference_worker.py` 中引用未導入的 `kp` | 中 | `_boxes_scale()` 和 `post_process_yolo_v5()` 在模組頂層使用 `kp.HwPreProcInfo` 等型別,但 `import kp` 在函數內才執行 |
### 7.3 設計假設(未驗證)
- Custom Model 後處理固定使用 YOLOv5未提供自定義後處理的擴充機制
- 應用程式假設攝影機 index 為 0第一個相機無法選擇其他相機
- 應用程式固定使用 Windows 路徑格式,不支援跨平台
---
## 8. 功能優先級RICE 分析)
> ⚠️ 以下 RICE 分數為從現有程式碼功能狀態推斷Effort 值基於程式碼完成度估算。**請與產品負責人及開發團隊確認 Reach、Impact 和 Confidence 的實際數值。**
| 功能 | Reach | Impact | Confidence | Effort人天 | RICE 分數 | 階段 |
|------|-------|--------|------------|--------------|----------|------|
| Video 模式推論 | 100% | 3 | 90% | — | 高 | ✅ 已完成 |
| Image 模式推論 | 90% | 2 | 90% | — | 高 | ✅ 已完成 |
| Plugin 系統config.json | 100% | 3 | 85% | — | 高 | ✅ 已完成 |
| Custom Model 推論 | 60% | 3 | 80% | — | 中高 | ✅ 已完成 |
| 裝置掃描 / 連接 | 100% | 3 | 90% | — | 高 | ✅ 已完成 |
| 登入驗證(完整實作) | 100% | 3 | 70% | 5 | 高 | 🔄 進行中 |
| Dongle 授權管理 | 100% | 3 | 65% | 10 | 高 | 🔄 設計中 |
| Purchased Items API 對接 | 80% | 2 | 70% | 7 | 中 | 🔄 設計中 |
| Driver 自動安裝 | 70% | 2 | 60% | 5 | 中 | 🔄 設計中 |
| 音訊推論模式 | 40% | 2 | 50% | 10 | 低中 | ⏳ 待實作 |
| 多攝影機選擇 | 30% | 1 | 70% | 3 | 低 | ⏳ 未排期 |
| 跨平台支援macOS/Linux | 50% | 2 | 50% | 20 | 中 | ⏳ 未排期 |
---
## 9. 輸入資料格式規範
### 9.1 攝影機影像
- 擷取方式OpenCV `cv2.VideoCapture`DirectShow backendWindows 優先)
- 解析度640×480
- 格式:`QImage.Format_RGB888`(透過 `VideoThread` 發出),後轉為 NumPy 陣列 `(height, width, 3)`,通道順序 RGB888
### 9.2 上傳圖片
- 讀取方式:`cv2.imread()`
- 格式NumPy 陣列BGR 格式OpenCV 預設)
- 儲存位置:`%LOCALAPPDATA%/Kneron_Academy/uploads/`
### 9.3 Custom Model 輸入(預處理後)
- 目標大小640×640
- 格式BGR565`cv2.COLOR_BGR2BGR565`
### 9.4 input_params 字典格式
`InferenceWorkerThread` 接收的 `input_params` 標準結構:
```python
{
"usb_port_id": 32, # Dongle USB port ID
"device_group": <kp.DeviceGroup>, # 已連接的裝置群組物件
"scpu_path": "...\\firmware\\KL520\\fw_scpu.bin",
"ncpu_path": "...\\firmware\\KL520\\fw_ncpu.bin",
"fw_folder": "...\\firmware", # 全域 firmware 目錄
"file_path": "...\\uploads\\image.jpg", # 圖片模式使用
"model": "...\\utils\\{mode}\\{model}\\{model_file}.nef",
"model_descriptor": <kp.ModelDescriptor>, # 已上傳的模型描述符
# 以下為 config.json 中的 input_parameters 欄位(由模型設定決定)
"threshold": 0.75,
"max_faces": 10,
...
}
```
---
## 10. 推論結果輸出格式
`script.py` 回傳或 `CustomInferenceWorkerThread` 發出的標準推論結果:
```json
{
"num_boxes": 2,
"bounding boxes": [[x1, y1, x2, y2], [x3, y3, x4, y4]],
"results": ["label1", "label2"]
}
```
其中座標為絕對像素值,對應原始影像尺寸(非縮放後的模型輸入尺寸)。
---
## 11. 安裝需求
### 11.1 開發環境安裝
```shell
# 1. 安裝 KneronPLUS SDK
cd ./external/kneron_plus_{version}/package/{platform}/
pip install KneronPLUS-{version}-py3-none-any.whl
# 2. 安裝其他依賴
pip install PyQt5 opencv-python pyinstaller pyarmor
# 3. 執行應用程式
python main.py
```
### 11.2 打包指令
```shell
pyinstaller --onefile --windowed main.py \
--additional-hooks-dir=hooks \
--add-data "uxui;uxui" \
--add-data "src;src" \
--add-data "{conda_env}\\Lib\\site-packages\\kp\\lib;kp\\lib"
```
---
## 12. 風險與緩解措施
| 風險 | 可能性 | 影響 | 緩解措施 |
|------|--------|------|----------|
| `script.py` 介面無標準文件,第三方難以開發 Plugin | 高 | 高 | 盡速制定並文件化 `script.py` 介面規範 |
| Purchased Items 功能仍是 Mock 資料,影響客戶體驗 | 中 | 高 | 確認後端 API 規格,完成對接 |
| 缺乏自動化測試,難以安全重構 | 高 | 中 | 補齊關鍵路徑的 unit test推論 queue、裝置連接 |
| `custom_inference_worker.py` 的 `kp` 引入問題,可能在非 kp 環境崩潰 | 中 | 中 | 修復模組頂層的型別引用問題 |
| 硬體相依性強,無 dongle 時無法測試核心功能 | 高 | 中 | 建立 Mock/Stub 的 kp 測試層 |
| Windows 專屬設計,未來擴展平台成本高 | 低 | 中 | 現階段維持 Windows 優先,抽象化路徑處理為未來鋪路 |
---
## 附錄 A程式碼結構快速參照
| 模組 | 路徑 | 功能 |
|------|------|------|
| `AppController` | `main.py` | 應用程式入口,管理 QStackedWidget 頁面切換 |
| `SelectionScreen` | `src/views/selection_screen.py` | 首頁選擇畫面 |
| `LoginScreen` | `src/views/login_screen.py` | 登入驗證畫面 |
| `UtilitiesScreen` | `src/views/utilities_screen.py` | 裝置管理工具頁面 |
| `MainWindow` | `src/views/mainWindows.py` | AI 推論主視窗 |
| `DeviceController` | `src/controllers/device_controller.py` | 裝置掃描、連接、中斷 |
| `InferenceController` | `src/controllers/inference_controller.py` | 推論工具選擇、queue 管理 |
| `MediaController` | `src/controllers/media_controller.py` | 攝影機操作 |
| `InferenceWorkerThread` | `src/models/inference_worker.py` | 標準推論 Worker動態載入 script.py |
| `CustomInferenceWorkerThread` | `src/models/custom_inference_worker.py` | Custom Model 推論 WorkerYOLOv5 後處理) |
| `VideoThread` | `src/models/video_thread.py` | 攝影機影像擷取 Thread |
| `check_available_device()` | `src/services/device_service.py` | 含 timeout 的裝置掃描服務 |
| `DeviceType`, `DongleModelMap` | `src/config.py` | 支援裝置型號列舉與對應表 |
---
*本 PRD 版本v1.0(從程式碼反推)*
*建立日期2026-04-04*
*建立者PM AgentAutoflow*
*狀態:待產品負責人確認標注「⚠️ 待確認」的項目*