Windows64下通過python調用海康SDK實現登入、預覽、抓圖、光學變倍、相機激活、區域聚焦、區域曝光功能

在windous系統下Python實現海康相機登入、預覽、抓圖、光學變倍、相機激活、區域聚焦、區域曝光功能;linux系統下載相應的海康SDK,並將lib文件更換爲相對應的庫文件,同時將HCNetSDKCom文件夾拷貝出來(與lib文件夾同一級別)

    python實現的功能如下:

import numpy as np
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()
    m_struFocusModeCfg.byRes
    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))
        ctypes.ARRAY()
    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))




# 透傳接口輸入參數結構體
class NET_DVR_XML_CONFIG_INPUT(ctypes.Structure):
    _fields_ = [
        ("dwSize", ctypes.c_uint32),
        ("lpRequestUrl", ctypes.c_void_p),
        ("dwRequestUrlLen", ctypes.c_uint32),
        ("lpInBuffer", ctypes.c_void_p),
        ("dwInBufferSize", ctypes.c_uint32),
        ("dwRecvTimeOut", ctypes.c_uint32),
        ("byForceEncrpt", ctypes.c_byte),
        ("byRes", ctypes.c_byte*31),]

# 透傳接口輸出參數結構體
class NET_DVR_XML_CONFIG_OUTPUT(ctypes.Structure):
    _fields_ = [
        ("dwSize", ctypes.c_uint32),
        ("lpOutBuffer", ctypes.c_void_p),
        ("dwOutBufferSize", ctypes.c_uint32),
        ("dwReturnedXMLSize", ctypes.c_uint32),
        ("lpStatusBuffer", ctypes.c_void_p),
        ("dwStatusSize", ctypes.c_uint32),
        ("byRes", ctypes.c_byte*31)]


#區域局部聚焦和局部曝光功能:矩形區域座標左上角和右下角(startX,startY,endX,endY)
# flag=1局部聚焦功能,flag!=1局部曝光功能
def RegionalCorrection(startX,startY,endX,endY,flag=1):
    # #定義傳輸內容
    if(flag==1):
        choise="regionalFocus"
    else:
        choise = "regionalExposure"
    inUrl = "PUT /ISAPI/Image/channels/1/" + choise
    inPutBuffer = "<" + choise + "><StartPoint><positionX>" + str(startX) + "</positionX><positionY>" + str(startY) + "</positionY></StartPoint><EndPoint><positionX>" + str(endX) + "</positionX><positionY>" + str(endY) + "</positionY></EndPoint></" + choise + ">"

    szUrl = (ctypes.c_char * 256)()
    struInput = NET_DVR_XML_CONFIG_INPUT()
    struOuput = NET_DVR_XML_CONFIG_OUTPUT()
    struInput.dwSize=ctypes.sizeof(struInput)
    struOuput.dwSize=ctypes.sizeof(struOuput)
    dwBufferLen = 1024 * 1024
    pBuffer = (ctypes.c_char * dwBufferLen)()
#_____________________________________________put________________________________________________________
    csCommand = bytes(inUrl, "ascii")
    ctypes.memmove(szUrl, csCommand, len(csCommand))
    struInput.lpRequestUrl = ctypes.cast(szUrl,ctypes.c_void_p)
    struInput.dwRequestUrlLen = len(szUrl)

    m_csInputParam= bytes(inPutBuffer, "ascii")
    dwInBufferLen = 1024 * 1024
    pInBuffer=(ctypes.c_byte * dwInBufferLen)()
    ctypes.memmove(pInBuffer, m_csInputParam, len(m_csInputParam))
    struInput.lpInBuffer = ctypes.cast(pInBuffer,ctypes.c_void_p)
    struInput.dwInBufferSize = len(m_csInputParam)

    struOuput.lpStatusBuffer = ctypes.cast(pBuffer,ctypes.c_void_p)
    struOuput.dwStatusSize = dwBufferLen

    if (callCpp("NET_DVR_STDXMLConfig", lUserID, ctypes.byref(struInput), ctypes.byref(struOuput))):
        error_info = callCpp("NET_DVR_GetLastError")
        print("上傳成功:" + str(error_info))
    else:
        error_info = callCpp("NET_DVR_GetLastError")
        print("上傳失敗:錯誤號爲"+ str(error_info))


#海康相機激活參數結構體
class NET_DVR_ACTIVATECFG(ctypes.Structure):
    _fields_ = [
        ("dwSize", ctypes.c_uint32),
        ("sPassword",ctypes.c_byte*16),
        ("byRes",  ctypes.c_byte*108)]


#海康相機激活
def OnActivateDevice():
    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

    szLan=(ctypes.c_char * 256)()
    pwd=bytes('guoji123', "ascii")#相機激活所需密碼
    DevAddr=bytes('192.168.1.64', "ascii") #相機初始默認IP地址
    struActivateCfg=NET_DVR_ACTIVATECFG()
    struActivateCfg.dwSize=ctypes.sizeof(struActivateCfg)
    ctypes.memmove(struActivateCfg.sPassword, pwd, len(pwd))
    if(callCpp("NET_DVR_ActivateDevice",DevAddr,8000,ctypes.byref(struActivateCfg))):
        error_info = callCpp("NET_DVR_GetLastError")
        print("激活成功:" + str(error_info))
    else:
        error_info = callCpp("NET_DVR_GetLastError")
        print("激活失敗:" + str(error_info))



# OnActivateDevice()#海康相機激活
# 相機登入print(ctypes.sizeof(NET_DVR_FOCUSMODE_CFG))
lUserID=NET_DVR_Login_V30()
相機預覽
m_lRealHandle=Preview()
# Get_JPEGpicture()
# Change_CamZoom(1)

#區域局部聚焦和局部曝光功能:矩形區域座標左上角和右下角(startX,startY,endX,endY)
# flag=1局部聚焦功能,flag!=1局部曝光功能
RegionalCorrection(20,20,50,50,flag=1)

最新Demo地址:https://download.csdn.net/download/weixin_40851278/10686000

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章