https://github.com/NVIDIA-AI-IOT/jetson-cloudnative-demo
Cloud-Native Demo on Jetson を試したいと思います。
4つのデモンストレーションがありますが、目を引くのは、Pose detectionではないでしょうか。
やってみたい。
Docker で試す
ガイドでは、Docker での使用を説明しました。
素直に従います。
git clone https://github.com/NVIDIA-AI-IOT/jetson-cloudnative-demo
sudo apt-get install xdotool
cd jetson-cloudnative-demo
# sudo ./run_demo.sh ではなく、
sudo ./run_pose.sh
WEBカメラで試す
サンプルは、事前に撮影された動画に対する解析ですが、ここはやはり、WEBカメラで動作させたいところです。
Docker コンテナにはいる
run_pose.sh を改造して、楽をします。
cp run_pose.sh run_pose2.sh
して、作成します。
変更が残るように -rm
を削除、
WEBカメラ /dev/video0
を使用できるように、--device /dev/video0:/dev/video0:mwr
追加、
シェルに入るだけでいいので、最後のコマンドも削除。
Video は不要といえば不要ですが、
残しました。
#!/usr/bin/env bash
CONTAINER=nvcr.io/nvidia/jetson-pose:r32.4.2
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
HOST_VIDEO_DIR="$ROOT_DIR/Videos"
HOST_VIDEO_NAME=
VIDEO=/videos/pose_video.mp4
#VIDEO=/userVideos/$HOST_VIDEO_NAME
echo Running pose
sudo nvpmodel -m 2
sudo jetson_clocks
xhost +
sudo xhost +si:localuser:root
sudo docker run --runtime nvidia -it --network host -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix -v $HOST_VIDEO_DIR:/userVideos/ --device /dev/video0:/dev/video0:mwr --cpuset-cpus=2,3 $CONTAINER
そして、
sudo ./run_pose2.sh
コンテナ内の構造
# ls /
bin dev home media opt proc run srv tmp trt_pose usr var vision
boot etc lib mnt pose root sbin sys torch2trt userVideos utils videos
# ls /userVideos/
gaze_video.mp4 pose_video.mp4
# ls /dev/video0
/dev/video0
/userVideo
と /dev/video0
が作られています。
/utils/video.py
を改造して /utils/cam.py
を作成します。
使用可能な解像度
刺したWEBカメラで利用可能な解像度を確認します。
$ sudo apt-get install v4l-utils
$ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.042s (24.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.133s (7.500 fps)
Interval: Discrete 0.200s (5.000 fps)
(中略)
Index : 1
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : Motion-JPEG
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.042s (24.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.133s (7.500 fps)
Interval: Discrete 0.200s (5.000 fps)
大量にリストされます。
大きく YUYV フォーマットと、MJPG フォーマットが有ることがわかります。
Size: Discrete 960×720 15.0 fps を使用しましょう。
cam.py
import cv2
class Cam(object):
def __init__(self, width, height, qsize=10, loop=True, codec='h264'):
self.width = width
self.height = height
self.qsize = qsize
self.loop = loop
self.codec = codec
self.reset()
def _gst_str(self):
return 'filesrc location={path} ! qtdemux ! queue max-size-buffers={qsize} ! {codec}parse ! omx{codec}dec ! nvvidconv ! video/x-raw,format=BGRx ! queue max-size-buffers={qsize} ! videoconvert ! queue max-size-buffers={qsize} ! video/x-raw,format=BGR,width={width},height={height} ! appsink sync=0'.format(path=self.path, width=self.width, height=self.height, qsize=self.qsize, codec=self.codec)
def reset(self):
if hasattr(self, 'cap'):
del self.cap
self.cap = cv2.VideoCapture(0, cv2.CAP_GSTREAMER)
self.cap.set(cv2.CAP_PROP_FPS, 15)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 960)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
def read(self):
re, img = self.cap.read()
if re:
return img
elif self.loop:
self.reset()
re, img = self.cap.read()
if re:
return img
else:
return None
else:
return None
def destroy(self):
self.cap.release()
_gst_str
関数だとかは、適当です。
cp run_pose_pipeline.py run_pose_pipeline.cam.py
変更箇所
from cam import Cam
(略)
# parser.add_argument('video')
parser.add_argument('--width', type=int, default=960)
# parser.add_argument('--height', type=int, default=540)
parser.add_argument('--height', type=int, default=720)
parser.add_argument('--loop', action="store_true")
parser.add_argument('--codec', type=str, default='h264')
args = parser.parse_args()
# media
# video = Video(args.video, args.width, args.height, loop=args.loop, codec=args.codec)
video = Cam(args.width, args.height, loop=args.loop, codec=args.codec)
display = Display(args.width, args.height)
これで、とりあえずは動きます。
python3 run_pose_pipeline.cam.py
15FPS 前後でした。
終了できない・・・
Ctrl + c
でもプロセスが止まりません。
Ctrl + z
で停止させて、kill %1
などで kill しましょう。