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 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
# torchvision 0.12.0
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
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/ b/utils/
index d849d51..b4a5fbc 100644
--- a/utils/
+++ b/utils/
@@ -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)


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

LD_PRELOAD=/usr/lib/aarch64-linux-gnu/ is the workaround explained below.

That’s all.