1. Jetson Nano开发环境搭建实战
NVIDIA Jetson Nano作为一款面向边缘计算的人工智能开发板,凭借其强大的GPU算力和紧凑的尺寸,已经成为计算机视觉和AI应用开发的热门选择。我在实际项目中使用Jetson Nano开发过多款视觉识别系统,今天就来分享从系统配置到相机驱动开发的完整实战经验。
1.1 硬件准备与系统烧录
首先需要准备以下硬件组件:
- Jetson Nano开发板(建议选择4GB内存版本)
- 32GB以上容量的UHS-1级别microSD卡
- 5V/4A直流电源(USB供电可能功率不足)
- CSI接口摄像头(如Raspberry Pi Camera Module V2)
- HDMI显示器和USB键鼠(用于初始配置)
系统烧录步骤:
- 从NVIDIA官网下载最新的JetPack镜像(当前最新为4.6.1版本)
- 使用BalenaEtcher工具将镜像写入microSD卡
- 插入SD卡后连接显示器、键盘和电源启动
注意:首次启动时会进行系统初始化配置,建议选择英文界面和UTC时区,可以避免后续开发中的本地化问题。
1.2 基础系统配置
完成首次启动后,需要执行以下基础配置:
bash复制# 更新软件源和系统组件
sudo apt update
sudo apt full-upgrade -y
# 安装常用开发工具
sudo apt install -y build-essential cmake git python3-dev python3-pip
# 配置交换空间(防止内存不足)
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
对于国内用户,建议更换apt源以提高下载速度:
bash复制sudo sed -i 's/ports.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
sudo apt update
2. 相机硬件连接与驱动配置
2.1 CSI相机连接与测试
Jetson Nano配备了一个MIPI CSI-2接口,支持连接Raspberry Pi等兼容摄像头模块。连接步骤:
- 关闭开发板电源
- 轻轻拉起CSI接口的卡扣
- 将摄像头排线金属面朝向散热器方向插入
- 按下卡扣固定排线
连接完成后,使用以下命令测试摄像头:
bash复制# 安装GStreamer工具
sudo apt install -y gstreamer1.0-tools
# 测试摄像头预览
nvgstcapture-1.0 --orientation=2
如果看到摄像头画面,说明硬件连接正确。常见问题排查:
- 无画面显示:检查排线方向是否正确插入
- 画面花屏:尝试重新插拔排线
- 报错"Device not found":确认摄像头型号兼容性
2.2 USB相机驱动配置
对于USB摄像头,需要先确认设备识别情况:
bash复制ls /dev/video*
lsusb
安装必要的视频处理库:
bash复制sudo apt install -y v4l-utils libv4l-dev
配置相机参数(以Logitech C920为例):
bash复制# 设置分辨率与帧率
v4l2-ctl --set-fmt-video=width=1280,height=720,pixelformat=YUYV
v4l2-ctl --set-parm=30
# 查看所有可调参数
v4l2-ctl -l
3. OpenCV环境搭建与相机开发
3.1 OpenCV 4.5编译安装
虽然JetPack自带OpenCV,但建议自行编译以获得完整功能:
bash复制# 安装依赖项
sudo apt install -y libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev \
libswscale-dev libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev \
libdc1394-22-dev libv4l-dev
# 下载源码
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.5.5.zip
unzip opencv.zip
# 编译安装
cd opencv-4.5.5
mkdir build && cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D WITH_CUDA=ON \
-D CUDA_ARCH_BIN=5.3 \
-D CUDA_ARCH_PTX="" \
-D WITH_GSTREAMER=ON \
-D WITH_LIBV4L=ON \
-D BUILD_opencv_python3=ON \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_EXAMPLES=OFF ..
make -j4
sudo make install
编译过程约需1-2小时,完成后验证安装:
python复制import cv2
print(cv2.__version__)
print(cv2.getBuildInformation())
3.2 Python相机采集示例
CSI接口相机采集代码:
python复制import cv2
def csi_camera():
# CSI相机管道配置
pipeline = "nvarguscamerasrc ! video/x-raw(memory:NVMM),width=1280,height=720,format=NV12,framerate=30/1 ! nvvidconv flip-method=0 ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink"
cap = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imshow('CSI Camera', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
csi_camera()
USB相机采集代码:
python复制import cv2
def usb_camera():
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cap.set(cv2.CAP_PROP_FPS, 30)
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imshow('USB Camera', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
usb_camera()
4. 深度相机配置与开发
4.1 Intel RealSense驱动安装
对于D400系列深度相机,需要安装librealsense SDK:
bash复制# 安装依赖
sudo apt install -y libssl-dev libusb-1.0-0-dev libglfw3-dev libgtk-3-dev
# 下载并编译源码
git clone https://github.com/IntelRealSense/librealsense.git
cd librealsense
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release \
-DBUILD_EXAMPLES=true \
-DFORCE_RSUSB_BACKEND=true \
-DBUILD_WITH_CUDA=true
make -j4
sudo make install
# 配置udev规则
sudo cp ../config/99-realsense-libusb.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger
4.2 RealSense Python示例
python复制import pyrealsense2 as rs
import numpy as np
import cv2
# 配置深度和彩色流
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
# 开始流式传输
pipeline.start(config)
try:
while True:
# 等待一组帧
frames = pipeline.wait_for_frames()
depth_frame = frames.get_depth_frame()
color_frame = frames.get_color_frame()
if not depth_frame or not color_frame:
continue
# 转换为numpy数组
depth_image = np.asanyarray(depth_frame.get_data())
color_image = np.asanyarray(color_frame.get_data())
# 渲染图像
depth_colormap = cv2.applyColorMap(
cv2.convertScaleAbs(depth_image, alpha=0.03),
cv2.COLORMAP_JET)
# 显示图像
images = np.hstack((color_image, depth_colormap))
cv2.imshow('RealSense', images)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
finally:
pipeline.stop()
cv2.destroyAllWindows()
5. 性能优化技巧
5.1 电源管理模式设置
Jetson Nano有三种电源模式:
- 模式0:5W(最大节能)
- 模式1:10W(平衡模式)
- 模式2:MAXN(全性能)
设置为全性能模式:
bash复制sudo nvpmodel -m 0
sudo jetson_clocks
5.2 视频流处理优化
使用GStreamer管道可以显著提高视频处理性能:
python复制def optimized_csi_pipeline():
pipeline = (
"nvarguscamerasrc ! "
"video/x-raw(memory:NVMM),width=1280,height=720,format=NV12,framerate=30/1 ! "
"nvvidconv ! "
"video/x-raw,format=BGRx ! "
"videoconvert ! "
"video/x-raw,format=BGR ! "
"appsink drop=1"
)
return cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
5.3 多线程视频采集
使用生产者-消费者模式提高处理效率:
python复制from threading import Thread
import queue
class VideoCaptureThread:
def __init__(self, src=0):
self.cap = cv2.VideoCapture(src)
self.q = queue.Queue(maxsize=2)
self.running = True
self.thread = Thread(target=self._reader, daemon=True)
self.thread.start()
def _reader(self):
while self.running:
ret, frame = self.cap.read()
if not ret:
break
if not self.q.full():
self.q.put(frame)
def read(self):
return self.q.get()
def stop(self):
self.running = False
self.thread.join()
self.cap.release()
6. 常见问题解决方案
6.1 相机无法识别问题排查
-
检查硬件连接:
bash复制dmesg | grep -i camera ls /dev/video* -
验证CSI接口状态:
bash复制sudo apt install -y v4l-utils v4l2-ctl --list-devices -
检查摄像头供电:
- CSI摄像头可能需要额外启用供电
bash复制sudo apt install -y wiringpi gpio -g mode 8 out gpio -g write 8 1
6.2 OpenCV CUDA加速问题
如果遇到CUDA加速不工作,检查:
-
验证CUDA支持:
python复制print(cv2.cuda.getCudaEnabledDeviceCount()) -
重新编译OpenCV时确保开启CUDA支持:
bash复制
cmake -D WITH_CUDA=ON -D CUDA_ARCH_BIN=5.3 ..
6.3 系统卡顿与内存管理
Jetson Nano内存有限,建议:
-
监控系统资源:
bash复制sudo tegrastats -
优化交换空间使用:
bash复制sudo sysctl vm.swappiness=10 -
关闭不必要的服务:
bash复制sudo systemctl stop apt-daily.service sudo systemctl disable apt-daily.service
7. 项目实战:智能监控系统开发
结合前面知识,开发一个基于运动检测的智能监控系统:
python复制import cv2
import numpy as np
class MotionDetector:
def __init__(self, camera_type='csi'):
if camera_type == 'csi':
self.cap = self._create_csi_capture()
else:
self.cap = cv2.VideoCapture(0)
self.fgbg = cv2.createBackgroundSubtractorMOG2(
history=500, varThreshold=16, detectShadows=False)
def _create_csi_capture(self):
pipeline = "nvarguscamerasrc ! video/x-raw(memory:NVMM),width=1280,height=720,format=NV12,framerate=30/1 ! nvvidconv flip-method=0 ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink"
return cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
def run(self):
while True:
ret, frame = self.cap.read()
if not ret:
break
# 运动检测
fgmask = self.fgbg.apply(frame)
_, thresh = cv2.threshold(fgmask, 244, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, _ = cv2.findContours(
thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
if cv2.contourArea(contour) > 500:
x,y,w,h = cv2.boundingRect(contour)
cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2)
cv2.putText(frame, "Motion Detected", (10,30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
cv2.imshow('Monitoring', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
self.cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
detector = MotionDetector('csi')
detector.run()
这个项目展示了如何将相机驱动开发与实际应用结合。在实际部署时,还可以添加以下功能:
- 运动事件录像保存
- 网络视频流传输
- 移动端报警通知
- 基于深度学习的对象识别
