Jetson Nano – YOLOv5 with CSI-2 Camera

Jetson Nano

This article explains how to run YOLOv5 on a Jetson Nano using a CSI-2 camera. In this article, we used a USB camera to run YOLOv5 on the Jetson Nano, but this time we will use the CSI-2 camera, which is a Raspberry Pi Camera V2.

Raspberry Pi Camera V2

In this article, we will explain how to download and run pre-built libraries.

You can install PyTorch and TorchVision on the Jetson Nano with this article and install OpenCV with this article. Alternatively, you can build the libraries on your host and install them on the Jetson Nano with this article.

Install the necessary packages. We will use python 3.8 again (the pre-built packages are also targeted to python 3.8).

sudo apt update
sudo apt install -y 
    python3.8 python3.8-dev python3-pip 
    libopenmpi-dev libomp-dev libopenblas-dev libblas-dev libeigen3-dev libcublas-devCode language: Bash (bash)

Next, download the pre-built OpenCV package.

python3.8 -m pip install -U pip
python3.8 -m pip install gdown
export PATH=.local/bin:$PATH
gdown https://drive.google.com/uc?id=1VPU1oUO0_trI8Dm1AJ5UVTEGzqcnl3HU
gdown https://drive.google.com/uc?id=1Z4yKz_5azGbqq3aslc7k0WAwR-yF4Mgc
gdown https://drive.google.com/uc?id=1ZNio67dove9W5kMHqz_nmvmf1GR2y3hQ
gdown https://drive.google.com/uc?id=1_loSh1aD6_FARGhVNFIBz2W4lSw7dfqN
gdown https://drive.google.com/uc?id=1dWN5QWx-8htYURSELGbj4caqHY1228HL
gdown https://drive.google.com/uc?id=1uMfj78AxtDaIirnR5T_qfWsE4Xf8WdJPCode language: Bash (bash)

When we ran YOLOv5 in this article, we did not need to install any special OpenCV packages, but this time we need to install OpenCV packages that support GStreamer because OpenCV needs to support GStreamer.

Remove the pre-installed OpenCV package due to conflicts, and then install the downloaded OpenCV packages.

apt list --installed *opencv*|awk -F/ '/opencv/ {print $1}'|sudo xargs apt remove -y
sudo apt install -y ./OpenCV*.debCode language: Bash (bash)

Next, download and install the pre-built PyTorch and TorchVision packages.

# pytorch 1.11.0
gdown https://drive.google.com/uc?id=1hs9HM0XJ2LPFghcn7ZMOs5qu5HexPXwM
# torchvision 0.12.0
gdown https://drive.google.com/uc?id=1m0d8ruUY8RvCP9eVjZw4Nc8LAwM8yuGV
python3.8 -m pip install torch-*.whl torchvision-*.whlCode language: Bash (bash)

Clone YOLOv5 and install the required python packages. Comment out the opencv-python package in the requirements.txt file so that it will not be installed by pip.

git clone https://github.com/ultralytics/yolov5.git
cd yolov5
sed -i 's/^opencv-python/#opencv-python/g' requirements.txt 
python3.8 -m pip install -r requirements.txtCode language: Bash (bash)

YOLOv5 does not support GStreamer, so create the following patch file (patch.txt).

diff --git a/utils/dataloaders.py b/utils/dataloaders.py
index d849d51..b4a5fbc 100644
--- a/utils/dataloaders.py
+++ b/utils/dataloaders.py
@@ -359,7 +359,7 @@ class LoadStreams:
             if s == 0:
                 assert not is_colab(), '--source 0 webcam unsupported on Colab. Rerun command in a local environment.'
                 assert not is_kaggle(), '--source 0 webcam unsupported on Kaggle. Rerun command in a local environment.'
-            cap = cv2.VideoCapture(s)
+            cap = cv2.VideoCapture(self._gstreamer_pipeline(flip_method=0), cv2.CAP_GSTREAMER)
             assert cap.isOpened(), f'{st}Failed to open {s}'
             w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
             h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
@@ -420,6 +420,25 @@ class LoadStreams:
     def __len__(self):
         return len(self.sources)  # 1E12 frames = 32 streams at 30 FPS for 30 years
 
+    def _gstreamer_pipeline(
+        self,
+        capture_width=1280,
+        capture_height=720,
+        display_width=1280,
+        display_height=720,
+        framerate=60,
+        flip_method=0,
+    ):
+        return (
+            "nvarguscamerasrc ! "
+            "video/x-raw(memory:NVMM), "
+            f"width=(int){capture_width}, height=(int){capture_height}, "
+            f"format=(string)NV12, framerate=(fraction){framerate}/1 ! "
+            f"nvvidconv flip-method={flip_method} ! "
+            f"video/x-raw, width=(int){display_width}, height=(int){display_height}, format=(string)BGRx ! "
+            "videoconvert ! "
+            "video/x-raw, format=(string)BGR ! appsink"
+        )
 
 def img2label_paths(img_paths):
     # Define label paths as a function of image paths
Code language: Diff (diff)

Apply the above patch.

patch -p1 < patch.txtCode language: Bash (bash)

Run

LD_LIBRARY_PATH=/usr/ python3.8 detect.py --source 0Code language: Bash (bash)

LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libgomp.so.1 is the workaround explained below.https://forums.developer.nvidia.com/t/error-importerror-usr-lib-aarch64-linux-gnu-libgomp-so-1-cannot-allocate-memory-in-static-tls-block-i-looked-through-available-threads-already/166494

That’s all.