在Conda環境中從源代碼編譯OpenCV(支持CUDA和GStreamer)
以下是完整的方案步驟,包括必要的依賴庫安裝過程:
1. 安裝Miniconda(如果尚未安裝)
# 下載Miniconda安裝腳本
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh# 安裝Miniconda
bash Miniconda3-latest-Linux-x86_64.sh# 初始化conda
conda init bash# 重啟終端或執行
source ~/.bashrc
2. 創建并激活Conda環境
# 創建環境
conda create -n opencvcuda python=3.9 -y
conda activate opencvcuda # 安裝編譯工具和依賴
#conda install cmake ninja git -y(這個沒有做)
conda install ffmpeg gstreamer gst-plugins-base gst-plugins-good -y
conda install numpy -y
3. 安裝系統級依賴
# 安裝編譯OpenCV所需的系統庫
sudo apt-get update
sudo apt-get install -y build-essential
sudo apt-get install -y libgtk-3-dev libjpeg-dev libpng-dev libtiff-dev libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install -y libxvidcore-dev libx264-dev libatlas-base-dev gfortran
sudo apt-get install -y libtbb2 libtbb-dev libdc1394-22-dev(這個包似乎沒有)
添加:export GST_PLUGIN_PATH=/usr/lib/x86_64-linux-gnu/gstreamer-1.0:$GST_PLUGIN_PATH
到環境變量中。
4. 下載OpenCV源代碼
# 創建工作目錄
mkdir -p ~/opencv_build && cd ~/opencv_build# 下載OpenCV和OpenCV_contrib
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.8.0.zip
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.8.0.zip# 解壓
unzip opencv.zip
unzip opencv_contrib.zip# 重命名目錄(為什么要重命名呢,不需要也行)
mv opencv-4.8.0 opencv
mv opencv_contrib-4.8.0 opencv_contrib
5. 配置CMake
# 創建構建目錄
mkdir -p build && cd build
#install_path=install
# 配置CMake(根據你的CUDA版本和GPU架構調整)
cmake -G "Unix Makefiles" \-D CMAKE_BUILD_TYPE=RELEASE \-D CMAKE_INSTALL_PREFIX=$CONDA_PREFIX \-D WITH_CUDA=ON \-D WITH_CUDNN=ON \-D OPENCV_DNN_CUDA=ON \-D CUDA_ARCH_BIN="7.5;8.0;8.6;8.9" \-D WITH_GSTREAMER=ON \-D WITH_LIBV4L=ON \-D BUILD_opencv_python2=OFF \-D BUILD_opencv_python3=ON \-D PYTHON3_EXECUTABLE=$(which python) \-D PYTHON3_INCLUDE_DIR=$(python -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \-D PYTHON3_NUMPY_INCLUDE_DIRS=$(python -c "import numpy; print(numpy.get_include())") \-D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.8.0/modules \-D INSTALL_PYTHON_EXAMPLES=OFF \-D INSTALL_C_EXAMPLES=OFF \-D BUILD_EXAMPLES=OFF \../opencv-4.8.0 #這里是上面對應的mv opencv-4.8.0 opencv 重命名后的路徑# 編譯(使用CPU核心數加速)
make -j$(nproc)
# 安裝到指定路徑(根據腳本中的install_path變量)
make install
注意:CUDA_ARCH_BIN
參數應根據你的GPU架構調整。常見值:
- RTX 40系列:8.9
- RTX 30系列:8.6
- RTX 20系列:7.5
- GTX 10系列:6.1
- Tesla V100:7.0
- 自動檢測:使用
-D CUDA_ARCH_BIN=Auto
(需要NVCC)
6. 編譯并安裝
# 使用cmake編譯
make-j$(nproc)# 安裝到Conda環境
make install
生成好的opencv庫以及對應的文件將會報存在創建的環境對應的目錄下
7. 驗證安裝
# 激活環境(如果尚未激活)
conda activate opencvcuda# 驗證OpenCV版本和功能
python -c "
import cv2
print(f'OpenCV version: {cv2.__version__}')# 檢查CUDA支持
cuda_available = cv2.cuda.getCudaEnabledDeviceCount() > 0
print(f'CUDA support: {"? Yes" if cuda_available else "? No"}')# 檢查GStreamer支持
try:cap = cv2.VideoCapture('videotestsrc ! video/x-raw, format=BGRx ! videoconvert ! appsink', cv2.CAP_GSTREAMER)gstreamer_available = cap.isOpened()cap.release()print(f'GStreamer support: {"? Yes" if gstreamer_available else "? No"}')
except:print('? GStreamer check failed')
"
運行結果為:
8. 使用GStreamer硬解碼和CUDA加速的示例
import cv2
import numpy as npdef main():video_path = "2018_0412_115801_006.MP4"# 根據實際視頻編碼調整parse插件(示例為H.264) 硬解碼不行,提示無法找到nvv4l2decoder,應該是jetson平臺的'''gstreamer_pipeline = (f"filesrc location={video_path} ! ""qtdemux ! ""h264parse ! " "nvv4l2decoder ! ""nvvidconv ! ""video/x-raw, format=BGRx ! ""videoconvert ! ""appsink")'''#x86平臺用Nvidia nvcodec 插件組的核心組件nvh264dec,專為GPU硬件解碼優化gstreamer_pipeline = (f"filesrc location={video_path} ! ""qtdemux ! ""h264parse ! " "nvh264dec ! " "videoconvert ! ""video/x-raw,format=BGR !""appsink")# 簡化后的CPU解碼管道(替換原pipeline)軟解碼能用'''gstreamer_pipeline = (f"filesrc location={video_path} ! qtdemux ! h264parse ! avdec_h264 ! " # 使用CPU解碼器avdec_h264"videoconvert ! video/x-raw,format=BGR ! appsink")'''print(gstreamer_pipeline)cap = cv2.VideoCapture(gstreamer_pipeline, cv2.CAP_GSTREAMER)if not cap.isOpened():print("Error opening video stream")return# 移除未使用的gpu_bgr變量if cv2.cuda.getCudaEnabledDeviceCount() > 0:gpu_frame = cv2.cuda_GpuMat()gpu_gray = cv2.cuda_GpuMat() # 僅保留需要的變量while True:ret, frame = cap.read()if not ret:breakif cv2.cuda.getCudaEnabledDeviceCount() > 0:try:gpu_frame.upload(frame)gpu_gray = cv2.cuda.cvtColor(gpu_frame, cv2.COLOR_BGR2GRAY)gray = gpu_gray.download()except Exception as e:print(f"GPU處理失敗: {str(e)}")# 可回退到CPU處理gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)else:gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imshow("CUDA + GStreamer Demo", gray)if cv2.waitKey(1) & 0xFF == 27:breakcap.release()cv2.destroyAllWindows()if __name__ == "__main__":main()
啟動的時候顯卡情況:
在這里,我嘗試了使用nvv4l2decoder來進行硬解碼,但是我始終無法正確使用它,只能用nvv4l2decoder適合在jetson平臺下使用的理由說服自己,有能用成功的請留言告知,后面更換為nvh264dec進行硬解碼,這個能成功。
常見問題及解決方法
-
CMake找不到CUDA:
- 確保系統已安裝CUDA:
nvcc --version
- 設置CUDA路徑:
export CUDA_HOME=/usr/local/cuda
- 在CMake配置中添加:
-D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda
- 確保系統已安裝CUDA:
-
GStreamer錯誤:
- 安裝更多GStreamer插件:
sudo apt-get install gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly
- 檢查環境變量:
export GST_PLUGIN_PATH=/usr/lib/x86_64-linux-gnu/gstreamer-1.0/
- 安裝更多GStreamer插件:
-
編譯失敗:
- 清除構建目錄并重新開始:
rm -rf build && mkdir build && cd build
- 檢查CMake輸出日志,查找缺失的依賴
- 清除構建目錄并重新開始:
-
Python導入錯誤:
- 確保OpenCV已正確安裝到Conda環境:
ls $CONDA_PREFIX/lib/python3.8/site-packages/cv2
- 嘗試重新激活環境:
conda deactivate && conda activate opencv-gpu
- 確保OpenCV已正確安裝到Conda環境:
-
cmake過程中需要下載東西:
- 編譯過程中wechat_qrcode: Downloading detect.caffemodel from
https://raw.githubusercontent.com/WeChatCV/opencv_3rdparty/a8b69ccc738421293254aec5ddb38bd523503252/detect.caffemodel
這個地方卡住了,",“multiMedia”:[],“parsedQuery”:["編譯過程中wechat_qrcode: Downloading detect.caffemodel from ",{“type”:“web_page”,“url”:“https://raw.githubusercontent.com/WeChatCV/opencv_3rdparty/a8b69ccc738421293254aec5ddb38bd523503252/detect.caffemodel”,“unlinkText”:“取消鏈接”},"這個地方卡住了,可以手動下載放到構建的緩存目錄中,路徑為: /opencv_build/build/downloads/wechat_qrcode/
- 編譯過程中wechat_qrcode: Downloading detect.caffemodel from
-
import cv2報錯:
>>> import cv2Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/home/a/anaconda3/envs/opencvcuda/lib/python3.9/site-packages/cv2/__init__.py", line 181, in <module>bootstrap()File "/home/a/anaconda3/envs/opencvcuda/lib/python3.9/site-packages/cv2/__init__.py", line 153, in bootstrapnative_module = importlib.import_module("cv2")File "/home/a/anaconda3/envs/opencvcuda/lib/python3.9/importlib/__init__.py", line 127, in import_modulereturn _bootstrap._gcd_import(name[level:], package, level)ImportError: /home/a/anaconda3/envs/opencvcuda/lib/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /home/a/anaconda3/envs/opencvcuda/lib/libopencv_gapi.so.408)
原因:conda環境中的 libstdc++.so.6 (來自 libstdcxx-ng 包)版本過低,無法滿足OpenCV編譯庫 libopencv_gapi.so.408 對 GLIBCXX_3.4.30 的依賴。
最好的解決方法是更新 libstdcxx-ng 包,比如:conda install libstdcxx-ng=13.2.0
,但是我的環境無法獲取到這個版本,只能獲取到11.2的,當然你也可以升級conda,我選擇的方式是到Anaconda.org查找目標版本,下載后手動安裝:conda install /path/to/downloaded/libstdcxx-ng-13.2.0-hc0a3c3a_8.conda
7. 驗證過程中:對于 libgstgtk.so 的 Wayland 錯誤::
sudo apt-get install gstreamer1.0-gl libwayland-dev
對于 libgstqmlgl.so
的 Qt 錯誤:
sudo apt-get install qtwayland5 libqt5waylandclient5-dev
通過以上步驟,你可以在Conda環境中成功編譯并使用支持CUDA和GStreamer的OpenCV版本,同時保持與系統環境的隔離。