<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      NVIDIA Jetson TX2 邊緣盒子運行姿態檢測模型記錄

      Jetson TX2

      • 系統版本:JetPack 4.6.1 (對應 L4T R32.6.1)
      • 架構:aarch64(ARM 64)
      • CUDA 版本:10.2
      • python 3.6

      背景介紹

      ? 最近在做關于視頻流處理方面項目,接觸到NVIDIA 的邊緣盒子,就嘗試著看在邊緣盒子上能不能運行 yolov8 或 Google 的 mediapipe 。

      yolov8 是無法在這個版本的盒子運行(無法使用 cuda,CPU 推理卡的厲害),而且 Jetpack 4.6.1 版本的盒子無法升級 5.xx 版本,yolov8 最低需要 Python 3.8 版本,所以就選擇 mediapipe 。

      使用 mediapipe 最好就是使用 docker 來處理,自己在系統安裝環境非常麻煩(CUDA10.2 + aarch64 問題),而且坑特別多根本跳不完的坑。

      設置 docker

      參考資料

      1. 安裝nano(或任何其他文本編輯器):

        sudo apt-get install nano
        
      2. 開放時間/etc/docker/daemon.json

        sudo nano /etc/docker/daemon.json
        
      3. 編輯自:

        json

        {
            "runtimes": {
                "nvidia": {
                    "path": "nvidia-container-runtime",
                    "runtimeArgs": []
                }
            }
        }
        

        到:

        json

        {
            "runtimes": {
                "nvidia": {
                    "path": "nvidia-container-runtime",
                    "runtimeArgs": []
                }
            }, 
        
            "default-runtime": "nvidia"
        }
        
      4. 重啟docker:

        sudo systemctl restart docker
        
      5. 現在需要將 docker 添加用戶到組:

        sudo usermod -aG docker $USER
        

      拉鏡像

      Python OpenCV mediapipe 鏡像標簽 鏡像文件
      3.6.9 4.8.0 0.8.5 l4t32.7.1-py3.6.9-ocv4.8.0-mp0.8.5 Dockerfile
      docker pull ghcr.io/lanzani/mediapipe:l4t32.7.1-py3.6.9-ocv4.8.0-mp0.8.5
      

      啟動容器

      參考資料

      顯示支持

      運行容器之前:

      export DISPLAY=:0
      
      xhost +
      

      然后運行你的容器。

      啟動命令:

      sudo docker run -it --rm \
        --runtime nvidia \
        --network host \
        -v /tmp/argus_socket:/tmp/argus_socket \
        -v /etc/enctune.conf:/etc/enctune.conf \
        -v /etc/nv_tegra_release:/etc/nv_tegra_release \
        -v /tmp/nv_jetson_model:/tmp/nv_jetson_model \
        -v /tmp/.X11-unix/:/tmp/.X11-unix \
        -v /tmp/.docker.xauth:/tmp/.docker.xauth \
        -v /home/ubuntu/google-media/data:/opt \
        --device /dev/snd \
        --device /dev/bus/usb \
        -e DISPLAY=:0 \
        -e XAUTHORITY=/tmp/.docker.xauth \
      ghcr.io/lanzani/mediapipe:l4t32.7.1-py3.6.9-ocv4.8.0-mp0.8.5 \
      python3.6 /opt/pcv3.py
      

      參數說明

      1?? 基本選項

      參數 作用 說明
      sudo 提權執行 docker 因為 Docker 默認需要 root 權限,或者用戶在 docker 組中
      docker run 啟動容器 核心命令
      -it 交互式終端 -i 保持 STDIN 打開,-t 分配偽終端,-t 換成 -d 可后臺運行
      --rm 容器退出后自動刪除 避免堆積臨時容器,測試使用,沒問題后可刪除這個選擇

      2?? GPU/NVIDIA 相關

      參數 作用 說明
      --runtime nvidia 使用 NVIDIA Docker runtime 讓容器訪問 GPU。Jetson 的 L4T 環境通常也需要這個
      --device /dev/snd 音頻設備 允許容器訪問宿主機的音頻設備,方便 TTS 或播放
      --device /dev/bus/usb USB 設備 允許訪問 USB 攝像頭或其他設備

      3?? 網絡

      參數 作用 說明
      --network host 容器共享宿主機網絡 對于訪問本地攝像頭、USB 或 V4L2 流媒體方便

      4?? 掛載卷(Volume)

      Volume 主要是讓容器訪問宿主機文件或設備。

      參數 作用 說明
      -v /tmp/argus_socket:/tmp/argus_socket Argus 攝像頭 socket Jetson 的攝像頭 API(Argus)需要這個 socket
      -v /etc/enctune.conf:/etc/enctune.conf GPU/編碼配置 Jetson 的編碼器調優文件
      -v /etc/nv_tegra_release:/etc/nv_tegra_release 系統版本信息 讓容器識別 Jetson 系統版本
      -v /tmp/nv_jetson_model:/tmp/nv_jetson_model Jetson 硬件信息 某些 SDK 需要讀取型號信息
      -v /tmp/.X11-unix/:/tmp/.X11-unix X11 socket 允許 GUI 程序在宿主機顯示
      -v /tmp/.docker.xauth:/tmp/.docker.xauth X11 認證 避免權限問題
      -v /home/ubuntu/google-media/data:/opt 數據文件 容器內 /opt 可訪問宿主機數據(你寫的 pcv3.py 就在這里)

      5?? 顯示相關環境變量

      參數 作用 說明
      -e DISPLAY=:0 X11 顯示 指定 GUI 輸出到宿主機顯示器
      -e XAUTHORITY=/tmp/.docker.xauth X11 認證 配合掛載 .docker.xauth 文件使用

      6?? 鏡像和命令

      參數 作用 說明
      ghcr.io/lanzani/mediapipe:l4t32.7.1-py3.6.9-ocv4.8.0-mp0.8.5 Docker 鏡像 這個鏡像包含 MediaPipe、OpenCV 4.8、Python3.6.9,適配 Jetson L4T 32.7.1
      python3.6 /opt/pcv3.py 容器啟動后執行 執行你掛載在 /opt 的 Python 文件

      ? 總結

      這個命令做了幾件事情:

      1. 啟動一個基于 Jetson 的 MediaPipe 鏡像。
      2. 容器可以訪問 GPU、音頻和 USB 設備。
      3. 容器共享宿主機網絡和 X11 顯示,可以直接用 GUI。
      4. 容器自動掛載宿主機文件和配置,運行 Python 腳本 /opt/pcv3.py

      測試代碼

      pcv3.py

      # -*- coding: utf-8 -*-
      import cv2
      import sys
      import os
      import mediapipe as mp
      
      print("pwd:", os.getcwd())
      
      print("mediapipe pwd:", mp.__file__)
      
      # === RTSP 地址(請改成你的攝像頭地址) ===
      RTSP_URL = "rtsp://admin:123456@192.168.0.1:554/stream1"
      
      # === 初始化 MediaPipe Pose ===
      mp_drawing = mp.solutions.drawing_utils
      mp_pose = mp.solutions.pose
      
      # 啟動 RTSP 視頻流
      cap = cv2.VideoCapture(RTSP_URL)
      
      if not cap.isOpened():
          print("xxxx stop")
          exit()
      
      print("start")
      
      # 初始化 Pose 模型(static_image_mode=False 表示視頻流)
      with mp_pose.Pose(
          static_image_mode=False,
          model_complexity=1,
          min_detection_confidence=0.5,
          min_tracking_confidence=0.5
      ) as pose:
      
          while True:
              success, frame = cap.read()
              if not success:
                  print("dddiu")
                  break
      
              # 轉換為 RGB(MediaPipe 要求輸入 RGB)
              image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
      
              # 推理
              results = pose.process(image_rgb)
      
              # 可視化骨架
              if results.pose_landmarks:
                  mp_drawing.draw_landmarks(
                      frame, 
                      results.pose_landmarks, 
                      mp_pose.POSE_CONNECTIONS,
                      landmark_drawing_spec=mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2),
                      connection_drawing_spec=mp_drawing.DrawingSpec(color=(255, 0, 0), thickness=2)
                  )
      
              # 顯示畫面
              #cv2.imshow('Pose Detection (RTSP)', frame)
      
              # 按 q 退出
              if cv2.waitKey(1) & 0xFF == ord('q'):
                  break
      
      cap.release()
      cv2.destroyAllWindows()
      
      

      開合跳代碼

      通過關鍵點,計算開合跳數量

      # -*- coding: utf-8 -*-
      import cv2
      import threading
      import queue
      import math
      import time
      import requests
      import mediapipe as mp
      
      # ======================
      # 配置
      # ======================
      RTSP_URL = "rtsp://admin:123456@127.0.0.1:554/stream1?transport=tcp"
      SERVER_URL = "http://127.0.0.1:8080/upload"
      JPEG_QUALITY = 80  # JPEG 編碼質量
      QUEUE_MAXSIZE = 1   # 隊列長度 1,保持最新幀
      
      # ======================
      # 隊列
      # ======================
      frame_queue = queue.Queue(maxsize=QUEUE_MAXSIZE)
      upload_queue = queue.Queue(maxsize=QUEUE_MAXSIZE)
      
      
      
      # 計算兩點之間的歐式距離(用于判斷雙腳分開的程度)
      def calc_distance(p1, p2):
          return math.sqrt((p1.x - p2.x)**2 + (p1.y - p2.y)**2)
      
      # ======================
      # 上傳函數
      # ======================
      def upload_jpeg_bytes(image_bytes, server_url):
          try:
              files = {'image': ('uploaded_image.jpg', image_bytes, 'image/jpeg')}
              response = requests.post(server_url, files=files, timeout=2)
              response.raise_for_status()
          except Exception as e:
              print("上傳失敗:", e)
      
      # ======================
      # 抓幀線程
      # ======================
      def frame_grabber():
          cap = cv2.VideoCapture(RTSP_URL)
          if not cap.isOpened():
              print("無法打開 RTSP 流")
              return
      
          while True:
              success, frame = cap.read()
              if not success:
                  continue
              # 丟棄舊幀
              if frame_queue.full():
                  try:
                      frame_queue.get_nowait()
                  except queue.Empty:
                      pass
              frame_queue.put(frame)
      
      # ======================
      # 上傳線程
      # ======================
      def uploader():
          while True:
              try:
                  frame_bytes = upload_queue.get()
                  upload_jpeg_bytes(frame_bytes, SERVER_URL)
              except Exception as e:
                  print("上傳線程異常:", e)
      
      # ======================
      # 主線程處理
      # ======================
      def main_loop():
          mp_drawing = mp.solutions.drawing_utils
          mp_pose = mp.solutions.pose
          jumping_jacks = 0   # 開合跳次數計數器
          stage = "down"      # 動作階段:down=手腳收攏,up=手腳張開
      
          with mp_pose.Pose(
                  static_image_mode=False,
                  model_complexity=1,
                  min_detection_confidence=0.5,
                  min_tracking_confidence=0.5
          ) as pose:
      
              while True:
                  if frame_queue.empty():
                      time.sleep(0.001)
                      continue
      
                  frame = frame_queue.get()
      
                  # 轉 RGB
                  image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
      
                  # Mediapipe 推理
                  results = pose.process(image_rgb)
      
                  # 繪制骨架
                  if results.pose_landmarks:
                      mp_drawing.draw_landmarks(
                          frame,
                          results.pose_landmarks,
                          mp_pose.POSE_CONNECTIONS,
                          landmark_drawing_spec=mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2),
                          connection_drawing_spec=mp_drawing.DrawingSpec(color=(255, 0, 0), thickness=2)
                      )
                      # 如果檢測到人體關鍵點
                  if results.pose_landmarks:
                      landmarks = results.pose_landmarks.landmark
      
                      # 取出關鍵點(左右手腕、鼻子、左右腳踝)
                      left_wrist = landmarks[15]
                      right_wrist = landmarks[16]
                      nose = landmarks[0]          # 頭頂附近點
                      left_ankle = landmarks[27]
                      right_ankle = landmarks[28]
      
                      # ===== 手部邏輯 =====
                      # 當手腕的 y 坐標小于鼻子時,說明手舉過頭頂
                      hands_up = left_wrist.y < nose.y and right_wrist.y < nose.y
      
                      # ===== 腳部邏輯 =====
                      # 計算左右腳踝之間的距離
                      ankle_dist = calc_distance(left_ankle, right_ankle)
                      print(r"ankle_dis",ankle_dist)
                      # 如果距離大于閾值,說明雙腳分開
                      legs_open = ankle_dist > 0.10
      
                      # ===== 動作階段判斷 =====
                      # 如果手舉起且腳分開,認為處于 "up" 狀態
                      if hands_up and legs_open:
                          stage = "up"
                      # 如果手放下且腳收攏,并且之前是 "up",說明完成一次開合跳
                      elif not hands_up and not legs_open and stage == "up":
                          stage = "down"
                          jumping_jacks += 1  # 次數 +1
      
      
      
                      # 在左上角顯示開合跳次數
                      cv2.putText(
                          frame,
                          f'Jumping Jacks: {jumping_jacks}',  # 顯示文本
                          (20, 50),                          # 位置 (x,y)
                          cv2.FONT_HERSHEY_SIMPLEX,          # 字體
                          1.2,                               # 字號
                          (0, 255, 0),                       # 顏色 (綠色)
                          3                                  # 粗細
                      )
      
                  # 編碼 JPEG 并放入上傳隊列
                  _, buffer = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), JPEG_QUALITY])
                  frame_bytes = buffer.tobytes()
      
                  if upload_queue.full():
                      try:
                          upload_queue.get_nowait()
                      except queue.Empty:
                          pass
                  upload_queue.put(frame_bytes)
      
      # ======================
      # 啟動線程
      # ======================
      if __name__ == "__main__":
          threading.Thread(target=frame_grabber, daemon=True).start()
          threading.Thread(target=uploader, daemon=True).start()
          main_loop()
      
      

      注意事項

      一、目錄掛載問題

      -v /home/ubuntu/google-media/data:/opt \ 將宿主機的測試 python 代碼掛載到容器 opt 目錄下,所以/home/ubuntu/google-media/data這個目錄是自己創建的。

      二、Can't find file: mediapipe/modules/pose_detection/pose_detection.tflite

      Mediapipe 模型加載問題,沒有找到這個文件,python3.6 /opt/pcv3.py 是在容器的 opt 目錄下執行的,在當前工作目錄下默認是沒有這個 mediapipe/modules/pose_detection/pose_detection.tflite 文件,簡單粗暴解決辦法:

      通過 docker exec 容器ID /bin/bash,進入容器創建 /opt/mediapipe/modules/pose_detection/dist-packages 拷貝一個份

      mkdir -p /opt/mediapipe/modules/pose_detection/
      cp /usr/local/lib/python3.6/dist-packages/mediapipe/modules/pose_detection/pose_detection.tflite /opt/mediapipe/modules/pose_detection/
      

      啟動日志:

      WARNING: Logging before InitGoogleLogging() is written to STDERR
      I20251016 06:39:17.998665    24 gl_context_egl.cc:163] Successfully initialized EGL. Major : 1 Minor: 5
      I20251016 06:39:18.044948    42 gl_context.cc:331] GL version: 3.2 (OpenGL ES 3.2 NVIDIA 32.6.1)
      I20251016 06:39:18.045231    24 gl_context_egl.cc:163] Successfully initialized EGL. Major : 1 Minor: 5
      I20251016 06:39:18.072178    43 gl_context.cc:331] GL version: 3.2 (OpenGL ES 3.2 NVIDIA 32.6.1)
      W20251016 06:39:18.075790    42 tflite_model_loader.cc:32] Trying to resolve path manually as GetResourceContents failed: ; Can't find file: mediapipe/modules/pose_detection/pose_detection.tflite
      INFO: Created TensorFlow Lite delegate for GPU.
      

      三、eglChooseConfig() returned no matching EGL configuration for RGBA8888 D16 ES2 request

      AI 回答:

      MediaPipe 默認會嘗試用 GPU (OpenGL ES) 模式運行 Pose 模型。
      但 Jetson TX2 某些驅動 / EGL 庫 版本(尤其 JetPack 4.6.x)下:

      • EGL 配置不匹配
      • X server 或 DISPLAY 環境未正確設置
      • 無法創建 GLES3 / GLES2 上下文

      最終 GPU 初始化失敗,導致 MediaPipe Pose 圖計算圖無法啟動。

      實際情況是在啟動 docker 容器時缺少了一些必要參數:

      -v /tmp/argus_socket:/tmp/argus_socket \
      -v /etc/enctune.conf:/etc/enctune.conf \
      -v /etc/nv_tegra_release:/etc/nv_tegra_release \
      -v /tmp/nv_jetson_model:/tmp/nv_jetson_model \
      -v /tmp/.X11-unix/:/tmp/.X11-unix \
      -v /tmp/.docker.xauth:/tmp/.docker.xauth \
      --device /dev/snd \
      --device /dev/bus/usb \
      -e DISPLAY=:0 \
      -e XAUTHORITY=/tmp/.docker.xauth \
      

      參考資料

      1. Jetson torch 下載中心
      2. Jetson 開發文檔
      3. 手動安裝 Google MediaPipe Github
      4. Google MediaPipe

      擴展信息

      查看版本信息

      cat /etc/nv_tegra_release
      

      查看系統架構

      uname -m
      

      查看 cuda 信息

      nvcc --version
      

      查看 CPU、GPU、內存使用情況

      sudo tegrastats
      

      診斷系統 OpenCV 是否支持 cuda,也可以自容器執行

      python3.6 -c "import cv2; print('--- System OpenCV Info ---'); print(cv2.getBuildInformation())"
      

      查看 mediapipe 版本信息

      python3.6 -c "import mediapipe as mp; print(mp.__version__)"
      

      PyTorch(適用于 JetPack 4.6.1):是一個針對使用 GPU 和 CPU 進行深度學習而優化的張量庫
      NVIDIA JetPack? :是 NVIDIA Jetson? 平臺的官方軟件堆棧,為您提供構建 AI 驅動的邊緣應用程序所需的一整套工具和庫。

      posted @ 2025-10-17 09:30  天葬  閱讀(27)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久国产乱子伦免费精品| 蜜臀av久久国产午夜| 亚亚洲视频一区二区三区| 久久综合伊人77777| 国产综合精品一区二区在线| 国产一级片内射在线视频| 无码国产精品一区二区av| 91福利视频一区二区| 国产自产对白一区| 日韩国产中文字幕精品| 中文字幕乱码在线播放| 国产精品亚洲二区在线播放| 鸡泽县| 日韩一区二区三区女优丝袜| 潮喷失禁大喷水无码| 亚洲情A成黄在线观看动漫尤物| 久久人人妻人人爽人人爽| 日本福利一区二区精品| 亚洲人成电影网站 久久影视| 国内久久人妻风流av免费| 青青草无码免费一二三区| 国产二区三区不卡免费| 人妻少妇精品中文字幕| 佛坪县| 久久久久国产精品熟女影院| 久久精品岛国AV一区二区无码| 亚洲一区二区偷拍精品| 亚洲欧美综合精品成人网站| 国产成AV人片久青草影院| 国产线播放免费人成视频播放| 精品偷自拍另类精品在线| 97人妻天天摸天天爽天天| 色综合色综合久久综合频道| 国产一区日韩二区欧美三区| 国产一区二区日韩在线| 大名县| 久久久久噜噜噜亚洲熟女综合| 精品国产美女福到在线不卡| 忘忧草在线社区www中国中文 | 一本色道久久88亚洲综合| 亚洲欧美偷国产日韩|