天天看點

ONVIF系列——c++使用gsoap onvif編寫onvif代碼并控制海康攝像頭1 環境要求編譯連結

最近的工作需要對海康攝像頭進行操作,同時環境是jetson nano的ubuntu18.04環境,海康sdk功能是比較多的,但是在類似于嵌入式的jetson nano闆子上,海康sdk是不支援的,是以需要使用其他的庫,比如說onvif,如果想了解onvif,請看ONVIF系列——Onvif協定介紹,如果想了解python控制onvif,請看ONVIF系列——python操控onvif.

對于c++的onvif庫,我将在網上找的資料附在末尾,同時将我實作的gsoap-onvif附在文章末尾。

這篇文章将不會講解gsoap代碼是怎麼來的,而是直接介紹onvif的c++代碼如何實作,讓你拿來就能用,直接編譯運作。

1 環境要求

該代碼是在jetson nano ubuntu 18.04,jetpack version為4.4.1上實作的,并成功運作。

  1. 一台jetson nano闆子(或者ubuntu 18.04系統的linux主機)
  2. github庫gsoap-onvif

請按照gsoap-onvif的readme訓示的去操作。我也會在下面進行再次叙述。

安裝openssl

gsoap-onvif需要用到openssl。當然,在Jetson 系列——jetson nano Ubuntu18.04安裝Openssl-1.1.1中有詳細的openssl介紹,雖然是1.1.1版本,但是大差不差。如果遇到安裝的報錯,或者安裝完以後編譯有報錯,可以到這篇文章裡找找看看有沒有是我遇到的問題。

# download openssl from web 
wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2l.tar.gz
tar -xzvf openssl-1.0.2l.tar.gz
cd openssl-1.0.2l
sudo ./config
sudo make 
sudo make test # you can test it with this line 
sudo make install 
# check openssl version
openssl version
           

這裡需要注意的是,openssl的版本是1.0.2l,最好按照要求得來,因為如果版本過高,可能有些代碼在編譯的過程中會報錯。

我們首先從官網上下載下傳openssl:

wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2l.tar.gz
           

然後解壓,并進入到解壓後的檔案夾中,下載下傳的路徑和解壓的路徑請随意選擇:

tar -xzvf openssl-1.0.2l.tar.gz
cd openssl-1.0.2l
           

下面是安裝openssl的過程,請注意,在安裝的過程中,最好使用sudo權限,因為需要在/usr/bin等地方建立檔案或者檔案夾。

sudo ./config
sudo make 
sudo make test # you can test it with this line 
sudo make install 
           

當安裝完成以後,請輸入

openssl version
           

檢視openssl的版本。如果檢視成功,并且版本号和我們安裝到版本号相同,那麼就安裝成功了。

安裝libssl1.0

sudo apt-get install libssl1.0-dev
           

當完成上面的步驟時,基本環境就算是安裝好了,當然,我這裡預設是安裝時了opencv的,并且opencv的版本是4.1.1。

編譯連結

一次封裝

這個項目有兩個可以編譯連結的地方,你可以試試對gsoap-onvif進行一次封裝的代碼.

首先進入factory檔案夾,并建立一個

build

檔案夾

cd factory
mkdir build
           

然後進行編譯連結

cmake ..
make 
           

你可以在

./factory/test/test_analyse.cpp

中找到測試的代碼,類似的代碼如下:

#include <chrono>
#include <iostream>
#include <sstream> 
#include "glog/logging.h"
#include "OnvifClientDevice.hpp"
#include "OnvifClientPTZ.hpp"
#include "OnvifClientMedia.hpp"

using namespace std;

int main(int argc, const char *argv[]) {
	
    std::string url = "192.168.66.64";
	std::string name = "admin";
	std::string password = "wst123456";
	OnvifClientPTZ *PTZ = new OnvifClientPTZ(url, name, password, true);
	OnvifClientMedia *Media = new OnvifClientMedia(url, name, password, true);
	std::vector<_ocp_Profile> get_profilesResponse;
	Media->getProfiles(get_profilesResponse);
	PTZ->gotoPreset(get_profilesResponse[0].profileToken,3,0.5);
	PTZ->getPresets(get_profilesResponse[0].profileToken);
    return 0;
}
           

可以看到,本項目調用了OnvifClientDevice,OnvifClientPTZ,OnvifClientMedia三個檔案,這三個檔案是對gsoap-onvif代碼的一次封裝,具體的封裝方法,你可以到

./factory/3rdparty/ssigonvif/ssig/

中看到源代碼。

那麼本項目的使用風格就是這樣。先聲明執行個體化PTZ和Media

OnvifClientPTZ *PTZ = new OnvifClientPTZ(url, name, password, true);
OnvifClientMedia *Media = new OnvifClientMedia(url, name, password, true);
           

注意執行個體化的時候要輸入該攝像頭的url,name,passwd。

随後,便可以調用這個類的方法,目前日常所需要的onvif操縱攝像頭的方法,都有實作,如果沒有,你也可以仿照的已經實作的方法進行二次開發。

例如調用攝像頭到某個預置位:

PTZ->gotoPreset(get_profilesResponse[0].profileToken,3,0.5);
           

注意這裡第一個輸入的來源,是需要從Media中擷取配置的參數

std::vector<_ocp_Profile> get_profilesResponse;
Media->getProfiles(get_profilesResponse);
           

然後将參數的傳回token傳入到接口中,因為onvif要進行認證,隻用這樣才能正常調用和控制,否則會出現沒有權限的情況。

又如stop,move等操作

PTZ->continuousMove(get_profilesResponse[0].profileToken, 0.5, 0, 0);
//sleep(2);
PTZ->stop(get_profilesResponse[0].profileToken, 0, 0);
PTZ->relativeMove(get_profilesResponse[0].profileToken, 0.0, 0.0, 0.0, 0.0, 0.5, 1);
           

對于ptz控制,media的config擷取或者device的config擷取,都可以看對應檔案下的函數實作,然後直接調用即可。

比如打開OnvifClientPTZ.hpp,可以看到實作了下面的方法,setHomePosition的設定初始位置,goToHomePosition的複位,panLeft的向左多少度等操作,可以根據提示進行使用。

void setHomePosition(std::string profileToken);
void goToHomePosition(std::string profileToken);
// pan to the left n Degress
void panLeft(std::string profileToken, int nDegrees);
// pan to the right n Degrees
void panRight(std::string profileToken, int nDegrees);
void tiltDown(std::string profileToken, int nDegrees);
void tiltUp(std::string profileToken, int nDegrees);
           

二次封裝

也有一個二次封裝的代碼,即

/src

檔案夾下的

teacher.cpp

,将onvif中的ptz和media等封裝成了一個類,需要用時執行個體化就好,這可以憑自己的喜好使用,并添加代碼。

github代碼:https://github.com/RichardoMrMu/gsoap-onvif

參考資料:

  1. ONVIF協定網絡錄影機(IPC)用戶端程式開發(1):專欄開篇
  2. 基于ONVIF協定的攝像頭開發總結
  3. ONVIF協定開發之網絡攝像頭雲台控制(C版)
  4. onvif專欄