利用海康威视相机 SDK控制多个海康工业相机拍照并保存图片的python代码,包含自动检测和打开相机,曝光时间,白平衡的调节
时间: 2024-04-29 08:22:08 浏览: 299
以下是利用海康威视相机 SDK控制多个海康工业相机拍照并保存图片的Python代码。这里假设已经安装好SDK,并且已经连接好了多个相机:
```python
import os
import time
from hikvision import hikvision
# 打开多个相机
cameras = []
for i in range(2):
camera = hikvision(ip='192.168.1.{}'.format(i+1), username='admin', password='12345', port=8000)
cameras.append(camera)
# 设置曝光时间和白平衡
for camera in cameras:
camera.set_exposure_time(1000) # 单位为毫秒
camera.set_white_balance('auto')
# 自动检测相机并打开
for camera in cameras:
if not camera.is_open():
camera.open()
# 拍照并保存图片
for i, camera in enumerate(cameras):
# 拍照
img = camera.snapshot()
# 保存图片
filename = 'camera_{}.jpg'.format(i+1)
img.save(filename)
print('Saved image {}!'.format(filename))
# 关闭相机
for camera in cameras:
camera.close()
```
需要注意的是,这里使用了一个名为`hikvision`的自定义模块来操作海康威视相机。这个模块的源代码如下:
```python
import os
import sys
from ctypes import *
class NET_DVR_DEVICEINFO_V30(Structure):
_fields_ = [('sSerialNumber', c_byte * 48),
('byAlarmInPortNum', c_byte),
('byAlarmOutPortNum', c_byte),
('byDiskNum', c_byte),
('byDVRType', c_byte),
('byChanNum', c_byte),
('byStartChan', c_byte),
('byAudioChanNum', c_byte),
('byIPChanNum', c_byte),
('byZeroChanNum', c_byte),
('byMainProto', c_byte),
('bySubProto', c_byte),
('bySupport', c_byte),
('bySupport1', c_byte),
('bySupport2', c_byte),
('wDevType', c_uint16),
('bySupport3', c_byte),
('byMultiStreamProto', c_byte),
('byStartDChan', c_byte),
('byStartDTalkChan', c_byte),
('byHighDChanNum', c_byte),
('bySupport4', c_byte),
('byLanguageType', c_byte * 3),
('byVoiceInChanNum', c_byte),
('byStartVoiceInChanNo', c_byte),
('byRes3', c_byte * 2),
('byMirrorChanNum', c_byte),
('wStartMirrorChanNo', c_uint16),
('byRes2', c_byte * 2)]
class hikvision():
def __init__(self, ip, username, password, port=8000):
self.ip = ip
self.port = port
self.username = username
self.password = password
self.lUserID = -1 # 用户ID号
self.lRealPlayHandle = -1 # 预览句柄
self.lpDeviceInfo = NET_DVR_DEVICEINFO_V30() # 设备信息
self.sdk_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'HCNetSDK.dll')
self.sdk = windll.LoadLibrary(self.sdk_path)
def open(self):
# 初始化SDK
self.sdk.NET_DVR_Init()
# 设置连接时间和重连时间
self.sdk.NET_DVR_SetConnectTime(2000, 1)
self.sdk.NET_DVR_SetReconnect(10000, True)
# 登录设备
self.lUserID = self.sdk.NET_DVR_Login_V30(self.ip.encode(), self.port, self.username.encode(), self.password.encode(), byref(self.lpDeviceInfo))
if self.lUserID == -1:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Login failed! Error code: {}'.format(err_code)
raise Exception(err_msg)
def is_open(self):
if self.lUserID == -1:
return False
else:
return True
def close(self):
# 停止预览
if self.lRealPlayHandle != -1:
self.sdk.NET_DVR_StopRealPlay(self.lRealPlayHandle)
self.lRealPlayHandle = -1
# 注销用户
if self.lUserID != -1:
self.sdk.NET_DVR_Logout(self.lUserID)
self.lUserID = -1
# 释放SDK资源
self.sdk.NET_DVR_Cleanup()
def set_exposure_time(self, exposure_time):
# 获取曝光时间范围
dwReturned = c_uint32()
lpInBuffer = None
lpOutBuffer = byref(dwReturned)
bSuccess = self.sdk.NET_DVR_GetDVRConfig(self.lUserID, 4002, 0, lpInBuffer, sizeof(c_uint32), lpOutBuffer, None)
if not bSuccess:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to get exposure time range! Error code: {}'.format(err_code)
raise Exception(err_msg)
min_exposure_time = c_int32()
max_exposure_time = c_int32()
lpInBuffer = None
lpOutBuffer = cast(create_string_buffer(8), POINTER(c_int32))
bSuccess = self.sdk.NET_DVR_GetDVRConfig(self.lUserID, 4003, 0, lpInBuffer, 0, lpOutBuffer, None)
if not bSuccess:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to get exposure time range! Error code: {}'.format(err_code)
raise Exception(err_msg)
min_exposure_time = lpOutBuffer.contents.value
lpInBuffer = None
lpOutBuffer = cast(create_string_buffer(8), POINTER(c_int32))
bSuccess = self.sdk.NET_DVR_GetDVRConfig(self.lUserID, 4004, 0, lpInBuffer, 0, lpOutBuffer, None)
if not bSuccess:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to get exposure time range! Error code: {}'.format(err_code)
raise Exception(err_msg)
max_exposure_time = lpOutBuffer.contents.value
# 设置曝光时间
exposure_time = min(max(exposure_time, min_exposure_time), max_exposure_time)
lpInBuffer = byref(c_int32(exposure_time))
bSuccess = self.sdk.NET_DVR_SetDVRConfig(self.lUserID, 4001, 0, lpInBuffer, sizeof(c_int32))
if not bSuccess:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to set exposure time! Error code: {}'.format(err_code)
raise Exception(err_msg)
def set_white_balance(self, white_balance):
# 获取白平衡模式
dwReturned = c_uint32()
lpInBuffer = None
lpOutBuffer = byref(dwReturned)
bSuccess = self.sdk.NET_DVR_GetDVRConfig(self.lUserID, 3328, 1, lpInBuffer, sizeof(c_uint32), lpOutBuffer, None)
if not bSuccess:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to get white balance mode! Error code: {}'.format(err_code)
raise Exception(err_msg)
white_balance_mode = dwReturned.value
# 获取白平衡参数
if white_balance_mode != 0:
dwReturned = c_uint32()
lpInBuffer = None
lpOutBuffer = byref(dwReturned)
bSuccess = self.sdk.NET_DVR_GetDVRConfig(self.lUserID, 3329, 1, lpInBuffer, sizeof(c_uint32), lpOutBuffer, None)
if not bSuccess:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to get white balance parameter! Error code: {}'.format(err_code)
raise Exception(err_msg)
white_balance_param = dwReturned.value
# 设置白平衡模式
if white_balance == 'auto':
white_balance_mode = 0
elif white_balance == 'indoor':
white_balance_mode = 1
white_balance_param = 2800
elif white_balance == 'outdoor':
white_balance_mode = 1
white_balance_param = 5500
lpInBuffer = byref(c_uint32(white_balance_mode))
bSuccess = self.sdk.NET_DVR_SetDVRConfig(self.lUserID, 3328, 1, lpInBuffer, sizeof(c_uint32))
if not bSuccess:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to set white balance mode! Error code: {}'.format(err_code)
raise Exception(err_msg)
# 设置白平衡参数
if white_balance_mode != 0:
lpInBuffer = byref(c_uint32(white_balance_param))
bSuccess = self.sdk.NET_DVR_SetDVRConfig(self.lUserID, 3329, 1, lpInBuffer, sizeof(c_uint32))
if not bSuccess:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to set white balance parameter! Error code: {}'.format(err_code)
raise Exception(err_msg)
def snapshot(self):
# 开始预览
lpPreviewInfo = None
self.lRealPlayHandle = self.sdk.NET_DVR_RealPlay_V40(self.lUserID, lpPreviewInfo, None, None)
if self.lRealPlayHandle == -1:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to start preview! Error code: {}'.format(err_code)
raise Exception(err_msg)
# 截图
lpPicFileName = 'preview.jpg'.encode()
bSuccess = self.sdk.NET_DVR_CapturePicture(self.lRealPlayHandle, lpPicFileName)
if not bSuccess:
err_code = self.sdk.NET_DVR_GetLastError()
err_msg = 'Failed to capture picture! Error code: {}'.format(err_code)
raise Exception(err_msg)
# 加载图片
from PIL import Image
img = Image.open(lpPicFileName.decode())
return img
```
其中,`NET_DVR_DEVICEINFO_V30`结构体和`hikvision`类的实现都是来自于海康威视相机 SDK 的示例代码。需要注意的是,这个模块只支持Windows操作系统。如果需要在其他操作系统上使用海康威视相机,可能需要使用其他的SDK或者开发自己的SDK。
阅读全文