Kaynağa Gözat

commit depthsensing

master
Jeong Geol Kim 4 yıl önce
ebeveyn
işleme
2375d50e43
1 değiştirilmiş dosya ile 529 ekleme ve 0 silme
  1. 529
    0
      depthsensing.py

+ 529
- 0
depthsensing.py Dosyayı Görüntüle

1
+#!python3
2
+"""
3
+Python 3 wrapper for identifying objects in images
4
+
5
+Requires DLL compilation
6
+
7
+Original *nix 2.7: https://github.com/pjreddie/darknet/blob/0f110834f4e18b30d5f101bf8f1724c34b7b83db/python/darknet.py
8
+Windows Python 2.7 version: https://github.com/AlexeyAB/darknet/blob/fc496d52bf22a0bb257300d3c79be9cd80e722cb/build/darknet/x64/darknet.py
9
+
10
+@author: Philip Kahn, Aymeric Dujardin
11
+@date: 20180911
12
+"""
13
+# pylint: disable=R, W0401, W0614, W0703
14
+import cv2
15
+import pyzed.sl as sl
16
+from ctypes import *
17
+import math
18
+import random
19
+import os
20
+import numpy as np
21
+import statistics
22
+import sys
23
+import getopt
24
+from random import randint
25
+import time
26
+import pandas as pd
27
+from pandas import  DataFrame as df
28
+import  subprocess
29
+
30
+
31
+#NOTE at 2020-12-22: if svo's resulotion changed, then you have to edit WIDTH, HEIGHT and DEPTH_MAX
32
+WIDTH = 1920
33
+HEIGHT = 1080
34
+DEPTH_MAX = 8
35
+
36
+
37
+def sample(probs):
38
+    s = sum(probs)
39
+    probs = [a/s for a in probs]
40
+    r = random.uniform(0, 1)
41
+    for i in range(len(probs)):
42
+        r = r - probs[i]
43
+        if r <= 0:
44
+            return i
45
+    return len(probs)-1
46
+
47
+
48
+def c_array(ctype, values):
49
+    arr = (ctype*len(values))()
50
+    arr[:] = values
51
+    return arr
52
+
53
+
54
+class BOX(Structure):
55
+    _fields_ = [("x", c_float),
56
+                ("y", c_float),
57
+                ("w", c_float),
58
+                ("h", c_float)]
59
+
60
+
61
+class DETECTION(Structure):
62
+    _fields_ = [("bbox", BOX),
63
+                ("classes", c_int),
64
+                ("prob", POINTER(c_float)),
65
+                ("mask", POINTER(c_float)),
66
+                ("objectness", c_float),
67
+                ("sort_class", c_int)]
68
+
69
+
70
+class IMAGE(Structure):
71
+    _fields_ = [("w", c_int),
72
+                ("h", c_int),
73
+                ("c", c_int),
74
+                ("data", POINTER(c_float))]
75
+
76
+
77
+class METADATA(Structure):
78
+    _fields_ = [("classes", c_int),
79
+                ("names", POINTER(c_char_p))]
80
+
81
+
82
+#lib = CDLL("/home/pjreddie/documents/darknet/libdarknet.so", RTLD_GLOBAL)
83
+#lib = CDLL("darknet.so", RTLD_GLOBAL)
84
+hasGPU = True
85
+if os.name == "nt":
86
+    cwd = os.path.dirname(__file__)
87
+    os.environ['PATH'] = cwd + ';' + os.environ['PATH']
88
+    winGPUdll = os.path.join(cwd, "yolo_cpp_dll.dll")
89
+    #print(winGPUdll)
90
+    winNoGPUdll = os.path.join(cwd, "yolo_cpp_dll_nogpu.dll")
91
+    envKeys = list()
92
+    for k, v in os.environ.items():
93
+        envKeys.append(k)
94
+    try:
95
+        try:
96
+            tmp = os.environ["FORCE_CPU"].lower()
97
+            if tmp in ["1", "true", "yes", "on"]:
98
+                raise ValueError("ForceCPU")
99
+            else:
100
+                pass#print("Flag value '"+tmp+"' not forcing CPU mode")
101
+        except KeyError:
102
+            # We never set the flag
103
+            if 'CUDA_VISIBLE_DEVICES' in envKeys:
104
+                if int(os.environ['CUDA_VISIBLE_DEVICES']) < 0:
105
+                    raise ValueError("ForceCPU")
106
+            try:
107
+                global DARKNET_FORCE_CPU
108
+                if DARKNET_FORCE_CPU:
109
+                    raise ValueError("ForceCPU")
110
+            except NameError:
111
+                pass
112
+            # #print(os.environ.keys())
113
+            # #print("FORCE_CPU flag undefined, proceeding with GPU")
114
+        if not os.path.exists(winGPUdll):
115
+            raise ValueError("NoDLL")
116
+        lib = CDLL(winGPUdll, RTLD_GLOBAL)
117
+    except (KeyError, ValueError):
118
+        hasGPU = False
119
+        if os.path.exists(winNoGPUdll):
120
+            lib = CDLL(winNoGPUdll, RTLD_GLOBAL)
121
+            #print("Notice: CPU-only mode")
122
+        else:
123
+            # Try the other way, in case no_gpu was
124
+            # compile but not renamed
125
+            lib = CDLL(winGPUdll, RTLD_GLOBAL)
126
+            #print("Environment variables indicated a CPU run, but we didn't find `" +
127
+            #      winNoGPUdll+"`. Trying a GPU run anyway.")
128
+else:
129
+    lib = CDLL("/root/darknet/libdarknet.so", RTLD_GLOBAL)
130
+lib.network_width.argtypes = [c_void_p]
131
+lib.network_width.restype = c_int
132
+lib.network_height.argtypes = [c_void_p]
133
+lib.network_height.restype = c_int
134
+
135
+predict = lib.network_predict
136
+predict.argtypes = [c_void_p, POINTER(c_float)]
137
+predict.restype = POINTER(c_float)
138
+
139
+if hasGPU:
140
+    set_gpu = lib.cuda_set_device
141
+    set_gpu.argtypes = [c_int]
142
+
143
+make_image = lib.make_image
144
+make_image.argtypes = [c_int, c_int, c_int]
145
+make_image.restype = IMAGE
146
+
147
+get_network_boxes = lib.get_network_boxes
148
+get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(
149
+    c_int), c_int, POINTER(c_int), c_int]
150
+get_network_boxes.restype = POINTER(DETECTION)
151
+
152
+make_network_boxes = lib.make_network_boxes
153
+make_network_boxes.argtypes = [c_void_p]
154
+make_network_boxes.restype = POINTER(DETECTION)
155
+
156
+free_detections = lib.free_detections
157
+free_detections.argtypes = [POINTER(DETECTION), c_int]
158
+
159
+free_ptrs = lib.free_ptrs
160
+free_ptrs.argtypes = [POINTER(c_void_p), c_int]
161
+
162
+network_predict = lib.network_predict
163
+network_predict.argtypes = [c_void_p, POINTER(c_float)]
164
+
165
+reset_rnn = lib.reset_rnn
166
+reset_rnn.argtypes = [c_void_p]
167
+
168
+load_net = lib.load_network
169
+load_net.argtypes = [c_char_p, c_char_p, c_int]
170
+load_net.restype = c_void_p
171
+
172
+load_net_custom = lib.load_network_custom
173
+load_net_custom.argtypes = [c_char_p, c_char_p, c_int, c_int]
174
+load_net_custom.restype = c_void_p
175
+
176
+do_nms_obj = lib.do_nms_obj
177
+do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]
178
+
179
+do_nms_sort = lib.do_nms_sort
180
+do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]
181
+
182
+free_image = lib.free_image
183
+free_image.argtypes = [IMAGE]
184
+
185
+letterbox_image = lib.letterbox_image
186
+letterbox_image.argtypes = [IMAGE, c_int, c_int]
187
+letterbox_image.restype = IMAGE
188
+
189
+load_meta = lib.get_metadata
190
+lib.get_metadata.argtypes = [c_char_p]
191
+lib.get_metadata.restype = METADATA
192
+
193
+load_image = lib.load_image_color
194
+load_image.argtypes = [c_char_p, c_int, c_int]
195
+load_image.restype = IMAGE
196
+
197
+rgbgr_image = lib.rgbgr_image
198
+rgbgr_image.argtypes = [IMAGE]
199
+
200
+predict_image = lib.network_predict_image
201
+predict_image.argtypes = [c_void_p, IMAGE]
202
+predict_image.restype = POINTER(c_float)
203
+
204
+
205
+def array_to_image(arr):
206
+    import numpy as np
207
+    # need to return old values to avoid python freeing memory
208
+    arr = arr.transpose(2, 0, 1)
209
+    c = arr.shape[0]
210
+    h = arr.shape[1]
211
+    w = arr.shape[2]
212
+    arr = np.ascontiguousarray(arr.flat, dtype=np.float32) / 255.0
213
+    data = arr.ctypes.data_as(POINTER(c_float))
214
+    im = IMAGE(w, h, c, data)
215
+    return im, arr
216
+
217
+
218
+def classify(net, meta, im):
219
+    out = predict_image(net, im)
220
+    res = []
221
+    for i in range(meta.classes):
222
+        if altNames is None:
223
+            nameTag = meta.names[i]
224
+        else:
225
+            nameTag = altNames[i]
226
+        res.append((nameTag, out[i]))
227
+    res = sorted(res, key=lambda x: -x[1])
228
+    return res
229
+
230
+
231
+def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45, debug=False):
232
+    """
233
+    Performs the detection
234
+    """
235
+    custom_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
236
+    custom_image = cv2.resize(custom_image, (lib.network_width(
237
+        net), lib.network_height(net)), interpolation=cv2.INTER_LINEAR)
238
+    im, arr = array_to_image(custom_image)
239
+    num = c_int(0)
240
+    pnum = pointer(num)
241
+    predict_image(net, im)
242
+    dets = get_network_boxes(
243
+        net, image.shape[1], image.shape[0], thresh, hier_thresh, None, 0, pnum, 0)
244
+    num = pnum[0]
245
+    if nms:
246
+        do_nms_sort(dets, num, meta.classes, nms)
247
+    res = []
248
+    if debug:
249
+        pass
250
+        #print("about to range")
251
+    for j in range(num):
252
+        for i in range(meta.classes):
253
+            try:
254
+                if dets[j].prob[i] > 0:
255
+                    b = dets[j].bbox
256
+                    if altNames is None:
257
+                        nameTag = meta.names[i]
258
+                    else:
259
+                        nameTag = altNames[i]
260
+                    res.append((nameTag, dets[j].prob[i], (b.x, b.y, b.w, b.h), i))
261
+            except ValueError as e:
262
+                #print(e)
263
+                pass
264
+    res = sorted(res, key=lambda x: -x[1])
265
+    free_detections(dets, num)
266
+    return res
267
+
268
+
269
+netMain = None
270
+metaMain = None
271
+altNames = None
272
+
273
+
274
+def getObjectDepth(depth, bounds):
275
+    area_div = 2
276
+
277
+    x_vect = []
278
+    y_vect = []
279
+    z_vect = []
280
+
281
+    for j in range(int(bounds[0] - area_div), int(bounds[0] + area_div)):
282
+        for i in range(int(bounds[1] - area_div), int(bounds[1] + area_div)):
283
+            z = depth[i, j, 2]
284
+            if not np.isnan(z) and not np.isinf(z):
285
+                x_vect.append(depth[i, j, 0])
286
+                y_vect.append(depth[i, j, 1])
287
+                z_vect.append(z)
288
+    try:
289
+        x = statistics.median(x_vect)
290
+        y = statistics.median(y_vect)
291
+        z = statistics.median(z_vect)
292
+    except Exception:
293
+        x = -1
294
+        y = -1
295
+        z = -1
296
+        pass
297
+
298
+    return x, y, z
299
+
300
+
301
+def generateColor(metaPath):
302
+    random.seed(42)
303
+    f = open(metaPath, 'r')
304
+    content = f.readlines()
305
+    class_num = int(content[0].split("=")[1])
306
+    color_array = []
307
+    for x in range(0, class_num):
308
+        color_array.append((randint(0, 255), randint(0, 255), randint(0, 255)))
309
+    return color_array
310
+
311
+
312
+def main(argv):
313
+
314
+    thresh = 0.25
315
+    configPath = "/sources/cfg.cfg"
316
+    weightPath = "/sources/mailsys.weight"
317
+    metaPath = "/sources/data.data"
318
+    svoPath = None
319
+
320
+    help_str = 'darknet_zed.py -c <config> -w <weight> -m <meta> -t <threshold> -s <svo_file> -o <output_path>'
321
+    try:
322
+        opts, args = getopt.getopt(
323
+            argv, "hc:w:m:t:s:o:", ["config=", "weight=", "meta=", "threshold=", "svo_file=", "output_path="])
324
+    except getopt.GetoptError:
325
+        print (help_str)
326
+        sys.exit(2)
327
+    for opt, arg in opts:
328
+        if opt == '-h':
329
+            print (help_str)
330
+            sys.exit()
331
+        elif opt in ("-c", "--config"):
332
+            configPath = arg
333
+        elif opt in ("-w", "--weight"):
334
+            weightPath = arg
335
+        elif opt in ("-m", "--meta"):
336
+            metaPath = arg
337
+        elif opt in ("-t", "--threshold"):
338
+            thresh = float(arg)
339
+        elif opt in ("-s", "--svo_file"):
340
+            svoPath = arg
341
+        elif opt in ("-o", "--output_path"):
342
+            output_path = arg
343
+
344
+    init = sl.InitParameters()
345
+    init.coordinate_units = sl.UNIT.METER
346
+
347
+
348
+
349
+    if svoPath is not None:
350
+        init.set_from_svo_file(svoPath)
351
+
352
+    dirname = os.path.splitext(svoPath)[0]
353
+    dir, filename = os.path.split(dirname)
354
+    #print(output_path)
355
+    #print(filename)
356
+
357
+    #try:
358
+    #    if not (os.path.isdir(output_path)):
359
+    #        os.makedirs(os.path.join(output_path))
360
+    #except OSError as e:
361
+    #    #print(e)
362
+
363
+
364
+    cam = sl.Camera()
365
+    if not cam.is_opened():
366
+        #print("Opening ZED Camera...")
367
+        pass
368
+    status = cam.open(init)
369
+    if status != sl.ERROR_CODE.SUCCESS:
370
+        #print(repr(status))
371
+        exit()
372
+
373
+    runtime = sl.RuntimeParameters()
374
+    # Use STANDARD sensing mode
375
+    runtime.sensing_mode = sl.SENSING_MODE.STANDARD
376
+    mat = sl.Mat()
377
+    point_cloud_mat = sl.Mat()
378
+
379
+    # Import the global variables. This lets us instance Darknet once, then just call performDetect() again without instancing again
380
+    global metaMain, netMain, altNames  # pylint: disable=W0603
381
+    assert 0 < thresh < 1, "Threshold should be a float between zero and one (non-inclusive)"
382
+    if not os.path.exists(configPath):
383
+        raise ValueError("Invalid config path `" +
384
+                         os.path.abspath(configPath)+"`")
385
+    if not os.path.exists(weightPath):
386
+        raise ValueError("Invalid weight path `" +
387
+                         os.path.abspath(weightPath)+"`")
388
+    if not os.path.exists(metaPath):
389
+        raise ValueError("Invalid data file path `" +
390
+                         os.path.abspath(metaPath)+"`")
391
+    if netMain is None:
392
+        netMain = load_net_custom(configPath.encode(
393
+            "ascii"), weightPath.encode("ascii"), 0, 1)  # batch size = 1
394
+    if metaMain is None:
395
+        metaMain = load_meta(metaPath.encode("ascii"))
396
+    if altNames is None:
397
+        # In thon 3, the metafile default access craps out on Windows (but not Linux)
398
+        # Read the names file and create a list to feed to detect
399
+        try:
400
+            with open(metaPath) as metaFH:
401
+                metaContents = metaFH.read()
402
+                import re
403
+                match = re.search("names *= *(.*)$", metaContents,
404
+                                  re.IGNORECASE | re.MULTILINE)
405
+                if match:
406
+                    result = match.group(1)
407
+                else:
408
+                    result = None
409
+                try:
410
+                    if os.path.exists(result):
411
+                        with open(result) as namesFH:
412
+                            namesList = namesFH.read().strip().split("\n")
413
+                            altNames = [x.strip() for x in namesList]
414
+                except TypeError:
415
+                    pass
416
+        except Exception:
417
+            pass
418
+
419
+    color_array = generateColor(metaPath)
420
+
421
+    #print("Running...")
422
+    #df1 = df(data={'frame': [], 'label': [], 'x': [], 'y': [], 'depth': []})
423
+    df1 = df(data={'x': [], 'y': [], 'z': [], 'frame': []})
424
+    #print(df1)
425
+    start = time.time()
426
+    key = ''
427
+    count = 0
428
+    frame = 1
429
+
430
+    #image_size = cam.get_resolution()
431
+    #width = image_size.width
432
+    #height = image_size.height
433
+    #width_sbs = width * 2
434
+
435
+    # Prepare side by side image container equivalent to CV_8UC4
436
+    #svo_image_sbs_rgba = np.zeros((height, width_sbs, 4), dtype=np.uint8)
437
+    fourcc = cv2.VideoWriter_fourcc('M', '4', 'S', '2')
438
+
439
+    # 컬러 영상 저장시
440
+    ##print(cam.get_camera_fps(), "!!!!!!!!!!!")
441
+    #video_path = os.path.join(output_path, filename)
442
+    #writer = cv2.VideoWriter(str(video_path)+"_output.avi", fourcc, cam.get_camera_fps(), (width, height))
443
+    ##print(video_path)
444
+    ##print(writer)
445
+    while key != 113:  # for 'q' key
446
+        err = cam.grab(runtime)
447
+        if err == sl.ERROR_CODE.SUCCESS:
448
+            cam.retrieve_image(mat, sl.VIEW.LEFT)
449
+            image = mat.get_data()
450
+
451
+            cam.retrieve_measure(
452
+                point_cloud_mat, sl.MEASURE.XYZRGBA)
453
+            depth = point_cloud_mat.get_data()
454
+
455
+            # Do the detection
456
+            detections = detect(netMain, metaMain, image, thresh)
457
+
458
+            #print(chr(27) + "[2J"+"**** " +
459
+                #  str(len(detections)) + " Results ****")
460
+            frame += 1
461
+            for detection in detections:
462
+                label = detection[0]
463
+                confidence = detection[1]
464
+                pstring = label+": "+str(np.rint(100 * confidence))+"%"
465
+                #print(pstring)
466
+                bounds = detection[2]
467
+                yExtent = int(bounds[3])
468
+                xEntent = int(bounds[2])
469
+                # Coordinates are around the center
470
+                xCoord = int(bounds[0] - bounds[2]/2)
471
+                yCoord = int(bounds[1] - bounds[3]/2)
472
+                boundingBox = [[xCoord, yCoord], [xCoord, yCoord + yExtent], [xCoord + xEntent, yCoord + yExtent], [xCoord + xEntent, yCoord] ]
473
+                thickness = 1
474
+                x, y, z = getObjectDepth(depth, bounds)
475
+                distance_xyz = math.sqrt(x * x + y * y + z * z)
476
+
477
+                distance = "{:.4f}".format(distance_xyz)
478
+
479
+                #print(label, distance, xCoord, yCoord)
480
+                cv2.rectangle(image, (xCoord-thickness, yCoord-thickness), (xCoord + xEntent+thickness, yCoord+(18 +thickness*4)), color_array[detection[3]], -1)
481
+                cv2.putText(image, label + " " +  (str(distance) + " m"), (xCoord+(thickness*4), yCoord+(10 +thickness*4)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 2)
482
+                cv2.rectangle(image, (xCoord-thickness, yCoord-thickness), (xCoord + xEntent+thickness, yCoord + yExtent+thickness), color_array[detection[3]], int(thickness*2))
483
+                x = xCoord-thickness
484
+                x1 = xCoord + xEntent+thickness
485
+                y = yCoord-thickness
486
+                y1 = yCoord + yExtent+thickness
487
+                
488
+
489
+                #If need normalize, erase # and change df1.loc[count]
490
+                #norm_x = (x + x1) / 2 / WIDTH
491
+                #norm_y = (y + y1) / 2 / HEIGHT
492
+                #norm_z = distance_xyz / DEPTH_MAX
493
+
494
+
495
+                
496
+                df1.loc[count] = [int(xCoord), int(yCoord), distance_xyz, int(frame)]
497
+                #df1.columns = ['idx','frame','label','x','y','depth']
498
+                cv2.line(image, (int((x+x1)/2), int((y+y1)/2)), (int((x+x1)/2), int((y+y1)/2)), (0, 0, 255), 10)
499
+
500
+                count += 1
501
+                image = cv2.cvtColor(image, cv2.COLOR_RGBA2RGB)
502
+            #print(frame)
503
+            image = cv2.cvtColor(image, cv2.COLOR_RGBA2RGB)
504
+            #writer.write(image)
505
+            # cv2.imshow("ZED", image)
506
+           # key = cv2.waitKey(5)
507
+            # #print(cam.get_svo_number_of_frames())
508
+            if frame == cam.get_svo_number_of_frames():
509
+                break
510
+        else:
511
+            #print('something happend')
512
+            #key = cv2.waitKey(5)
513
+            pass
514
+    #print("time :", time.time() - start)
515
+
516
+    cam.close()
517
+    #writer.release()
518
+    #cv2.destroyAllWindows()
519
+    #print("\nFINISH")
520
+    ##print(df1)
521
+    
522
+    df1.to_csv(output_path, index=False)
523
+    #print("csv save")
524
+
525
+
526
+if __name__ == "__main__":
527
+
528
+    #print(sys.argv)
529
+    main(sys.argv[1:])

Loading…
İptal
Kaydet