

終止支援通知：2026 年 5 月 31 日， AWS 將終止對 的支援 AWS Panorama。2026 年 5 月 31 日之後，您將無法再存取 AWS Panorama 主控台或 AWS Panorama 資源。如需詳細資訊，請參閱[AWS Panorama 終止支援](https://docs.aws.amazon.com/panorama/latest/dev/panorama-end-of-support.html)。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 建置 AWS Panorama 應用程式
<a name="panorama-development"></a>

應用程式會在 AWS Panorama 設備上執行，以在視訊串流上執行電腦視覺任務。您可以結合 Python 程式碼和機器學習模型來建置電腦視覺應用程式，並透過網際網路將其部署到 AWS Panorama 設備。應用程式可以將視訊傳送至顯示器，或使用 AWS 開發套件將結果傳送至 AWS 服務。

[模型](applications-models.md)會分析影像以偵測人員、車輛和其他物件。根據在訓練期間看到的影像，模型會告訴您它認為什麼是事物，以及它對猜測的可信度。您可以使用自己的影像資料來訓練模型，或開始使用範例。

應用程式[程式碼](gettingstarted-sample.md)程序仍會處理來自攝影機串流的影像、將其傳送至模型，以及處理結果。模型可能會偵測多個物件，並傳回其形狀和位置。程式碼可以使用此資訊將文字或圖形新增至視訊，或將結果傳送至 AWS 服務以進行儲存或進一步處理。

若要從串流取得影像、與模型互動，以及輸出影片，應用程式程式碼會使用 [AWS Panorama 應用程式開發套件](applications-panoramasdk.md)。應用程式 SDK 是一個 Python 程式庫，支援使用 PyTorch、Apache MXNet 和 TensorFlow 產生的模型。

**Topics**
+ [電腦視覺模型](applications-models.md)
+ [建置應用程式映像](applications-image.md)
+ [從應用程式碼呼叫 AWS 服務](applications-awssdk.md)
+ [AWS Panorama 應用程式開發套件](applications-panoramasdk.md)
+ [執行多個執行緒](applications-threading.md)
+ [提供傳入流量](applications-ports.md)
+ [使用 GPU](applications-gpuaccess.md)
+ [在 Windows 中設定開發環境](applications-devenvwindows.md)

# 電腦視覺模型
<a name="applications-models"></a>

*電腦視覺模型*是經過訓練的軟體程式，可偵測影像中的物件。模型會學習透過訓練先分析這些物件的影像，以辨識一組物件。電腦視覺模型會將影像做為輸入，並輸出其偵測到之物件的相關資訊，例如物件類型及其位置。AWS Panorama 支援使用 PyTorch、Apache MXNet 和 TensorFlow 建置的電腦視覺模型。

**注意**  
如需已使用 AWS Panorama 測試的預先建置模型清單，請參閱[模型相容性](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/model-compatibility.md)。

**Topics**
+ [在程式碼中使用模型](#applications-models-using)
+ [建置自訂模型](#applications-models-custom)
+ [封裝模型](#applications-models-package)
+ [訓練模型](#applications-models-training)

## 在程式碼中使用模型
<a name="applications-models-using"></a>

模型會傳回一或多個結果，其中可能包括偵測到的類別、位置資訊和其他資料的概率。下列範例示範如何從影片串流對影像執行推論，並將模型的輸出傳送至處理函數。

**Example [application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/application.py) – 推論**  

```
    def process_media(self, stream):
        """Runs inference on a frame of video."""
        image_data = preprocess(stream.image,self.MODEL_DIM)
        logger.debug('Image data: {}'.format(image_data))
        # Run inference
        inference_start = time.time()
        inference_results = self.call({"data":image_data}, self.MODEL_NODE)
         # Log metrics
        inference_time = (time.time() - inference_start) * 1000
        if inference_time > self.inference_time_max:
            self.inference_time_max = inference_time
        self.inference_time_ms += inference_time
        # Process results (classification)
        self.process_results(inference_results, stream)
```

下列範例顯示處理基本分類模型結果的函數。範例模型會傳回機率陣列，這是結果陣列中第一個且唯一的值。

**Example [application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/application.py) – 處理結果**  

```
    def process_results(self, inference_results, stream):
        """Processes output tensors from a computer vision model and annotates a video frame."""
        if inference_results is None:
            logger.warning("Inference results are None.")
            return
        max_results = 5
        logger.debug('Inference results: {}'.format(inference_results))
        class_tuple = inference_results[0]
        enum_vals = [(i, val) for i, val in enumerate(class_tuple[0])]
        sorted_vals = sorted(enum_vals, key=lambda tup: tup[1])
        top_k = sorted_vals[::-1][:max_results]
        indexes =  [tup[0] for tup in top_k]

        for j in range(max_results):
            label = 'Class [%s], with probability %.3f.'% (self.classes[indexes[j]], class_tuple[0][indexes[j]])
            stream.add_label(label, 0.1, 0.1 + 0.1*j)
```

應用程式程式碼會尋找機率最高的值，並將其映射到初始化期間載入的資源檔案中的標籤。

## 建置自訂模型
<a name="applications-models-custom"></a>

您可以在 AWS Panorama 應用程式中使用在 PyTorch、Apache MXNet 和 TensorFlow 中建置的模型。除了在 SageMaker AI 中建置和訓練模型之外，您也可以使用訓練模型，或使用支援的架構建置和訓練自己的模型，並在本機環境或 Amazon EC2 中匯出模型。

**注意**  
如需 SageMaker AI Neo 支援的架構版本和檔案格式的詳細資訊，請參閱《Amazon SageMaker AI 開發人員指南》中的[支援的架構](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html)。

本指南的 儲存庫提供範例應用程式，以 TensorFlow `SavedModel` 格式示範 Keras 模型的此工作流程。它使用 TensorFlow 2，並且可以在虛擬環境或 Docker 容器中在本機執行。範例應用程式也包含範本和指令碼，用於在 Amazon EC2 執行個體上建置模型。

****
+ [自訂模型範例應用程式](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/custom-model)

![\[\]](http://docs.aws.amazon.com/zh_tw/panorama/latest/dev/images/sample-custom-model.png)


AWS Panorama 使用 SageMaker AI Neo 編譯模型，用於 AWS Panorama 設備。對於每個架構，請使用 [ SageMaker AI Neo 支援的格式](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-compilation-preparing-model.html)，並將模型封裝在`.tar.gz`封存中。

如需詳細資訊，請參閱《Amazon SageMaker AI 開發人員指南》中的[使用 Neo 編譯和部署模型](https://docs.aws.amazon.com/sagemaker/latest/dg/neo.html)。

## 封裝模型
<a name="applications-models-package"></a>

模型套件包含描述項、套件組態和模型封存。與[應用程式映像套件](applications-image.md)一樣，套件組態會通知 AWS Panorama 服務，模型和描述符存放在 Amazon S3 中。

**Example [packages/123456789012-SQUEEZENET\$1PYTORCH-1.0/descriptor.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SQUEEZENET_PYTORCH-1.0/descriptor.json)**  

```
{
    "mlModelDescriptor": {
        "envelopeVersion": "2021-01-01",
        "framework": "PYTORCH",
        "frameworkVersion": "1.8",
        "precisionMode": "FP16",
        "inputs": [
            {
                "name": "data",
                "shape": [
                    1,
                    3,
                    224,
                    224
                ]
            }
        ]
    }
}
```

**注意**  
僅指定架構版本的主要和次要版本。如需支援的 PyTorch、Apache MXNet 和 TensorFlow 版本清單，請參閱[支援的架構](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html)。

若要匯入模型，請使用 AWS Panorama Application CLI `import-raw-model`命令。如果您對模型或其描述項進行任何變更，則必須重新執行此命令來更新應用程式的資產。如需詳細資訊，請參閱[變更電腦視覺模型](gettingstarted-sample.md#gettingstarted-sample-model)。

如需描述項檔案的 JSON 結構描述，請參閱 [assetDescriptor.schema.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/manifest-schema/ver_2021-01-01/assetDescriptor.schema.json)。

## 訓練模型
<a name="applications-models-training"></a>

當您訓練模型時，請使用目標環境的影像，或從與目標環境非常相似的測試環境。請考慮可能影響模型效能的下列因素：

****
+ **照明** – 主體反射的光線量決定模型必須分析的細節。使用光線良好的主題影像訓練的模型可能無法在光線不足或背光的環境中正常運作。
+ **解析度** – 模型的輸入大小通常以方形長寬比固定為 224 到 512 像素寬的解析度。將影片影格傳遞至模型之前，您可以縮減或裁切影片，以符合所需的大小。
+ **影像失真** – 相機的焦距和鏡頭形狀可能會導致影像偏離影格中心。攝影機的位置也會決定可看見主體的哪些功能。例如，具有廣角鏡頭的頭頂攝影機會在主體位於影格中心時顯示其頂部，並在主體遠離中心時顯示其側面的傾斜檢視。

若要解決這些問題，您可以在將影像傳送到模型之前預先處理影像，並在反映真實環境中差異的更廣泛影像上訓練模型。如果模型需要在照明情況和各種攝影機中操作，您需要更多資料來進行訓練。除了收集更多影像之外，您還可以透過建立現有影像的變體來取得更多訓練資料，這些變體是偏斜或有不同的光源。

# 建置應用程式映像
<a name="applications-image"></a>

AWS Panorama Appliance 會以從您建置的映像匯出的容器檔案系統的形式執行應用程式。您可以在使用 AWS Panorama 應用程式基礎映像作為起點的 Dockerfile 中指定應用程式的相依性和資源。

若要建置應用程式映像，請使用 Docker 和 AWS Panorama 應用程式 CLI。本指南範例應用程式的下列範例示範了這些使用案例。

**Example [package/123456789012-SAMPLE\$1CODE-1.0/Dockerfile](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/Dockerfile)**  

```
FROM public.ecr.aws/panorama/panorama-application
WORKDIR /panorama
COPY . .
RUN pip install --no-cache-dir --upgrade pip && \
    pip install --no-cache-dir -r requirements.txt
```

使用下列 Dockerfile 指示。

****
+ `FROM` – 載入應用程式基礎映像 (`public.ecr.aws/panorama/panorama-application`)。
+ `WORKDIR` – 在映像上設定工作目錄。 `/panorama` 用於應用程式程式碼和相關檔案。此設定只會在建置期間持續進行，不會影響應用程式在執行時間 () 的工作目錄`/`。
+ `COPY` – 將檔案從本機路徑複製到映像上的路徑。 會將目前目錄 （套件目錄） 中的檔案`COPY . .`複製到映像上的工作目錄。例如，應用程式程式碼會從 複製到 `packages/123456789012-SAMPLE_CODE-1.0/application.py` `/panorama/application.py`。
+ `RUN` – 在建置期間對映像執行 Shell 命令。單一`RUN`操作可在命令`&&`之間使用 依序執行多個命令。此範例會更新`pip`套件管理員，然後安裝 中列出的程式庫`requirements.txt`。

您可以使用其他在建置時有用的指示`ARG`，例如 `ADD`和 。將執行時間資訊新增至容器的指示，例如 `ENV`，不適用於 AWS Panorama。AWS Panorama 不會從映像執行容器。它只會使用映像來匯出檔案系統，該系統會傳輸至設備。

## 指定相依性
<a name="applications-image-dependencies"></a>

`requirements.txt` 是一種 Python 需求檔案，可指定應用程式使用的程式庫。範例應用程式使用 Open CV 和 適用於 Python (Boto3) 的 AWS SDK。

**Example [package/123456789012-SAMPLE\$1CODE-1.0/requirements.txt](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/requirements.txt)**  

```
boto3==1.24.*
opencv-python==4.6.*
```

Dockerfile 中的 `pip install`命令會將這些程式庫安裝到 下的 Python `dist-packages`目錄`/usr/local/lib`，以便您的應用程式程式碼可以匯入這些程式庫。

## 本機儲存體
<a name="applications-image-storage"></a>

AWS Panorama 會保留應用程式儲存的`/opt/aws/panorama/storage`目錄。您的應用程式可以在此路徑建立和修改檔案。在儲存目錄中建立的檔案會在重新啟動時保留。其他暫存檔案位置會在開機時清除。

## 建置映像資產
<a name="applications-image-build"></a>

當您使用 AWS Panorama Application CLI 建置應用程式套件的映像時，CLI `docker build`會在套件目錄中執行。這會建置包含應用程式程式碼的應用程式映像。然後，CLI 會建立容器、匯出其檔案系統、壓縮容器，並將其存放在`assets`資料夾中。

```
$ panorama-cli build-container --container-asset-name code_asset --package-path packages/123456789012-SAMPLE_CODE-1.0
docker build -t code_asset packages/123456789012-SAMPLE_CODE-1.0 --pull
docker export --output=code_asset.tar $(docker create code_asset:latest)
gzip -1 code_asset.tar
{
    "name": "code_asset",
    "implementations": [
        {
            "type": "container",
            "assetUri": "6f67xmpl32743ed0e60c151a02f2f0da1bf70a4ab9d83fe236fa32a6f9b9f808.tar.gz",
            "descriptorUri": "1872xmpl129481ed053c52e66d6af8b030f9eb69b1168a29012f01c7034d7a8f.json"
        }
    ]
}
Container asset for the package has been succesfully built at  /home/user/aws-panorama-developer-guide/sample-apps/aws-panorama-sample/assets/6f67xmpl32743ed0e60c151a02f2f0da1bf70a4ab9d83fe236fa32a6f9b9f808.tar.gz
```

輸出中的 JSON 區塊是資產定義，CLI 會將其新增至套件組態 (`package.json`)，並使用 AWS Panorama 服務註冊。CLI 也會複製描述項檔案，指定應用程式指令碼的路徑 （應用程式的進入點）。

**Example [package/123456789012-SAMPLE\$1CODE-1.0/descriptor.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/descriptor.json)**  

```
{
    "runtimeDescriptor":
    {
        "envelopeVersion": "2021-01-01",
        "entry":
        {
            "path": "python3",
            "name": "/panorama/application.py"
        }
    }
}
```

在資產資料夾中，描述符和應用程式映像會針對其 SHA-256 檢查總和命名。儲存資產時，此名稱會用作資產的唯一識別符，即為 Amazon S3。

# 從應用程式碼呼叫 AWS 服務
<a name="applications-awssdk"></a>

您可以使用 從應用程式程式碼 適用於 Python (Boto) 的 AWS SDK 呼叫 AWS 服務。例如，如果您的模型偵測到不尋常的情況，您可以將指標發佈至 Amazon CloudWatch、使用 Amazon SNS 傳送通知、將映像儲存至 Amazon S3，或叫用 Lambda 函數進行進一步處理。大多數 AWS 服務都具有可搭配 AWS 開發套件使用的公有 API。

根據預設，設備沒有存取任何 AWS 服務的許可。若要授予許可，[請為應用程式建立角色](permissions-application.md)，並在部署期間將其指派給應用程式執行個體。

**Topics**
+ [使用 Amazon S3](#applications-awssdk-s3)
+ [使用 AWS IoT MQTT 主題](#monitoring-messagestream)

## 使用 Amazon S3
<a name="applications-awssdk-s3"></a>

您可以使用 Amazon S3 來存放處理結果和其他應用程式資料。

```
import boto3
s3_client=boto3.client("s3")
s3_clients3.upload_file(data_file,
                    s3_bucket_name,
                    os.path.basename(data_file))
```

## 使用 AWS IoT MQTT 主題
<a name="monitoring-messagestream"></a>

您可以使用適用於 Python 的 SDK (Boto3) 將訊息傳送到 中的 [MQTT 主題](https://docs.aws.amazon.com/iot/latest/developerguide/topics.html) AWS IoT。在下列範例中，應用程式會張貼到以設備*物件名稱*命名的主題，您可以在 [AWS IoT 主控台](https://console.aws.amazon.com/iot/home#/thinghub)中找到。

```
import boto3
iot_client=boto3.client('iot-data')
topic = "panorama/panorama_my-appliance_Thing_a01e373b"
iot_client.publish(topic=topic, payload="my message")
```

選擇指出裝置 ID 或您選擇的其他識別符的名稱。若要發佈訊息，應用程式需要呼叫 的許可`iot:Publish`。

**監控 MQTT 佇列**

1. 開啟[AWS IoT 主控台測試頁面](https://console.aws.amazon.com/iot/home?region=us-east-1#/test)。

1. 針對**訂閱主題**，輸入主題的名稱。例如：`panorama/panorama_my-appliance_Thing_a01e373b`。

1. 請選擇 **Subscribe to topic** (訂閱主題)。

# AWS Panorama 應用程式開發套件
<a name="applications-panoramasdk"></a>

AWS Panorama 應用程式 SDK 是用於開發 AWS Panorama 應用程式的 Python 程式庫。在[應用程式程式碼](gettingstarted-sample.md)中，您可以使用 AWS Panorama 應用程式開發套件來載入電腦視覺模型、執行推論，並將影片輸出至監視器。

**注意**  
若要確保您可存取 AWS Panorama 應用程式開發套件的最新功能，[請升級設備軟體](appliance-manage.md#appliance-manage-software)。

如需應用程式開發套件定義之類別及其方法的詳細資訊，請參閱[應用程式開發套件參考](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/applicationsdk-reference.md)。

**Topics**
+ [新增文字和方塊以輸出影片](#applications-panoramasdk-overlays)

## 新增文字和方塊以輸出影片
<a name="applications-panoramasdk-overlays"></a>

使用 AWS Panorama SDK，您可以將影片串流輸出到顯示器。影片可以包含文字和方塊，顯示模型的輸出、應用程式的目前狀態或其他資料。

`video_in` 陣列中的每個物件都是來自連接到設備的攝影機串流的影像。此物件的類型為 `panoramasdk.media`。它有將文字和矩形方塊新增至映像的方法，然後您可以指派給`video_out`陣列。

在下列範例中，範例應用程式會為每個結果新增標籤。每個結果都位於相同的左側位置，但高度不同。

```
        for j in range(max_results):
            label = 'Class [%s], with probability %.3f.'% (self.classes[indexes[j]], class_tuple[0][indexes[j]])
            stream.add_label(label, 0.1, 0.1 + 0.1*j)
```

若要將方塊新增至輸出映像，請使用 `add_rect`。此方法需要 4 個介於 0 和 1 之間的值，表示方塊左上角和右下角的位置。

```
        w,h,c = stream.image.shape
        stream.add_rect(x1/w, y1/h, x2/w, y2/h)
```

# 執行多個執行緒
<a name="applications-threading"></a>

您可以在處理執行緒上執行應用程式邏輯，並將其他執行緒用於其他背景程序。例如，您可以建立[提供 HTTP 流量](applications-ports.md)進行偵錯的執行緒，或監控推論結果並傳送資料的執行緒 AWS。

若要執行多個執行緒，您可以使用 Python 標準程式庫中的[執行緒模組](https://docs.python.org/3/library/threading.html)來為每個程序建立執行緒。下列範例顯示偵錯伺服器範例應用程式的主迴圈，這會建立應用程式物件，並使用它來執行三個執行緒。

**Example [package/123456789012-DEBUG\$1SERVER-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) – 主迴圈**  

```
def main():
    panorama = panoramasdk.node()
    while True:
        try:
            # Instantiate application
            logger.info('INITIALIZING APPLICATION')
            app = Application(panorama)
            # Create threads for stream processing, debugger, and client
            app.run_thread = threading.Thread(target=app.run_cv)
            app.server_thread = threading.Thread(target=app.run_debugger)
            app.client_thread = threading.Thread(target=app.run_client)
            # Start threads
            logger.info('RUNNING APPLICATION')
            app.run_thread.start()
            logger.info('RUNNING SERVER')
            app.server_thread.start()
            logger.info('RUNNING CLIENT')
            app.client_thread.start()
            # Wait for threads to exit
            app.run_thread.join()
            app.server_thread.join()
            app.client_thread.join()
            logger.info('RESTARTING APPLICATION')
        except:
            logger.exception('Exception during processing loop.')
```

當所有執行緒結束時，應用程式會自行重新啟動。`run_cv` 迴圈處理來自攝影機串流的影像。如果它收到要停止的訊號，則會關閉偵錯工具程序，該程序會執行 HTTP 伺服器且無法自行關閉。每個執行緒都必須處理自己的錯誤。如果未攔截並記錄錯誤，執行緒會以無提示方式結束。

**Example [package/123456789012-DEBUG\$1SERVER-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) – 處理迴圈**  

```
    # Processing loop
    def run_cv(self):
        """Run computer vision workflow in a loop."""
        logger.info("PROCESSING STREAMS")
        while not self.terminate:
            try:
                self.process_streams()
                # turn off debug logging after 15 loops
                if logger.getEffectiveLevel() == logging.DEBUG and self.frame_num == 15:
                    logger.setLevel(logging.INFO)
            except:
                logger.exception('Exception on processing thread.')
        # Stop signal received
        logger.info("SHUTTING DOWN SERVER")
        self.server.shutdown()
        self.server.server_close()
        logger.info("EXITING RUN THREAD")
```

執行緒會透過應用程式的`self`物件進行通訊。若要重新啟動應用程式處理迴圈，除錯器執行緒會呼叫 `stop`方法。此方法會設定`terminate`屬性，以發出其他執行緒關閉的訊號。

**Example [package/123456789012-DEBUG\$1SERVER-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) – 停止方法**  

```
    # Interrupt processing loop
    def stop(self):
        """Signal application to stop processing."""
        logger.info("STOPPING APPLICATION")
        # Signal processes to stop
        self.terminate = True
    # HTTP debug server
    def run_debugger(self):
        """Process debug commands from local network."""
        class ServerHandler(SimpleHTTPRequestHandler):
            # Store reference to application
            application = self
            # Get status
            def do_GET(self):
                """Process GET requests."""
                logger.info('Get request to {}'.format(self.path))
                if self.path == "/status":
                    self.send_200('OK')
                else:
                    self.send_error(400)
            # Restart application
            def do_POST(self):
                """Process POST requests."""
                logger.info('Post request to {}'.format(self.path))
                if self.path == '/restart':
                    self.send_200('OK')
                    ServerHandler.application.stop()
                else:
                    self.send_error(400)
```



# 提供傳入流量
<a name="applications-ports"></a>

您可以搭配應用程式程式碼執行 HTTP 伺服器，在本機監控或偵錯應用程式。若要提供外部流量，請將 AWS Panorama 設備上的連接埠映射至應用程式容器上的連接埠。

**重要**  
根據預設，AWS Panorama 設備不接受任何連接埠上的傳入流量。在設備上開啟連接埠會有隱含的安全風險。使用此功能時，您必須採取其他步驟[來保護您的設備免受外部流量](appliance-network.md)影響，並保護授權用戶端與設備之間的通訊。  
本指南中包含的範例程式碼僅供示範之用，不會實作身分驗證、授權或加密。

您可以在設備上開啟範圍介於 8000–9000 的連接埠。這些連接埠開啟時，可以接收來自任何可路由用戶端的流量。部署應用程式時，您可以指定要開啟的連接埠，並將設備上的連接埠映射到應用程式容器上的連接埠。設備軟體會將流量轉送至容器，並將回應傳回給請求者。請求會在您指定的設備連接埠上收到，而回應則會在隨機暫時性連接埠上傳出。

## 設定傳入連接埠
<a name="applications-ports-configuration"></a>

您可以在應用程式組態的三個位置指定連接埠映射。程式碼套件的 `package.json`，您可以指定程式碼節點在`network`區塊中接聽的連接埠。下列範例宣告節點接聽連接埠 80。

**Example [package/123456789012-DEBUG\$1SERVER-1.0/package.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/package.json)**  

```
                "outputs": [
                    {
                        "description": "Video stream output",
                        "name": "video_out",
                        "type": "media"
                    }
                ],
                "network": {
                    "inboundPorts": [
                        {
                            "port": 80,
                            "description": "http"
                        }
                    ]
                }
```

在應用程式資訊清單中，您會宣告路由規則，將設備上的連接埠映射到應用程式的程式碼容器上的連接埠。下列範例新增規則，將裝置上的連接埠 8080 映射至`code_node`容器上的連接埠 80。

**Example [graphs/my-app/graph.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/graphs/my-app/graph.json)**  

```
            {
                "producer": "model_input_width",
                "consumer": "code_node.model_input_width"
            },
            {
                "producer": "model_input_order",
                "consumer": "code_node.model_input_order"
            }
        ],
        "networkRoutingRules": [
            {
                "node": "code_node",
                "containerPort": 80,
                "hostPort": 8080,
                "decorator": {
                    "title": "Listener port 8080",
                    "description": "Container monitoring and debug."
                }
            }
        ]
```

部署應用程式時，您可以在 AWS Panorama 主控台中指定相同的規則，或將覆寫文件傳遞至 [CreateApplicationInstance](https://docs.aws.amazon.com/panorama/latest/api/API_CreateApplicationInstance.html) API。您必須在部署時間提供此組態，以確認您想要開啟設備上的連接埠。

**Example [graphs/my-app/override.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/graphs/my-app/override.json)**  

```
            {
                "replace": "camera_node",
                "with": [
                    {
                        "name": "exterior-north"
                    }
                ]
            }
        ],
        "networkRoutingRules":[
            {
                "node": "code_node",
                "containerPort": 80,
                "hostPort": 8080
            }
        ],
        "envelopeVersion": "2021-01-01"
    }
}
```

如果應用程式資訊清單中指定的裝置連接埠正由另一個應用程式使用，您可以使用覆寫文件來選擇不同的連接埠。

## 服務流量
<a name="applications-ports-serverthread"></a>

在容器上開啟連接埠時，您可以開啟通訊端或執行伺服器來處理傳入的請求。此`debug-server`範例顯示搭配電腦視覺應用程式程式碼執行的 HTTP 伺服器的基本實作。

**重要**  
範例實作對於生產使用並不安全。為了避免讓您的設備容易遭受攻擊，您必須在程式碼和網路組態中實作適當的安全控制。

**Example [package/123456789012-DEBUG\$1SERVER-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) – HTTP 伺服器**  

```
    # HTTP debug server
    def run_debugger(self):
        """Process debug commands from local network."""
        class ServerHandler(SimpleHTTPRequestHandler):
            # Store reference to application
            application = self
            # Get status
            def do_GET(self):
                """Process GET requests."""
                logger.info('Get request to {}'.format(self.path))
                if self.path == '/status':
                    self.send_200('OK')
                else:
                    self.send_error(400)
            # Restart application
            def do_POST(self):
                """Process POST requests."""
                logger.info('Post request to {}'.format(self.path))
                if self.path == '/restart':
                    self.send_200('OK')
                    ServerHandler.application.stop()
                else:
                    self.send_error(400)
            # Send response
            def send_200(self, msg):
                """Send 200 (success) response with message."""
                self.send_response(200)
                self.send_header('Content-Type', 'text/plain')
                self.end_headers()
                self.wfile.write(msg.encode('utf-8'))
        try:
            # Run HTTP server
            self.server = HTTPServer(("", self.CONTAINER_PORT), ServerHandler)
            self.server.serve_forever(1)
            # Server shut down by run_cv loop
            logger.info("EXITING SERVER THREAD")
        except:
            logger.exception('Exception on server thread.')
```

伺服器接受`/status`路徑上的 GET 請求，以擷取應用程式的一些資訊。它也接受 的 POST 請求`/restart`，以重新啟動應用程式。

為了示範此功能，範例應用程式會在單獨的執行緒上執行 HTTP 用戶端。用戶端會在啟動後立即透過本機網路呼叫`/status`路徑，並在幾分鐘後重新啟動應用程式。

**Example [package/123456789012-DEBUG\$1SERVER-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) – HTTP 用戶端**  

```
    # HTTP test client
    def run_client(self):
        """Send HTTP requests to device port to demnostrate debug server functions."""
        def client_get():
            """Get container status"""
            r = requests.get('http://{}:{}/status'.format(self.device_ip, self.DEVICE_PORT))
            logger.info('Response: {}'.format(r.text))
            return
        def client_post():
            """Restart application"""
            r = requests.post('http://{}:{}/restart'.format(self.device_ip, self.DEVICE_PORT))
            logger.info('Response: {}'.format(r.text))
            return
        # Call debug server
        while not self.terminate:
            try:
                time.sleep(30)
                client_get()
                time.sleep(300)
                client_post()
            except:
                logger.exception('Exception on client thread.')
        # stop signal received
        logger.info("EXITING CLIENT THREAD")
```

主迴圈會管理執行緒，並在結束時重新啟動應用程式。

**Example [package/123456789012-DEBUG\$1SERVER-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) – 主迴圈**  

```
def main():
    panorama = panoramasdk.node()
    while True:
        try:
            # Instantiate application
            logger.info('INITIALIZING APPLICATION')
            app = Application(panorama)
            # Create threads for stream processing, debugger, and client
            app.run_thread = threading.Thread(target=app.run_cv)
            app.server_thread = threading.Thread(target=app.run_debugger)
            app.client_thread = threading.Thread(target=app.run_client)
            # Start threads
            logger.info('RUNNING APPLICATION')
            app.run_thread.start()
            logger.info('RUNNING SERVER')
            app.server_thread.start()
            logger.info('RUNNING CLIENT')
            app.client_thread.start()
            # Wait for threads to exit
            app.run_thread.join()
            app.server_thread.join()
            app.client_thread.join()
            logger.info('RESTARTING APPLICATION')
        except:
            logger.exception('Exception during processing loop.')
```

若要部署範例應用程式，請參閱[本指南的 GitHub 儲存庫中的指示。](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/README.md)

# 使用 GPU
<a name="applications-gpuaccess"></a>

您可以在 AWS Panorama 設備上存取圖形處理器 (GPU)，以使用 GPU 加速程式庫，或在應用程式程式碼中執行機器學習模型。若要開啟 GPU 存取，請在建置應用程式碼容器後，將 GPU 存取新增為套件組態的需求。

**重要**  
如果您啟用 GPU 存取，則無法在設備的任何應用程式中執行模型節點。為了安全起見，當設備執行使用 SageMaker AI Neo 編譯的模型時，GPU 存取會受到限制。使用 GPU 存取時，您必須在應用程式程式碼節點中執行模型，且裝置上的所有應用程式都必須共用 GPU 的存取權。

若要開啟應用程式的 GPU 存取，請在使用 AWS Panorama Application CLI 建置套件後更新套件[組態](applications-packages.md)。下列範例顯示將 GPU 存取權新增至應用程式程式碼節點的 `requirements` 區塊。

**Example package.json 與需求區塊**  

```
{
    "nodePackage": {
        "envelopeVersion": "2021-01-01",
        "name": "SAMPLE_CODE",
        "version": "1.0",
        "description": "Computer vision application code.",
        "assets": [
            {
                "name": "code_asset",
                "implementations": [
                    {
                        "type": "container",
                        "assetUri": "eba3xmpl71aa387e8f89be9a8c396416cdb80a717bb32103c957a8bf41440b12.tar.gz",
                        "descriptorUri": "4abdxmpl5a6f047d2b3047adde44704759d13f0126c00ed9b4309726f6bb43400ba9.json",
                        "requirements": [
                            {
                                "type": "hardware_access",
                                "inferenceAccelerators": [
                                    {
                                        "deviceType": "nvhost_gpu",
                                        "sharedResourcePolicy": {
                                            "policy" : "allow_all"
                                        }
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ],
        "interfaces": [
        ...
```

更新開發工作流程中建置和封裝步驟之間的套件組態。

**使用 GPU 存取部署應用程式**

1. 若要建置應用程式容器，請使用 `build-container`命令。

   ```
   $ panorama-cli build-container --container-asset-name code_asset --package-path packages/123456789012-SAMPLE_CODE-1.0
   ```

1. 將 `requirements` 區塊新增至套件組態。

1. 若要上傳容器資產和套件組態，請使用 `package-application`命令。

   ```
   $ panorama-cli package-application
   ```

1. 部署應用程式。

如需使用 GPU 存取的範例應用程式，請造訪 [aws-panorama-samples](https://github.com/aws-samples/aws-panorama-samples) GitHub 儲存庫。

# 在 Windows 中設定開發環境
<a name="applications-devenvwindows"></a>

若要建置 AWS Panorama 應用程式，您可以使用 Docker、命令列工具和 Python。在 Windows 中，您可以使用 Docker Desktop 搭配 Windows Subsystem for Linux 和 Ubuntu 來設定開發環境。本教學課程會逐步引導您完成使用 AWS Panorama 工具和範例應用程式測試之開發環境的設定程序。

**Topics**
+ [先決條件](#applications-devenvwindows-prerequisites)
+ [安裝 WSL 2 和 Ubuntu](#applications-devenvwindows-wsl2)
+ [安裝 Docker](#applications-devenvwindows-docker)
+ [設定 Ubuntu](#applications-devenvwindows-ubuntu)
+ [後續步驟](#applications-devenvwindows-nextsteps)

## 先決條件
<a name="applications-devenvwindows-prerequisites"></a>

若要遵循本教學課程，您需要支援 Windows Subsystem for Linux 2 (WSL 2) 的 Windows 版本。

****
+ Windows 10 1903 版及更高版本 （建置 18362 及更高版本） 或 Windows 11
+ Windows 功能
  + 適用於 Linux 的 Windows 子系統
  + Hyper-V：
  + 虛擬機器平台

本教學課程使用下列軟體版本開發。

****
+ Ubuntu 20.04
+ Python 3.8.5
+ Docker 20.10.8

## 安裝 WSL 2 和 Ubuntu
<a name="applications-devenvwindows-wsl2"></a>

如果您有 Windows 10 2004 版和更新版本 （建置 19041 和更新版本），您可以使用下列 PowerShell 命令安裝 WSL 2 和 Ubuntu 20.04。

```
> wsl --install -d Ubuntu-20.04
```

對於較舊的 Windows 版本，請遵循 WSL 2 文件中的指示：[較舊版本的手動安裝步驟](https://docs.microsoft.com/en-us/windows/wsl/install-manual)

## 安裝 Docker
<a name="applications-devenvwindows-docker"></a>

若要安裝 Docker Desktop，請從 [hub.docker.com](https://hub.docker.com/editions/community/docker-ce-desktop-windows/)：// 下載並執行安裝程式套件。如果您遇到問題，請遵循 Docker 網站的指示：[Docker Desktop WSL 2 後端](https://docs.docker.com/desktop/windows/wsl/)。

執行 Docker 桌面並遵循初次執行教學課程來建置範例容器。

**注意**  
Docker Desktop 只會在預設分佈中啟用 Docker。如果您在執行本教學課程之前已安裝其他 Linux 發行版本，請在 **資源**、**WSL 整合**下的 Docker 桌面設定選單中，在新安裝的 Ubuntu 發行版本中啟用 Docker。

## 設定 Ubuntu
<a name="applications-devenvwindows-ubuntu"></a>

您現在可以在 Ubuntu 虛擬機器中執行 Docker 命令。若要開啟命令列終端機，請從開始功能表執行分佈。第一次執行它時，您可以設定使用者名稱和密碼，可用來執行管理員命令。

若要完成開發環境的組態，請更新虛擬機器的軟體並安裝工具。

**設定虛擬機器**

1. 更新 Ubuntu 隨附的軟體。

   ```
   $ sudo apt update && sudo apt upgrade -y && sudo apt autoremove
   ```

1. 使用 apt 安裝開發工具。

   ```
   $ sudo apt install unzip python3-pip
   ```

1. 使用 pip 安裝 Python 程式庫。

   ```
   $ pip3 install awscli panoramacli
   ```

1. 開啟新的終端機，然後執行 `aws configure`來設定 AWS CLI。

   ```
   $ aws configure
   ```

   如果您沒有存取金鑰，您可以在 [IAM 主控台](https://console.aws.amazon.com/iamv2/home?#/users)中產生這些金鑰。

最後，下載並匯入範例應用程式。

**取得範例應用程式**

1. 下載並擷取範例應用程式。

   ```
   $ wget https://github.com/awsdocs/aws-panorama-developer-guide/releases/download/v1.0-ga/aws-panorama-sample.zip
   $ unzip aws-panorama-sample.zip
   $ cd aws-panorama-sample
   ```

1. 執行包含的指令碼來測試編譯、建置應用程式容器，並將套件上傳至 AWS Panorama。

   ```
   aws-panorama-sample$ ./0-test-compile.sh
   aws-panorama-sample$ ./1-create-role.sh
   aws-panorama-sample$ ./2-import-app.sh
   aws-panorama-sample$ ./3-build-container.sh
   aws-panorama-sample$ ./4-package-app.sh
   ```

AWS Panorama Application CLI 會上傳套件，並使用 AWS Panorama 服務註冊這些套件。您現在可以使用 AWS Panorama 主控台[部署範例應用程式](gettingstarted-deploy.md#gettingstarted-deploy-deploy)。

## 後續步驟
<a name="applications-devenvwindows-nextsteps"></a>

若要探索和編輯專案檔案，您可以使用 File Explorer 或支援 WSL 的整合式開發環境 (IDE)。

若要存取虛擬機器的檔案系統，請開啟檔案總管，然後在導覽列`\\wsl$`中輸入 。此目錄包含虛擬機器檔案系統 (`Ubuntu-20.04`) 和 Docker 資料檔案系統的連結。在 下`Ubuntu-20.04`，您的使用者目錄位於 `home\username`。

**注意**  
若要從 Ubuntu 內存取 Windows 安裝中的檔案，請導覽至 `/mnt/c`目錄。例如，您可以執行 來列出下載目錄中的檔案`ls /mnt/c/Users/windows-username/Downloads`。

使用 Visual Studio Code，您可以在開發環境中編輯應用程式程式碼，並使用整合式終端機執行命令。若要安裝 Visual Studio Code，請造訪 https：//[code.visualstudio.com](https://code.visualstudio.com/)。安裝後，新增[遠端 WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl) 延伸模組。

Windows 終端機是標準 Ubuntu 終端機的替代方案，而此終端機已執行命令。它支援多個索引標籤，並可以為您安裝的任何其他 Linux 類型執行 PowerShell、命令提示字元和終端機。它支援使用  Ctrl C 和 複製和貼上 Ctrl V 、可點選URLs 和其他有用的改進。若要安裝 Windows 終端機，請造訪 https：//[microsoft.com](https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701)。