在Linux下海康威视SDK编译为python库的教程
背景:公司需要在python的环境中对接有线和无线的海康威视摄像头,方便进行二次开发。我尝试过用rtsp + opencv 对接,由于opencv内部有集成rtsp协议,所以只需要数行代码就可播放,但是这种方法两个缺点:1.会出现h264解码的报错 2.网络不稳定的时候,无线摄像头很容易断流,一旦断流python程序无法自启。接着,我用ffmpeg的命令行去对接rtsp,不断截图,成功解决了问题1,但是断流的问题无法解决,另外由于是命令行,我无法对采集回来的图像直接处理和异常判断,降低了程序的整体性能和可靠性。最后实在没办法,我转战海康威视SDK,做二次开发,最终实现的效果是 实时获取视频 + 断开重连。
比较:
方法 | 协议 | 延迟 | 难易度 | 缺点 |
---|---|---|---|---|
opencv对接rtsp | rtsp | 2-3秒 | 低 | 解码报错,断流无法自启 |
ffmpeg对接rtsp | rtsp | 2-3秒 | 低 | 断流无法自启,读写图片文件时会出现阻塞 |
海康威视SDK | onvif | 无 | 中 | 依赖官方SDK |
基础环境:
1.Ubuntu-18.10-desktop-amd64
2.海康SDK Linux x64
3.Python3.7
1 准备环境
1.1 下载海康威视SDK,linux x64版
1.2 下载opencv 3.4.6,解压^2
安装依赖:
1 | sudo apt-get install build-essential |
可能出现 E: Unable to locate package libjasper-dev
报错,可以不安装这个文件,或者用以下指令解决^3:
1 | sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main" |
开始对opencv进行编译,进入文件夹cd opencv-3.4.6
,创建build文件夹mkdir build
,进入build文件夹cd build
,cmake编译(这里我没有使用opencv_contrib-3.4.6):
1 | cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local .. |
编译过程中,可能会卡在IPPICV: Download: ippicv_2019_lnx_intel64_general_20180723.tgz
,需要手动下载压缩包并更改文件加载路径[^4],下载压缩包:
修改文件vim /home/opencv-3.4.6/3rdparty/ippicv/ippicv.cmake
将这行代码:
"https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}ippicv/"
更换为ippicv_2019_lnx_intel64_general_20180723.tgz
所在路径:
"file:~/home/"
最后,make install:
1 | sudo make |
1.3 安装code::blocks
sudo add-apt-repository ppa:damien-moore/codeblocks-stable
sudo apt update
sudo apt install codeblocks build-essential
1.4 安装swig
sudo apt-get install swig
1.5 下载opencv-swig,解压
1.6 安装python3-dev
执行sudo apt-get install python3-dev
,会在/usr/include/python3.7
产生一个Python.h
的文件,否则编译会出现python.h:no such file or diectory
报错
1.7 安装boost
1 | sudo apt-get install mpi-default-dev -y |
下载对应版本,解压tar -zxvf boost_1_70_0.tar.gz
,进入目录cd boost_1_70_0
,执行以下命令安装:
1 | ./bootstrap.sh |
2 处理接口文件
2.1 下载接口文件
下载文件HKIPcamera.cpp
,HKIPcamera.h
,HKIPcamera.i
,也可以去这篇博客复制保存,下载链接:
2.2 cpp用swig转py
将三个接口文件放入 opencv-swig/lib
中,cd 进入该文件目录,用以下指令生成HKIPcamera.cxx
和HKIPcamera.py
文件,其中opencv-3.4.6的路径要替换成自己的:
swig -I/home/quake/opencv-3.4.6/modules/core/include/ -python -c++ HKIPcamera.i
生成结果如图:
2.3 添加环境变量
编辑文件sudo vim /etc/ld.so.conf
,在末尾追加SDK路径(注意:如果在最后调试运行的时候提示opencv相关的so文件找不到,也可以把opencv/bulid/lib路径追加到该文本中):
/home/quake/CH-HCNetSDKV6.0.2.35_build20190411_Linux64/lib
/home/quake/CH-HCNetSDKV6.0.2.35_build20190411_Linux64/lib/HCNetSDKCom
生效执行sudo ldconfig
编辑文件sudo vim /etc/profile
,在末尾追加:
export LD_LIBRARY_PATH=SLD_LIBRARY_PATH:/home/quake/CH-HCNetSDKV6.0.2.35_build20190411_Linux64:/home/quake/CH-HCNetSDKV6.0.2.35_build20190411_Linux64/lib
生效执行source /etc/profile
3 编译文件
3.1 工程环境
1 打开安装好的code::blocks,file > new > project > 新建shared library工程:
2 确定,Next ,选择c++编译:
3 输入工程名称和工程路径:
4 右键工程 > Add files,将生成好的HKIPcamera.cpp
,HKIPcamera.h
和HKIPcamera_wrap.cxx
添加到工程中:
5 右键工程 >Build option > Compiler settings > Other compiler options 添加 -fPIC
6 选择 Linker settings,添加所有的Opencv链接库文件(opencv-3.4.6 > build > lib),添加海康SDK中
CH-HCNetSDKV6.0.2.35_build20190411_Linux64/lib
以及CH-HCNetSDKV6.0.2.35_build20190411_Linux64/lib/HCNetSDKCom
下的所有so文件:
7 search directories > Compiler中添加头文件索引:
/usr/local/include/
/usr/local/include/opencv/
/usr/local/include/opencv2/
/CH-HCNetSDKV6.0.2.35_build20190411_Linux64/incCn
/CH-HCNetSDKV6.0.2.35_build20190411_Linux64/QtDemo/includeCn
/usr/include/python3.7
8 search directories > Linker中添加/usr/local/lib
9 OK保存,在Settings > Complier settings > Link settings >Linker libraries 添加 /usr/lib/x86_64-linux-gnu/libpthread.a
,右边Other linker options添加-lpthread
注意,Linux 32位下需要更改为:/usr/lib/i386-linux-gnu/libpthread.a
3.2 编译
右键工程rebuild,然后在工程目录下找到HKIPcamera/bin/Release
或者/Debug
中的libHKIPcamera.so
4 调试运行
拷贝以下代码,新建test.py文件:
1 | #test.py |
将libHKIPcamera.so
改名为_HKIPcamera.so
,将HKIPcamera.py
,test.py
,_HKIPcamera.so
放在同一个文件夹中:
打开终端,输入 python3 test.py
,出现登陆成功,以及摄像头窗口,则成功。
注意:可能会出现 登陆失败的情况,确保2.3的环境配置正确,在每次执行 python3 test.py
之前执行 source /etc/profile
,我也不知道为什么要这么做可以,但是如果用V5.2.7.4_build20170606_Linux64就不存在这个问题,详情可以参考这篇博客的评论区。
5 总结
这次的教程是基于Ubuntu 18 x64编译的,但是我在Ubuntu 16 x86上也尝试过编译,过程几乎一模一样,只有个别细节需要修改,大家可以自行根据报错调整。另外我在debina 9 x86上也编译过,所有的过程和环境都是一样,编译成功后,运行test.py,会出现段错误的报错,我没有找到解决方案,但是如果我把Ubuntu x86编译好的文件直接复制是可以使用的。
其实本次编译的最终目的是,把SDK移植到树莓派上,当时只考虑到树莓派是 debian x32 的,编译完成才知道树莓派3B+ 是armv7的指令架构,和x86的架构完全不一样。海康的SDK是无法用在arm上的,另外如果执行 ldd -r libhcnetsdk.so
也会报不是有效文件的错误,所以花了这么久的时间,到最后也没有结果,这里告诉大家,避免浪费时间。
由于编译环境的不同,可能编译好的dll和so文件不能直接移植,不过还是放出来给大家参考一下:
6 参考文献
[^4]:opencv 解决ippicv下载问题,离线:ippicv_2019_lnx_intel64_general_20180723.tgz
[^5]:ubuntu下安装boost
[^6]: linux下Python调用海康SDK实时显示网络摄像头
[^7]: ubuntu系统opencv3.4.3安装