20
20
)
21
21
22
22
23
+ def get_host_ip_by_target_ip (target_ip ):
24
+ import socket
25
+
26
+ return [
27
+ (s .connect ((target_ip , 80 )), s .getsockname ()[0 ], s .close ())
28
+ for s in [socket .socket (socket .AF_INET , socket .SOCK_DGRAM )]
29
+ ][0 ][1 ]
30
+
31
+
32
+ def get_setting_df ():
33
+ csv = boxx .pd .read_csv (__file__ .replace ("hik_camera.py" , "MvCameraNode-CH.csv" ))
34
+ setting_df = boxx .pd .DataFrame ()
35
+
36
+ def to_key (key ):
37
+ if "[" in key :
38
+ key = key [: key .index ("[" )]
39
+ return key .strip ()
40
+
41
+ def get_depend (key ):
42
+ key = key .strip ()
43
+ if "[" in key :
44
+ return key [key .index ("[" ) + 1 : - 1 ]
45
+ return ""
46
+
47
+ setting_df ["key" ] = csv [list (csv )[1 ]].map (to_key )
48
+ setting_df ["depend" ] = csv [list (csv )[1 ]].map (get_depend )
49
+ setting_df ["dtype" ] = csv [list (csv )[2 ]].map (lambda x : x .strip ().lower ())
50
+ return setting_df
51
+
52
+
23
53
class HikCamera (hik .MvCamera ):
24
- def __init__ (self ):
54
+ def __init__ (self , ip = None , host_ip = None ):
25
55
super ().__init__ ()
26
- self .get_setting_df ()
56
+ if ip is None :
57
+ return
58
+ ip = self .get_all_ips ()[0 ]
59
+ if host_ip is None :
60
+ host_ip = get_host_ip_by_target_ip (ip )
61
+ self ._ip = ip
62
+ self .host_ip = host_ip
63
+ # self.init_by_ip()
64
+ self .init_by_enum ()
65
+
66
+ def setting (self ):
67
+ self .set_exposure (250000 )
68
+ self .setitem ("ExposureAuto" , "Continuous" )
69
+ # self.adjust_auto_exposure()
70
+
71
+ self .pixel_format = "RGB8"
72
+ self .pixel_format = "BayerGB12Packed"
73
+ self .setitem ("PixelFormat" , self .pixel_format )
74
+
75
+ self .setitem ("GevSCPD" , 2000 ) # 包延时 ns
76
+
77
+ def init_by_spec_ip (self ,):
78
+ """
79
+ SDK 有 Bug, 调用完"枚举设备" 接口后, 再调用"无枚举连接相机" 会无法打开相机.
80
+ 暂时不能用
81
+ """
82
+ stDevInfo = hik .MV_CC_DEVICE_INFO ()
83
+ stGigEDev = hik .MV_GIGE_DEVICE_INFO ()
84
+
85
+ stGigEDev .nCurrentIp = ip_to_int (self .ip )
86
+ stGigEDev .nNetExport = ip_to_int (self .host_ip )
87
+ stDevInfo .nTLayerType = hik .MV_GIGE_DEVICE
88
+ stDevInfo .SpecialInfo .stGigEInfo = stGigEDev
89
+ assert not self .MV_CC_CreateHandle (stDevInfo )
90
+
91
+ def init_by_enum (self ):
92
+ stDevInfo = self .get_dev_info (self .ip )
93
+ assert not self .MV_CC_CreateHandle (stDevInfo )
94
+
95
+ @classmethod
96
+ def get_dev_info (cls , ip = None ):
97
+ if not hasattr (cls , "ip_to_dev_info" ):
98
+ ip_to_dev_info = {}
99
+ deviceList = hik .MV_CC_DEVICE_INFO_LIST ()
100
+ tlayerType = hik .MV_GIGE_DEVICE # | MV_USB_DEVICE
101
+ assert not hik .MvCamera .MV_CC_EnumDevices (tlayerType , deviceList )
102
+ for i in range (0 , deviceList .nDeviceNum ):
103
+ mvcc_dev_info = cast (
104
+ deviceList .pDeviceInfo [i ], POINTER (hik .MV_CC_DEVICE_INFO )
105
+ ).contents
106
+ _ip = int_to_ip (mvcc_dev_info .SpecialInfo .stGigEInfo .nCurrentIp )
107
+ if mvcc_dev_info .nTLayerType == hik .MV_GIGE_DEVICE :
108
+ ip_to_dev_info [_ip ] = mvcc_dev_info
109
+ cls .ip_to_dev_info = {
110
+ ip : ip_to_dev_info [ip ] for ip in sorted (ip_to_dev_info )
111
+ }
112
+ if ip is None :
113
+ return cls .ip_to_dev_info
114
+ return cls .ip_to_dev_info [ip ]
27
115
28
116
high_speed_lock = Lock ()
117
+ setting_df = get_setting_df ()
29
118
30
119
def get_frame (self ):
31
120
stFrameInfo = self .stFrameInfo
@@ -65,25 +154,6 @@ def get_frame(self):
65
154
)
66
155
return img
67
156
68
- def get_setting_df (self ):
69
- csv = boxx .pd .read_csv (__file__ .replace ("hik_camera.py" , "MvCameraNode-CH.csv" ))
70
- self .setting_df = boxx .pd .DataFrame ()
71
-
72
- def to_key (key ):
73
- if "[" in key :
74
- key = key [: key .index ("[" )]
75
- return key .strip ()
76
-
77
- def get_depend (key ):
78
- key = key .strip ()
79
- if "[" in key :
80
- return key [key .index ("[" ) + 1 : - 1 ]
81
- return ""
82
-
83
- self .setting_df ["key" ] = csv [list (csv )[1 ]].map (to_key )
84
- self .setting_df ["depend" ] = csv [list (csv )[1 ]].map (get_depend )
85
- self .setting_df ["dtype" ] = csv [list (csv )[2 ]].map (lambda x : x .strip ().lower ())
86
-
87
157
def getitem (self , key ):
88
158
df = self .setting_df
89
159
dtype = df [df .key == key ]["dtype" ].iloc [0 ]
@@ -150,25 +220,6 @@ def adjust_auto_exposure(self, t=2):
150
220
finally :
151
221
self .MV_CC_StopGrabbing ()
152
222
153
- pixel_format_values = {
154
- "RGB8" : 0x02180014 ,
155
- "BayerGB8" : 0x0108000A ,
156
- "BayerGB12" : 0x01100012 ,
157
- "BayerGB12Packed" : 0x010C002C ,
158
- }
159
-
160
- def setting (self ):
161
- # self.adjust_auto_exposure()
162
- self .setitem ("ExposureAuto" , "Off" )
163
- self .setitem ("ExposureTime" , 250000 )
164
- self .setitem ("ExposureAuto" , "Continuous" )
165
-
166
- self .pixel_format = "RGB8"
167
- self .pixel_format = "BayerGB12Packed"
168
- self .setitem ("PixelFormat" , self .pixel_format_values [self .pixel_format ])
169
-
170
- self .setitem ("GevSCPD" , 2000 ) # 包延时 ns
171
-
172
223
def __enter__ (self ):
173
224
assert not self .MV_CC_OpenDevice (hik .MV_ACCESS_Exclusive , 0 )
174
225
@@ -207,45 +258,25 @@ def get_shape(self):
207
258
def __exit__ (self , * l ):
208
259
self .MV_CC_CloseDevice ()
209
260
210
- @staticmethod
211
- def get_all_ips ():
212
- deviceList = hik .MV_CC_DEVICE_INFO_LIST ()
213
- tlayerType = hik .MV_GIGE_DEVICE # | MV_USB_DEVICE
214
-
215
- # ch:枚举设备 | en:Enum device
216
- assert not hik .MvCamera .MV_CC_EnumDevices (tlayerType , deviceList )
217
- ips = {}
218
- for i in range (0 , deviceList .nDeviceNum ):
219
- mvcc_dev_info = cast (
220
- deviceList .pDeviceInfo [i ], POINTER (hik .MV_CC_DEVICE_INFO )
221
- ).contents
222
- if mvcc_dev_info .nTLayerType == hik .MV_GIGE_DEVICE :
223
- ips [int_to_ip (mvcc_dev_info .SpecialInfo .stGigEInfo .nCurrentIp )] = i
224
- return ips
261
+ @classmethod
262
+ def get_all_ips (cls ):
263
+ ip_to_dev_info = cls .get_dev_info ()
264
+ return sorted (ip_to_dev_info )
225
265
226
266
@classmethod
227
- def get_all_cams (cls ):
228
- deviceList = hik .MV_CC_DEVICE_INFO_LIST ()
229
- tlayerType = hik .MV_GIGE_DEVICE # | MV_USB_DEVICE
230
-
231
- # ch:枚举设备 | en:Enum device
232
- assert not hik .MvCamera .MV_CC_EnumDevices (tlayerType , deviceList )
233
- cams = MultiHikCamera ()
234
- for i in range (0 , deviceList .nDeviceNum ):
235
- mvcc_dev_info = cast (
236
- deviceList .pDeviceInfo [i ], POINTER (hik .MV_CC_DEVICE_INFO )
237
- ).contents
238
- if mvcc_dev_info .nTLayerType == hik .MV_GIGE_DEVICE :
239
- cam = cls ()
240
- assert not cam .MV_CC_CreateHandle (mvcc_dev_info )
241
- ip = cam .ip
242
- cams [ip ] = cam
243
- cams = MultiHikCamera ({ip : cams [ip ] for ip in sorted (cams )})
267
+ def get_cams (cls , ips = None ):
268
+ if ips is None :
269
+ ips = cls .get_all_ips ()
270
+ else :
271
+ ips = sorted (ips )
272
+ cams = MultiHikCamera ({ip : cls (ip ) for ip in ips })
244
273
return cams
245
274
275
+ get_all_cams = get_cams
276
+
246
277
def MV_CC_CreateHandle (self , mvcc_dev_info ):
247
278
self .mvcc_dev_info = mvcc_dev_info
248
- self .ip = int_to_ip (mvcc_dev_info .SpecialInfo .stGigEInfo .nCurrentIp )
279
+ self ._ip = int_to_ip (mvcc_dev_info .SpecialInfo .stGigEInfo .nCurrentIp )
249
280
assert not super ().MV_CC_CreateHandle (mvcc_dev_info )
250
281
251
282
def __del__ (self ):
@@ -269,9 +300,18 @@ def raw_to_uint8_rgb(self, raw, poww=1, demosaicing_method="Malvar2004"):
269
300
def is_raw (self ):
270
301
return "Bayer" in self .__dict__ .get ("pixel_format" , "RGB8" )
271
302
303
+ @property
304
+ def ip (self ):
305
+ if not hasattr (self , "_ip" ):
306
+ self ._ip = self .getitem ("GevCurrentIPAddress" )
307
+ return self ._ip
308
+
272
309
273
310
class MultiHikCamera (dict ):
274
311
def __getattr__ (self , attr ):
312
+ if not callable (getattr (next (iter (self .values ())), attr )):
313
+ return {k : getattr (cam , attr ) for k , v in self .items ()}
314
+
275
315
def func (* args , ** kwargs ):
276
316
threads = []
277
317
res = {}
@@ -304,25 +344,23 @@ def __exit__(self, *l):
304
344
ips = HikCamera .get_all_ips ()
305
345
print (ips )
306
346
ip = list (ips )[0 ]
307
- cams = HikCamera .get_all_cams ()
308
- cam = cams .get ("10.9.5.102" , cams [ip ])
309
- with cams :
310
- with boxx .timeit ("get_frame" ):
311
- imgs = cams .get_frame ()
312
- print ("imgs = cams.get_frame()" )
313
- boxx .tree (imgs )
314
- # rgbs = [cam.raw_to_uint8_rgb(raw, poww=.3, demosaicing_method="simple") for raw in imgs.values()]
315
- # normas = [norma(img) for img in imgs.values()]
316
- # shows-[normas, rgbs]
317
347
348
+ cam = HikCamera (ip )
349
+ with cam :
318
350
for i in range (2 ):
319
351
with boxx .timeit ("cam.get_frame" ):
320
352
img = cam .get_frame ()
321
353
print ("cam.get_exposure" , cam ["ExposureTime" ])
322
- boxx .show (img )
323
354
if cam .is_raw :
324
355
rgbs = [
325
356
cam .raw_to_uint8_rgb (img , poww = 1 ),
326
357
cam .raw_to_uint8_rgb (img , poww = 0.3 ),
327
358
]
328
359
boxx .show (rgbs )
360
+
361
+ cams = HikCamera .get_all_cams ()
362
+ with cams :
363
+ with boxx .timeit ("cams.get_frame" ):
364
+ imgs = cams .get_frame ()
365
+ print ("imgs = cams.get_frame()" )
366
+ boxx .tree (imgs )
0 commit comments