windous系統下Python實現海康相機登入,預覽,抓圖,光學變倍;linux系統下載相應的海康SDK,並將lib文件更換爲相對應的庫文件,同時將HCNetSDKCom文件夾拷貝出來(與lib文件夾同一級別)
python實現的功能如下:
import os
import ctypes
#獲取所有的庫文件到一個列表
path = "lib/win64/"
def file_name(file_dir):
pathss=[]
for root, dirs, files in os.walk(file_dir):
for file in files:
pathss.append(path+file)
return pathss
dll_list=file_name(path)
lUserID = 0
lChannel=1
def callCpp(func_name,*args):
for HK_dll in dll_list:
try:
lib = ctypes.cdll.LoadLibrary(HK_dll)
try:
value = eval("lib.%s"%func_name)(*args)
# print("調用的庫:"+HK_dll)
# print("執行成功,返回值:"+str(value))
return value
except:
continue
except:
# print("庫文件載入失敗:"+HK_dll)
continue
# print("沒有找到接口!")
return False
# region 登入
#定義登入結構體
class LPNET_DVR_DEVICEINFO_V30(ctypes.Structure):
_fields_ = [
("sSerialNumber", ctypes.c_byte * 48),
("byAlarmInPortNum", ctypes.c_byte),
("byAlarmOutPortNum", ctypes.c_byte),
("byDiskNum", ctypes.c_byte),
("byDVRType", ctypes.c_byte),
("byChanNum", ctypes.c_byte),
("byStartChan", ctypes.c_byte),
("byAudioChanNum", ctypes.c_byte),
("byIPChanNum", ctypes.c_byte),
("byZeroChanNum", ctypes.c_byte),
("byMainProto", ctypes.c_byte),
("bySubProto", ctypes.c_byte),
("bySupport", ctypes.c_byte),
("bySupport1", ctypes.c_byte),
("bySupport2", ctypes.c_byte),
("wDevType", ctypes.c_uint16),
("bySupport3", ctypes.c_byte),
("byMultiStreamProto", ctypes.c_byte),
("byStartDChan", ctypes.c_byte),
("byStartDTalkChan", ctypes.c_byte),
("byHighDChanNum", ctypes.c_byte),
("bySupport4", ctypes.c_byte),
("byLanguageType", ctypes.c_byte),
("byVoiceInChanNum", ctypes.c_byte),
("byStartVoiceInChanNo", ctypes.c_byte),
("byRes3", ctypes.c_byte * 2),
("byMirrorChanNum", ctypes.c_byte),
("wStartMirrorChanNo", ctypes.c_uint16),
("byRes2", ctypes.c_byte * 2)]
#用戶註冊設備 並登入,需要修改IP,賬號、密碼
def NET_DVR_Login_V30(sDVRIP = "192.168.1.65",wDVRPort = 8000,sUserName = "admin",sPassword = "guoji123"):
init_res = callCpp("NET_DVR_Init")#SDK初始化
if init_res:
print("SDK初始化成功")
error_info = callCpp("NET_DVR_GetLastError")
else:
error_info = callCpp("NET_DVR_GetLastError")
print("SDK初始化錯誤:" + str(error_info))
return False
set_overtime = callCpp("NET_DVR_SetConnectTime",5000,4)#設置超時
if set_overtime:
print("設置超時時間成功")
else:
error_info = callCpp("NET_DVR_GetLastError")
print("設置超時錯誤信息:" + str(error_info))
return False
#用戶註冊設備
#c++傳遞進去的是byte型數據,需要轉成byte型傳進去,否則會亂碼
sDVRIP = bytes(sDVRIP,"ascii")
sUserName = bytes(sUserName,"ascii")
sPassword = bytes(sPassword,"ascii")
print( "數據轉化成功")
DeviceInfo = LPNET_DVR_DEVICEINFO_V30()
print(DeviceInfo)
lUserID = callCpp("NET_DVR_Login_V30",sDVRIP,wDVRPort,sUserName,sPassword,ctypes.byref(DeviceInfo))
print("登錄成功,用戶ID:"+str(lUserID))
if lUserID == -1:
error_info = callCpp("NET_DVR_GetLastError")
print("登錄錯誤信息:" + str(error_info))
return error_info
else:
return lUserID
# endregion
# region 預覽
#定義預覽結構體
class NET_DVR_PREVIEWINFO(ctypes.Structure):
_fields_ = [
("lChannel", ctypes.c_long),
("lLinkMode", ctypes.c_long),
("hPlayWnd", ctypes.c_void_p),
("sMultiCastIP", ctypes.c_char_p),
("byProtoType", ctypes.c_byte),
("byRes", ctypes.c_byte * 3)]
# 預覽實現
def Preview():
lpPreviewInfo=NET_DVR_PREVIEWINFO()
# hPlayWnd需要輸入創建圖形窗口的handle,沒有輸入無法實現BMP抓圖
lpPreviewInfo.hPlayWnd=None
lpPreviewInfo.lChannel=1
lpPreviewInfo.dwLinkMode=0
lpPreviewInfo.sMultiCastIP=None
m_lRealHandle=callCpp("NET_DVR_RealPlay_V30",lUserID,ctypes.byref(lpPreviewInfo),None,None,True)
if(m_lRealHandle<0):
error_info = callCpp("NET_DVR_GetLastError")
print("預覽失敗:" + str(error_info))
else:
print("預覽成功")
return m_lRealHandle
# endregion
# # region 抓圖
# # BMP抓圖預覽的時候hPlayWnd顯示窗口不能爲none
# def Get_BMPPicture():
# sBmpPicFileName = bytes("pytest.bmp", "ascii")
# if(callCpp("NET_DVR_CapturePicture",m_lRealHandle,sBmpPicFileName)==False):
# error_info = callCpp("NET_DVR_GetLastError")
# print("抓圖失敗:" + str(error_info))
# else:
# print("抓圖成功")
#
# 抓圖數據結構體
class NET_DVR_JPEGPARA(ctypes.Structure):
_fields_ = [
("wPicSize", ctypes.c_ushort),
("wPicQuality", ctypes.c_ushort)]
# jpeg抓圖hPlayWnd顯示窗口能爲none,存在缺點採集圖片速度慢
def Get_JPEGpicture():
sJpegPicFileName = bytes("pytest.jpg", "ascii")
lpJpegPara=NET_DVR_JPEGPARA()
lpJpegPara.wPicSize=0
lpJpegPara.wPicQuality=0
if (callCpp("NET_DVR_CaptureJPEGPicture", lUserID, lChannel, ctypes.byref(lpJpegPara), sJpegPicFileName)== False):
error_info = callCpp("NET_DVR_GetLastError")
print("抓圖失敗:" + str(error_info))
else:
print("抓圖成功")
# endregion
#定義光學變倍結構體
# 光學變倍結構體
class NET_DVR_FOCUSMODE_CFG(ctypes.Structure):
_fields_ = [
("dwSize", ctypes.c_uint32),
("byFocusMode", ctypes.c_byte),
("byAutoFocusMode", ctypes.c_byte),
("wMinFocusDistance", ctypes.c_uint16),
("byZoomSpeedLevel", ctypes.c_byte),
("byFocusSpeedLevel", ctypes.c_byte),
("byOpticalZoom", ctypes.c_byte),
("byDigtitalZoom", ctypes.c_byte),
("fOpticalZoomLevel", ctypes.c_float),
("dwFocusPos", ctypes.c_uint32),
("byFocusDefinitionDisplay", ctypes.c_byte),
("byFocusSensitivity", ctypes.c_byte),
("byRes1", ctypes.c_byte*2),
("dwRelativeFocusPos", ctypes.c_uint32),
("byRes", ctypes.c_byte * 48),]
# 獲取光學變倍值
def get_CamZoom():
m_struFocusModeCfg = NET_DVR_FOCUSMODE_CFG()
dwReturned = ctypes.c_uint16(0)
print(callCpp("NET_DVR_GetDVRConfig"))
if (callCpp("NET_DVR_GetDVRConfig", lUserID, 3305, lChannel, ctypes.byref(m_struFocusModeCfg), 76,
ctypes.byref(dwReturned)) == False):
error_info = callCpp("NET_DVR_GetLastError")
print("光學變倍獲取失敗:" + str(error_info))
else:
print("光學變倍獲取成功")
return m_struFocusModeCfg.fOpticalZoomLevel
# 修改光學變倍值
def Change_CamZoom(zoomScale):
m_struFocusModeCfg=NET_DVR_FOCUSMODE_CFG()
dwReturned=ctypes.c_uint16(0)
print(callCpp("NET_DVR_GetDVRConfig"))
if (callCpp("NET_DVR_GetDVRConfig", lUserID, 3305, lChannel,ctypes.byref(m_struFocusModeCfg),76, ctypes.byref(dwReturned))==False):
error_info = callCpp("NET_DVR_GetLastError")
print("光學變倍獲取失敗:" + str(error_info))
else:
print("光學變倍獲取成功")
print("當前光學變倍值:"+str(m_struFocusModeCfg.fOpticalZoomLevel))
m_struFocusModeCfg.fOpticalZoomLevel=zoomScale
if (callCpp("NET_DVR_SetDVRConfig", lUserID, 3306, lChannel, ctypes.byref(m_struFocusModeCfg),76)==False):
error_info = callCpp("NET_DVR_GetLastError")
print("光學變倍修改失敗:" + str(error_info))
else:
print("光學變倍修改成功;修改後的數據爲:"+str(m_struFocusModeCfg.fOpticalZoomLevel))
#相機登入
lUserID=NET_DVR_Login_V30()
# 相機預覽
m_lRealHandle=Preview()
Get_JPEGpicture()
Change_CamZoom(20)
Demo地址:https://download.csdn.net/download/weixin_40851278/10530931
參考文檔:https://blog.csdn.net/caobin0825/article/details/79667442