天天看點

捕獲海康威視IPCamera圖像,轉成OpenCV可以處理的圖像(一)

海康威視IPCamera圖像捕獲

捕獲海康威視IPCamera圖像,轉成OpenCV可以處理的IplImage圖像(一)

捕獲海康威視IPCamera圖像,轉成OpenCV可以處理的IplImage圖像(二)

所使用海康威視攝像頭型号:DS-2CD4026FWD-(A)(P)

海康威視IPCamera圖像捕獲方法有兩種:

(1)利用SDK裡面的NET_DVR_CaptureJPEGPicture_NEW進行視訊抓圖

(2)捕獲實時流,将實時流解碼成YV12,然後轉換成RGB

在這篇博文裡,我先介紹第一種方法。

第一種方法,關鍵是調用NET_DVR_CaptureJPEGPicture_NEW這個函數。關于這個函數的參數,可以在SDK中找到,我這裡截個圖以作說明。

捕獲海康威視IPCamera圖像,轉成OpenCV可以處理的圖像(一)

這個函數Ret是用于傳回該圖像大小的一個參數,但是該函數的這個參數大概是沒有用引用或者指針的方式來傳遞參數,導緻傳回值一直是我初始化的0,是以為後面的操作帶來了些許的不便——不得不使用一個較大的記憶體來儲存圖像一定能存儲的下。

NET_DVR_CaptureJPEGPicture_NEW這個函數是将單幀資料捕獲并儲存成JPEG,存放在指定的記憶體空間中。也就是記憶體裡的JPEG。為了獲得OpenCV能處理的IplImage圖像,必須在記憶體中進行解碼。

OpenCV在記憶體中解碼的函數隻有一個:imdecode,下圖是imdecode的說明

捕獲海康威視IPCamera圖像,轉成OpenCV可以處理的圖像(一)

該函數要求buf必須是數組或者是byte類型的vector. 是以需要對char * 類型的JPEG壓縮圖像進行存儲格式轉換。

#include <cstdio>
#include <iostream>
#include <ctime>
#include <Windows.h>
#include "HCNetSDK.h"
#include "highgui.h"
#include "cv.h"


using namespace cv;
using namespace std;


//typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();
//PROCGETCONSOLEWINDOW GetConsoleWindow;

int main(int argc, char * argv[]) 
{	
	//---------------------------------------
	// 初始化
	NET_DVR_Init();
	//設定連接配接時間與重連時間
	NET_DVR_SetConnectTime(2000, 1);
	NET_DVR_SetReconnect(10000, true);
	
	//---------------------------------------
	//擷取控制台視窗句柄
	//HMODULE hKernel32 = GetModuleHandle((LPCWSTR)"kernel32");
	//GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");

	
	//---------------------------------------
	// 注冊裝置
	LONG lUserID;
	NET_DVR_DEVICEINFO_V30 struDeviceInfo;
	lUserID = NET_DVR_Login_V30("10.102.7.88", 8000, "admin", "12345", &struDeviceInfo);
	if (lUserID < 0)
	{
		printf("Login error, %d\n", NET_DVR_GetLastError());
		NET_DVR_Cleanup();
		return -1;
	}	

	
	//---------------------------------------
	//cvNamedWindow("camera",CV_WINDOW_AUTOSIZE);
	IplImage* frame;
	//定義JPEG圖像品質
	LPNET_DVR_JPEGPARA JpegPara = new NET_DVR_JPEGPARA;
	JpegPara->wPicQuality = 0;
	JpegPara->wPicSize = 9;
	
	char * Jpeg = new char[200*1024];
	DWORD len = 200*1024;
	LPDWORD Ret = 0;
			
	if(!NET_DVR_SetCapturePictureMode(BMP_MODE))
	{
		cout<<"Set Capture Picture Mode error!"<<endl;
		cout<<"The error code is "<<NET_DVR_GetLastError()<<endl;
	}

	//bool capture = NET_DVR_CaptureJPEGPicture(lUserID,1,JpegPara,"1111");
	vector<char>data(200*1024);
	while(1)
	{
	bool capture = NET_DVR_CaptureJPEGPicture_NEW(lUserID,1,JpegPara,Jpeg,len,Ret);
	if(!capture)
	{
		printf("Error: NET_DVR_CaptureJPEGPicture_NEW = %d", NET_DVR_GetLastError());
		return -1;	
	}	

	for(int i=0;i<200*1024;i++)
		data[i] = Jpeg[i];

	Mat img = imdecode(Mat(data),1);
	imshow("camera",img);
	waitKey(1);
	
	}

	//FILE * fp = fopen("3.jpg","wb");
	//fwrite(Jpeg,1,123*1024,fp);
	//fclose(fp);
	
	return 0;
}
           

運作這個代碼當然OpenCV的配置不能少,HCNetSDK.h也必須包含進工程。

運作這個程式,可以捕獲到圖像,但是我計算了下時間,在調用 NET_DVR_CaptureJPEGPicture_NEW(lUserID,1,JpegPara,Jpeg,len,Ret);這一句話的時候,用時300ms,這個耗時太長,無法實時!但是如果對實時無要求,用這個也可以了,好了解!

*********************************************************************************************
       
轉載請注明出處:http://blog.csdn.net/wanghuiqi2008/article/details/31404571
       
*********************************************************************************************