linux下实现Python调用海康威视SDK

---作者疆,未经允许,严禁转载,违权必究---

---欢迎指正,需要源码和文件可站内私信联系---

-----------点击此处链接至博客园原文-----------

 

功能说明:将C++版的海康威视官方SDK封装、编译成动态共享对象(linux中称为DSO,Dynamic Shared Objects,windows中称动态链接库),供Python调用实现相关功能

运行环境:ubuntu14.04或ubuntu16.04、opencv2.4.13.5或opencv2.4.13.6、swig3.0.8、codeblocks16.01、Python2.7.6(仅在上述运行环境中验证过该博客有效性)

 

 

一、相关介绍

参考链接:swig扩展opencv Python调用C++(极重要参考)

本节主要介绍在linux系统下将C++源文件封装、编译为.so动态共享对象的大致流程和细节。swig是simplified wrapper and interface generator的缩写,是一个非常优秀的开源工具,支持将 C/C++代码与任何主流脚本语言相集成。其中,必须编写一个额外的接口文件(.i文件)来作为swig(终端工具)的入口。这里引用上文中(未调用opencv的简单)例子对该流程进行叙述。(若调用了opencv函数,则需利用opencv-swig接口文件,将在“四”中以例子形式介绍)

//example.hpp
#ifndef example_hpp
#define example_hpp
#include <iostream>
#include <vector>
class Test{
public:
    Test(){
        for(int i=0;i<10;i++) v.push_back(i);
    }
    void see();
private:
    std::vector<int> v;
};
#endif
//example.cpp
#include "example.hpp"
#include <stdio.h>
using namespace std;
void Test::see(){
    for(int i=0;i<(this->v).size();i++) 
        printf("%d ",v[i]);
}

example.i文件如下:

%module example
%include "std_vector.i"
%{
    #include "example.hpp"
%}
%include "example.hpp"

其中,example.cpp为C++源文件,定义了相关函数方法;example.hpp是对应的头文件,里面还定义了要封装的函数方法;为了实现封装,编写了对应接口文件example.i。

example.i中第一行 %module后面的名字(example)是被封装的模块名称,Python通过这个名称来加载程序;第二行是该.i文件依赖的头文件,vector本来是STL里面的,但是swig已经有对应的"std_vector.i"写好了,所以可以直接include "std_vector.i";第三行至第五行大括号中包含了该.i文件需要的一些函数声明和头文件;最后一行是声明了要封装的函数和变量,由于函数声明写在了头文件里,如果需要全部封装可以直接%include 头文件名(example.hpp)。

现在,就可以利用swig封装代码,生成预编译C++文件.cxx和.py文件 执行命令 swig -python -c++ example.i    (#将对应生成example.cxx :编译c++时用;example.py:python import包时使用)

接着,可以使用python内置的distutils库编译上述.cxx文件,该python脚本(setup.py)如下:

from distutils.core import setup,Extension
setup(name = "example", 
      version = "1.0", 
    ext_modules = [Extension("_example", ["example_wrap.cxx",   "example.cpp"],
   extra_compile_args = ['-std=c++11'])],
   py_modules=['example'])

执行命令 sudo python setup.py install  (#注意模块名称_example前面一定要加下划线、这会将生成的_example.so 和 example.py 送到python对应的package文件夹),接着可以执行:

In [1]: from example import *
In [2]: x = Test()
In [3]: x.see()
0 1 2 3 4 5 6 7 8 9

大致上,封装C++函数、编译动态共享对象供Python调用就是这个过程,若涉及调用opencv等函数库,情况和处理更为复杂一些,将在后文“四”中以例子形式叙述。上述文件(百度云盘备份不对外提供)。

二、环境搭建之opencv安装方法

参考链接:linux下Python调用海康SDK实时显示网络摄像头linux设置opencv环境变量linux下QT环境搭建及opencv交叉编译(可不参考)

opencv通常采用源码编译安装,常见的可利用cmake-qt-gui交叉编译或cmake编译安装。本人ubuntu14.04工作站很早就利用cmake-qt-gui预装了opencv2.4.13.6,在这里叙述利用cmake编译安装opencv2.4.13的方法(在ubuntu16.04上验证过)。如果在安装opencv之前机器预装了高版本的cuda9.0(cuda9.0不再支持2.0架构),照此方法会出错,将在后文“五”中叙述报错内容及解决方法,没有安装过cuda或安装cuda8.0等低版本可以参考本节opencv安装方法。

首先,安装依赖包,执行以下命令:

#更新软件源
sudo apt-get update
#-y表示yes,build-essential、cmake等为一系列依赖包 sudo apt
-get install -y build-essential cmake git libopencv-dev libgtk2.0-dev pkg-config libavcodec-dev libpng12-dev libavformat-dev libswscale-dev yasm libxine2 libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev libqt4-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils sudo apt-get install -y libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff5-dev libjasper-dev libdc1394-22-dev

然后,网上下载opencv2.4.13压缩包文件(以opencv-2.4.13.6.zip为例),将压缩包拷贝到主文件夹(/home/rcnn ,rcnn为本人机器用户名),执行以下命令:

unzip opencv-2.4.13.6.zip
cd opencv-2.4.13.6
#mkdir命令新建opencv-debug目录,用于存放编译后的文件
mkdir opencv-debug cd opencv-debug #精简版编译安装 cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local .. #或选择cuda版安装 cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_CUDA=ON -D ENABLE_FAST_MATH=ON -D CUDA_FAST_MATH=ON -D WITH_CUBLAS=1 -D WITH_NVCUVID=on -D CUDA_GENERATION=Auto .. make sudo make install

以上推荐使用精简版编译安装,安装路径设置为/usr/local(实际上编译安装后文件存在于opencv-debug下,但会复制头文件、库文件等到上述指定的路径中,如/usr/local/include/opencv2、 /usr/local/include/opencv、 /usr/include/opencv、 /usr/include/opencv2、 /usr/local/share/opencv、 /usr/local/share/OpenCV、 /usr/share/opencv、 /usr/share/OpenCV、 /usr/local/bin/opencv*、 /usr/local/lib/libopencv*)。然后,配置环境变量:

#新建opencv配置文件,gedit与vim均为文本编辑工具
sudo gedit /etc/ld.so.conf.d/opencv.conf
#在该文件中输入下句(依赖库路径)并保存关闭
/usr/local/lib   
#使配置生效
sudo ldconfig
#打开bash并配置
sudo gedit /etc/bash.bashrc  
#在该文件中输入下句(opencv.pc路径,该文件维护了opencv的相关信息,包含libs、cflags等)并保存
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig  
export PKG_CONFIG_PATH
#更新系统库缓存
#source /etc/bash.bashrc 
#更新数据库索引 #sudo updatedb

最后,可通过例子验证安装是否成功,具体可参考以上两个博客。上述文件(百度云盘备份不对外提供)。

三、环境搭建之swig和codeblocks

参考链接:linux下Python调用海康SDK实时显示网络摄像头ubuntu源码安装swig(博客一)、ubuntu源码安装swig(博客二)

swig在上文“一”中已经介绍过,而codeblocks是一款集成开发环境,在此使用主要是考虑到其方便添加各种库路径,执行以下命令:

#添加源,获取个人软件包档案源(ppa:personal package archives),将其添加至当前apt库中,并自动导入公钥
sudo add-apt-repository ppa:damien-moore/codeblocks-stable
#更新源 sudo apt update
#安装codeblocks(该源默认版本为16.01)和build-essential sudo apt install codeblocks build
-essential

在上述参考博客中,执行命令sudo apt-get install swig安装swig,可能会在最后编译.so动态链接库阶段产生如下报错:error:a comma operator cannot appear in a constant-expression...error:template argument 2 is invalid In function'cv::Vec<unsigned char,2>'*new_cv_Vec_Sl_uint8_t_Sc_2_Sg_SWIG_4(std::vec...。经过反复验证,发现是swig在封装得到的.cxx文件(6万行)中多余了很多小括号,若一行行去掉小括号该行不再报错。考虑到这主要是swig版本的问题(可能是软件源导致的问题,但又没找到合适的软件源),在ubuntu16.04上按上述更新源并安装的swig版本为swig3.0.8,而在ubuntu14.04却是swig2.0.11,若想安装swig3.0,需要执行sudo apt-get install swig3.0,但源中的版本是swig3.0.2,仍然会在最后编译时产生如上报错。这里,个人推荐先按sudo apt-get install swig或swig3.0安装,然后执行swig -version查看swig版本,若不是swig3.0.8建议执行sudo apt-get remove swig删除swig,并采用以下编译安装方法:(附swig下载地址),首先将swig-3.0.8压缩包拷贝至工程所在目录(本文中为/home/rcnn/HK_Double_Camera),执行以下命令:

cd /home/rcnn/HK_Double_Camera
#解压
tar -xzvf swig-3.0.8.tar.gz
#新建swigtool目录,用于存放swig编译文件
mkdir swigtool
cd swig-3.0.8
./configure --prefix=/home/rcnn/HK_Double_Camera/swigtool
#编译
make
#安装
make install sudo gedit
/etc/profile #输入以下两句并保存退出,即可在其他路径下也能执行swig命令 export SWIG_PATH=/home/rcnn/HK_Double_Camera/swigtool/bin export PATH=$SWIG_PATH:$PATH
#使配置生效
source /etc/profile
#若接着执行swig -version显示swig3.0.8则说明安装成功

此外,还需安装boost库(参考博客中未提及),执行以下命令:上述文件(百度云盘备份不对外提供)。

#搜索软件包
sudo apt-cache search boost
#安装 sudo apt
-get install libboost-dev

四、上手实验

参考链接:linux下Python调用海康SDK实时显示网络摄像头(唯一参考)

首先下载opencv-swig接口文件,点击下载。(在编写接口文件的时候,需要将依赖的头文件都添加进来,而opencv里面的文件繁多,在Github上面有人已经写好了)

然后,将接口文件lib文件夹下的文件(opencv文件夹和opencv.i)复制到工程目录下,与下面三个待封装编译的源文件处于同一目录下(本文中为/home/rcnn/HK_Double_Camera/)。其中,HKIPcamera.cpp文件将在以后博客中做专门注释解读。

//HKIPcamera.cpp
#include <opencv2/opencv.hpp>
#include <iostream>
#include <time.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <list>
#include "HCNetSDK.h"
#include "LinuxPlayM4.h"
#include <unistd.h>
#include <pthread.h>

#define USECOLOR 1
#define WINAPI

using namespace cv;
using namespace std;

//--------------------------------------------
int iPicNum = 0;//Set channel NO.
LONG nPort = -1;
HWND hWnd = NULL;
pthread_mutex_t g_cs_frameList;
list<Mat> g_frameList;
LONG lUserID;
NET_DVR_DEVICEINFO_V30 struDeviceInfo;
LONG lRealPlayHandle = -1;


void yv12toYUV(char *outYuv, char *inYv12, int width, int height, int widthStep)
{
int col, row;
unsigned int Y, U, V;
int tmp;
int idx;


//printf("widthStep=%d.\n",widthStep);


for (row = 0; row<height; row++)
{
idx = row * widthStep;
int rowptr = row*width;


for (col = 0; col<width; col++)
{
//int colhalf=col>>1;
tmp = (row / 2)*(width / 2) + (col / 2);
//         if((row==1)&&( col>=1400 &&col<=1600))
//         {
//          printf("col=%d,row=%d,width=%d,tmp=%d.\n",col,row,width,tmp);
//          printf("row*width+col=%d,width*height+width*height/4+tmp=%d,width*height+tmp=%d.\n",row*width+col,width*height+width*height/4+tmp,width*height+tmp);
//         }
Y = (unsigned int)inYv12[row*width + col];
U = (unsigned int)inYv12[width*height + width*height / 4 + tmp];
V = (unsigned int)inYv12[width*height + tmp];
//         if ((col==200))
//         {
//         printf("col=%d,row=%d,width=%d,tmp=%d.\n",col,row,width,tmp);
//         printf("width*height+width*height/4+tmp=%d.\n",width*height+width*height/4+tmp);
//         return ;
//         }
if ((idx + col * 3 + 2)> (1200 * widthStep))
{
//printf("row * widthStep=%d,idx+col*3+2=%d.\n",1200 * widthStep,idx+col*3+2);
}
outYuv[idx + col * 3] = Y;
outYuv[idx + col * 3 + 1] = U;
outYuv[idx + col * 3 + 2] = V;
}
}
//printf("col=%d,row=%d.\n",col,row);
}


//解码回调 视频为YUV数据(YV12),音频为PCM数据
void CALLBACK DecCBFun(int nPort, char * pBuf, int nSize, FRAME_INFO * pFrameInfo, void * nReserved1, int nReserved2)
{
long lFrameType = pFrameInfo->nType;


if (lFrameType == T_YV12)
{
#if USECOLOR
//int start = clock();
static IplImage* pImgYCrCb = cvCreateImage(cvSize(pFrameInfo->nWidth, pFrameInfo->nHeight), 8, 3);//???????????????????Y????????????
yv12toYUV(pImgYCrCb->imageData, pBuf, pFrameInfo->nWidth, pFrameInfo->nHeight, pImgYCrCb->widthStep);//????????????????RGB????????
static IplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth, pFrameInfo->nHeight), 8, 3);
cvCvtColor(pImgYCrCb, pImg, CV_YCrCb2RGB);
//int end = clock();
#else
static IplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth, pFrameInfo->nHeight), 8, 1);
memcpy(pImg->imageData, pBuf, pFrameInfo->nWidth*pFrameInfo->nHeight);
#endif
//printf("%d\n",end-start);


//Mat frametemp(pImg), frame;


//frametemp.copyTo(frame);
//      cvShowImage("IPCamera",pImg);
//      cvWaitKey(1);
pthread_mutex_lock(&g_cs_frameList);
Mat mat=cvarrToMat(pImg);
g_frameList.push_back(mat);
pthread_mutex_unlock(&g_cs_frameList);


#if USECOLOR
//      cvReleaseImage(&pImgYCrCb);
//      cvReleaseImage(&pImg);
#else
/*cvReleaseImage(&pImg);*/
#endif
//此时是YV12格式的视频数据,保存在pBuf中,可以fwrite(pBuf,nSize,1,Videofile);
//fwrite(pBuf,nSize,1,fp);
}
/***************
else if (lFrameType ==T_AUDIO16)
{
//此时是音频数据,数据保存在pBuf中,可以fwrite(pBuf,nSize,1,Audiofile);


}
else
{

}
*******************/


}


///实时流回调
void CALLBACK fRealDataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void *pUser)
{
DWORD dRet;
switch (dwDataType)
{
case NET_DVR_SYSHEAD:    //系统头
if (!PlayM4_GetPort(&nPort)) //获取播放库未使用的通道号
{
break;
}
if (dwBufSize > 0)
{
if (!PlayM4_OpenStream(nPort, pBuffer, dwBufSize, 1024 * 1024))
{
dRet = PlayM4_GetLastError(nPort);
break;
}
//设置解码回调函数 只解码不显示
if (!PlayM4_SetDecCallBack(nPort, DecCBFun))
{
dRet = PlayM4_GetLastError(nPort);
break;
}


//设置解码回调函数 解码且显示
//if (!PlayM4_SetDecCallBackEx(nPort,DecCBFun,NULL,NULL))
//{
//  dRet=PlayM4_GetLastError(nPort);
//  break;
//}


//打开视频解码
if (!PlayM4_Play(nPort, hWnd))
{
dRet = PlayM4_GetLastError(nPort);
break;
}


//打开音频解码, 需要码流是复合流
//          if (!PlayM4_PlaySound(nPort))
//          {
//              dRet=PlayM4_GetLastError(nPort);
//              break;
//          }     
}
break;

case NET_DVR_STREAMDATA:   //码流数据
if (dwBufSize > 0 && nPort != -1)
{
BOOL inData = PlayM4_InputData(nPort, pBuffer, dwBufSize);
while (!inData)
{
sleep(10);
inData = PlayM4_InputData(nPort, pBuffer, dwBufSize);
cout << (L"PlayM4_InputData failed \n") << endl;
}
}
break;
}
}


void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
{
char tempbuf[256] = { 0 };
switch (dwType)
{
case EXCEPTION_RECONNECT:    //预览时重连
printf("----------reconnect--------%d\n", time(NULL));
break;
default:
break;
}
}

bool OpenCamera(char* ip, char* usr, char* password)
{
lUserID = NET_DVR_Login_V30(ip, 8000, usr, password, &struDeviceInfo);
if (lUserID == 0)
{
cout << "Log in success!" << endl;
return TRUE;
}
else
{
printf("Login error, %d\n", NET_DVR_GetLastError());
NET_DVR_Cleanup();
return FALSE;
}
}
void * ReadCamera(void* IpParameter)
{
//---------------------------------------
//设置异常消息回调函数
NET_DVR_SetExceptionCallBack_V30(0, NULL, g_ExceptionCallBack, NULL);
//cvNamedWindow("Mywindow", 0);
//cvNamedWindow("IPCamera", 0);
//HWND  h = (HWND)cvGetWindowHandle("Mywindow");
//h = cvNamedWindow("IPCamera");
//---------------------------------------
//启动预览并设置回调数据流 
NET_DVR_CLIENTINFO ClientInfo;
ClientInfo.lChannel = 1;        //Channel number 设备通道号
ClientInfo.hPlayWnd = NULL;     //窗口为空,设备SDK不解码只取流
ClientInfo.lLinkMode = 1;       //Main Stream
ClientInfo.sMultiCastIP = NULL;

LONG lRealPlayHandle;
lRealPlayHandle = NET_DVR_RealPlay_V30(lUserID, &ClientInfo, fRealDataCallBack, NULL, TRUE);
if (lRealPlayHandle<0)
{
printf("NET_DVR_RealPlay_V30 failed! Error number: %d\n", NET_DVR_GetLastError());
//return -1;
}
else
cout << "码流回调成功!" << endl;
sleep(-1);
//fclose(fp);
//---------------------------------------
//关闭预览
if (!NET_DVR_StopRealPlay(lRealPlayHandle))
{
printf("NET_DVR_StopRealPlay error! Error number: %d\n", NET_DVR_GetLastError());
return 0;
}
//注销用户
NET_DVR_Logout(lUserID);
NET_DVR_Cleanup();
//return 0;
}

void init(char* ip, char* usr, char* password){
pthread_t hThread;
cout << "IP:" << ip << "    UserName:" << usr << "    PassWord:" << password << endl;
NET_DVR_Init();
NET_DVR_SetConnectTime(2000, 1);
NET_DVR_SetReconnect(10000, true);
OpenCamera(ip, usr, password);
pthread_mutex_init(&g_cs_frameList, NULL);
//hThread = ::CreateThread(NULL, 0, ReadCamera, NULL, 0, 0);
pthread_create(&hThread, NULL, ReadCamera, NULL);
}

Mat getframe(){
Mat frame1;
pthread_mutex_lock(&g_cs_frameList);
while (!g_frameList.size()){
pthread_mutex_unlock(&g_cs_frameList);
pthread_mutex_lock(&g_cs_frameList);
}
list<Mat>::iterator it;
it = g_frameList.end();
it--;
Mat dbgframe = (*(it));
(*g_frameList.begin()).copyTo(frame1);
frame1 = dbgframe;
g_frameList.pop_front();
//imshow("camera", frame1);
//waitKey(1);

g_frameList.clear();
pthread_mutex_unlock(&g_cs_frameList);
return(frame1);
}


void release(){
//close(hThread);
NET_DVR_StopRealPlay(lRealPlayHandle);
//注销用户
NET_DVR_Logout(lUserID);
NET_DVR_Cleanup();
}
//HKIPcamera.h
#include <opencv2/opencv.hpp>
using namespace cv;

void init(char* ip, char* usr, char* password);
Mat getframe();
void release();
// HKIPcamera.i
/*  Example of wrapping a C function that takes a C double array as input using
 *  numpy typemaps for SWIG. */
%module HKIPcamera
%include <opencv/mat.i>
%cv_mat__instantiate_defaults
%header %{
    /*  Includes the header in the wrapper code */
    #include "HKIPcamera.h"
%}


%include "HKIPcamera.h"

有了“一”中的理解,这里看起来可能不那么费劲了,执行以下命令:

#进入.i文件所在目录
cd /home/rcnn/HK_Double_Camera
#封装,-I与opencv的core文件夹、core.hpp路径中间无空格
swig -I/home/rcnn/opencv-2.4.13.6/modules/core/include -python -c++ HKIPcamera.i

将能在同级目录得到HKIPcamera.cxx和HKIPcamera.py文件。

然后,利用codeblocks进行编译(实际上也可用命令行编译,但由于依赖库、头文件太多、命令行比较长...),在codeblocks中新建shared library工程,依此选择GO---Next---C++----工程名取为“HKIPcamera”(路径为  /home/rcnn/HK_Double_Camera/HKIPcamera)---next---finish,删除新建工程的main.cpp,右键工程名Add files----选择文件----确定,依此添加HKIPcamera.cpp,HKIPcamera.h,HKIPcamera_wrap.cxx文件

在codeblocks中进行如下配置时,(右键工程名---Build options)左边任选debug或release模式,与最后编译方式一致即可

Build options---Linker settings---Linker libraries中添加opencv和海康威视SDK的所有库文件路径,如下图所示,分别进入/home/rcnn/opencv-2.4.13.6/opencv-debug/lib/、

/home/rcnn/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib和/home/rcnn/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib/HCNetSDKCom路径下选择所有.so和.a文件。(建议不选择相对路径)

 

Build options---Search directories – Compiler中添加所有头文件路径:/usr/local/include/ 、/usr/local/include/opencv、/usr/local/include/opencv2、

/home/rcnn/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/include、/usr/include/python2.7、/usr/include/boost(一共5个路径,其中3个是opencv头文件路径,1个是Python.h,1个是boost库头文件路径)

Build options---Search directories---Linker添加/usr/local/lib路径(一系列有关的库文件)

Build options---Compiler settings---Other compiler options添加 -fPIC(-fPIC表明使用地址无关代码,Linux下编译共享库时,必须加上-fPIC参数,否则在链接时会有错误提示,点击这里了解fPIC更多知识

主界面---Settings---Compiler settings---Linker settings---左边Linker libraries 添加 /usr/lib/x86_64-linux-gnu/libpthread.a 右边 Other linker options 添加 -lpthread,如下图所示: (与海康威视源文件中多线程有关,cpp文件中含头文件 pthread.h)

将海康威视SDK动态链接库地址添加进系统路径,执行以下命令:

sudo gedit /etc/ld.so.conf
#末尾添加
/home/rcnn/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib  
/home/rcnn/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib/HCNetSDKCom
#保存退出
sudo ldconfig

对应于上述设置,选择debug或release模式,点击build或rebuild,可见如下编译命令,将在工程目录(/home/rcnn/HK_Double_Camera/HKIPcamera/bin/Debug)下生成libHKIPcamera.so动态共享对象。

注意:若以后再次打开codeblocks工程,出现死机现象,删除工程下的.layout文件即可解决。

最后,工程目录下新建test文件夹,将libHKIPcamera.so改名为_HKIPcamera.so,与swig封装时产生的HKIPcamera.py文件一同放置在test目录(/home/rcnn/HK_Double_Camera/test)下,新建如下test.py文件。

import HKIPcamera
import time
import numpy as np
import matplotlib.pyplot as plt
import cv2

ip = str('192.168.1.64')  #摄像头IP地址,要和本机IP在同一局域网
name = str('admin')       #管理员用户名
pw = str('12345678')      #管理员密码
HKIPcamera.init(ip, name, pw)
while True:
    fram = HKIPcamera.getframe()
    cv2.imshow('show_img', np.array(fram))
    cv2.waitKey(1)
#HKIPcamera.release()
#time.sleep(5)

若之前未安装Python常用第三方库(cv2等)和配置本机IP,还需按下述处理:

sudo apt-get update
sudo apt-get install cython python-opencv python-tk python-scipy python-yaml
sudo pip install easydict
sudo python -m pip install Pillow
sudo apt-get install python-matplotlib

配置IP(右上角扇形符号---以太网有线连接---编辑---IPv4设置---手动---填写地址192.168.1.XXX、子网掩码255.255.255.0、网关0.0.0.0----保存),保证本机与摄像头IP在同一网段即可,最后执行test.py,大功告成!上述文件(百度云盘备份不对外提供)。

五、遇到的一些坑

(1)预装cuda9.0再安装opencv遇到的问题(以下解决办法摘录自参考链接)

参考链接:博客一博客二博客三

若在编译安装opencv前机器预装了cuda9.0,直接按上文“二”中编译安装方式将会报错如下:

CMake Error:The following variables are used in this project, but they are set to NOTFOUND...

linked by target "opencv_cudev"in directory .../opencv/sources/modules/dudev...

因此,需要先修改相关脚本文件,再按“二”中进行编译安装。修改如下:

find_cuda_helper_libs(nppial)
find_cuda_helper_libs(nppicc)
find_cuda_helper_libs(nppicom)
find_cuda_helper_libs(nppidei)
find_cuda_helper_libs(nppif)
find_cuda_helper_libs(nppig)
find_cuda_helper_libs(nppim)
find_cuda_helper_libs(nppist)
find_cuda_helper_libs(nppisu)
find_cuda_helper_libs(nppitc)
set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppial_LIBRARY};${CUDA_nppicc_LIBRARY};${CUDA_nppicom_LIBRARY};${CUDA_nppidei_LIBRARY};${CUDA_nppif_LIBRARY};${CUDA_nppig_LIBRARY};${CUDA_nppim_LIBRARY};${CUDA_nppist_LIBRARY};${CUDA_nppisu_LIBRARY};${CUDA_nppitc_LIBRARY};${CUDA_npps_LIBRARY}")

个人经验:将有关compute20脚本删除(文本中搜索2.0 2.X 1.X之类的均可删除,保留3.X)

(2)swig版本的问题

尝试过swig2.0.11、swig3.0.2和swig3.0.8,只在swig3.0.8下编译成功,其余版本均报错如下,具体解决办法可参见上文“三”。

 

六、其他

(1)如何卸载opencv

参考链接:ubuntu卸载opencv(仅参考“一”)

若是按上文“二”中编译安装opencv,可执行以下命令卸载opencv(注意做好文件备份)

cd /home/rcnn/opencv-2.4.13.6/opencv-debug
sudo make uninstall
cd ..
sudo rm -r build
sudo rm -r /usr/local/include/opencv2 /usr/local/include/opencv /usr/include/opencv /usr/include/opencv2 /usr/local/share/opencv /usr/local/share/OpenCV /usr/share/opencv /usr/share/OpenCV /usr/local/bin/opencv* /usr/local/lib/libopencv*

(2)如何卸载swig等ubuntu软件

参考链接:linux中卸载软件的几种命令ubuntu系统中默认安装路径、安装、卸载方法总结

由于swig是用apt-get安装的,可用sudo apt-get remove swig进行卸载,其余可能用到的卸载命令如下:

(3)源是什么

参考链接:ubuntu中的PPA源是什么?ubuntu添加PPA源

PPA源(Personal Package Archives)个人软件包文档,只有Ubuntu用户可以用,而所有的PPA都是寄存在launchpad.net网站上。Launchpad(启动器)是Canonical公司所架设的网站,是一个提供维护、支援或连络Ubuntu开发者的平台。其中Launchpad提供了线上翻译软件的功能,可以自由的参与Ubuntu或相关自由软件的开发或翻译工作。也可以利用该网站的回报机制来回报相关软件的Bug,或者进一步提供建议。使用PPA的好处是Ubuntu系统中使用PPA源的软件可以让你在第一时间体验到最新版本的软件。有很多PPA软件源提供多个版本,包括正式稳定版、每日创建版,开发版、测试版等。一个完整的通过PPA源安装软件的命令,例如添加chromium稳定版源(其网址为https://launchpad.net/~chromium-daily/+archive/stable)并安装的命令:(上文“三”中安装codeblocks与之类似)

#添加源,自动导入密钥等内容
sudo add-apt-repository ppa:chromium-daily/stable#更新源 
sudo apt-get update 
#安装chromium软件
sudo apt-get install chromium

实际上,执行命令sudo add-apt-repository ppa:chromium-daily/stable,即向/etc/apt/sources.list 源文件列表自动添加了(以下两行)两个软件源:(下图为chromium页面相关介绍)

deb http://ppa.launchpad.net/chromium-daily/stable/ubuntu YOUR_UBUNTU_VERSION_HERE main 
deb-src http://ppa.launchpad.net/chromium-daily/stable/ubuntu YOUR_UBUNTU_VERSION_HERE main 

对于“源”,有时候还会遇见一些问题,比如网速慢,比如“W 无法下载,无法发起与cn.archive.ubuntu.com...”的连接,这主要是由于被墙了原因,可以切换到国内源解决,即将/etc/apt/sources.list内cn.archive.ubuntu.com改为mirrors.aliyun.com,替换完成后再sudo apt update,记住备份原来的/etc/apt/sources.list。

(4)环境变量

参考链接:ubuntu12.04添加环境变量linux环境变量及其设置/etc/ld.so.conf详解

环境变量分为系统级和用户级

系统级变量设置环境为/etc/environment、/etc/profile等,不要轻易修改,易造成系统错误。

用户级变量设置路径为~/.bashrc、~/.bash_profile等(用户主目录~下隐藏文件),bashrc负责控制台调用的环境变量,profile负责本用户所有环境变量的设置。

 

(5)多版本opencv共存

之前怀疑是opencv版本的问题,差点就入坑了,多版本并存问题尽量避免吧,易混乱,可参考博客一博客二

(6)C++版的opencv与python-opencv的不同

个人总结一句:opencv本身就是C++写的,功能十分齐全,编译安装后内存很大;python-opencv对应的貌似是cv2.pyd,类似于动态链接库,内部集成了常见的函数方法,内存比较小。

 

posted @ 2019-04-03 17:43  JiangJ~  阅读(14840)  评论(32编辑  收藏  举报