Object Detection Tutorial#

Run on Google Colab View source on GitHub Download notebook

Start EVA server#

We are reusing the start server notebook for launching the EVA server.

!wget -nc "https://raw.githubusercontent.com/georgia-tech-db/eva/master/tutorials/00-start-eva-server.ipynb"
%run 00-start-eva-server.ipynb
cursor = connect_to_server()
File '00-start-eva-server.ipynb' already there; not retrieving.

nohup eva_server > eva.log 2>&1 &
Note: you may need to restart the kernel to use updated packages.

Download the Videos#

# Getting the video files
!wget -nc https://www.dropbox.com/s/k00wge9exwkfxz6/ua_detrac.mp4?raw=1 -O ua_detrac.mp4
# Getting the Yolo object detector
!wget -nc https://raw.githubusercontent.com/georgia-tech-db/eva/master/eva/udfs/yolo_object_detector.py
File 'ua_detrac.mp4' already there; not retrieving.
File 'yolo_object_detector.py' already there; not retrieving.

Load the surveillance videos for analysis#

We use regular expression to load all the videos into the table#

cursor.execute('DROP TABLE ObjectDetectionVideos')
response = cursor.fetch_all()
print(response)
cursor.execute('LOAD VIDEO "ua_detrac.mp4" INTO ObjectDetectionVideos;')
response = cursor.fetch_all()
print(response)
@status: ResponseStatus.SUCCESS
@batch: 
                                                    0
0  Table Successfully dropped: ObjectDetectionVideos
@query_time: 0.03936416003853083
@status: ResponseStatus.SUCCESS
@batch: 
                            0
0  Number of loaded VIDEO: 1
@query_time: 0.07350237295031548

Visualize Video#

from IPython.display import Video
Video("ua_detrac.mp4", embed=True)

Register YOLO Object Detector an an User-Defined Function (UDF) in EVA#

cursor.execute("""CREATE UDF IF NOT EXISTS YoloV5
      INPUT  (frame NDARRAY UINT8(3, ANYDIM, ANYDIM))
      OUTPUT (labels NDARRAY STR(ANYDIM), bboxes NDARRAY FLOAT32(ANYDIM, 4),
                scores NDARRAY FLOAT32(ANYDIM))
      TYPE  Classification
      IMPL  'yolo_object_detector.py';
      """)
response = cursor.fetch_all()
print(response)
@status: ResponseStatus.SUCCESS
@batch: 
                                            0
0  UDF YoloV5 already exists, nothing added.
@query_time: 0.014365370385348797

Run Object Detector on the video#

cursor.execute("""SELECT id, YoloV5(data)
                  FROM ObjectDetectionVideos 
                  WHERE id < 20""")
response = cursor.fetch_all()
print(response)
@status: ResponseStatus.SUCCESS
@batch: 
     objectdetectionvideos.id  \
0                          0   
1                          1   
2                          2   
3                          3   
4                          4   
5                          5   
6                          6   
7                          7   
8                          8   
9                          9   
10                        10   
11                        11   
12                        12   
13                        13   
14                        14   
15                        15   
16                        16   
17                        17   
18                        18   
19                        19   

                                                                                          yolov5.labels  \
0   [car, car, car, car, car, car, car, car, car, person, car, motorcycle, car, truck, car, car, car...   
1   [car, car, car, car, car, car, car, car, car, person, car, car, truck, car, car, car, car, motor...   
2   [car, car, car, car, car, car, car, car, car, car, person, car, truck, car, motorcycle, car, car...   
3   [car, car, car, car, car, car, car, car, car, car, car, car, truck, person, motorcycle, truck, c...   
4   [car, car, car, car, car, car, car, car, car, car, car, person, car, car, motorcycle, truck, car...   
5   [car, car, car, car, car, car, car, car, car, car, car, person, car, car, car, car, motorcycle, ...   
6   [car, car, car, car, car, car, car, car, person, car, car, car, car, car, motorcycle, car, car, ...   
7   [car, car, car, car, car, car, car, car, car, car, person, car, car, car, motorcycle, car, car, ...   
8   [car, car, car, car, car, car, car, car, car, person, car, motorcycle, car, car, car, car, truck...   
9   [car, car, car, car, car, car, car, car, car, car, person, car, car, car, car, truck, car, perso...   
10  [car, car, car, car, car, car, car, car, car, person, car, car, car, car, truck, car, car, car, ...   
11  [car, car, car, car, car, car, car, car, person, car, truck, car, truck, car, car, car, car, car...   
12  [car, car, car, car, car, car, car, car, car, person, car, car, motorcycle, car, car, car, truck...   
13  [car, car, car, car, car, car, car, car, car, truck, car, person, motorcycle, truck, car, car, m...   
14  [car, car, car, car, car, car, car, person, car, car, car, truck, truck, motorcycle, motorcycle,...   
15  [car, car, car, car, car, car, car, person, car, car, car, motorcycle, car, car, car, motorcycle...   
16  [car, car, car, car, car, car, person, car, car, car, car, motorcycle, motorcycle, truck, car, c...   
17  [car, car, car, car, car, car, car, person, car, car, car, car, car, truck, motorcycle, motorcyc...   
18  [car, car, car, car, car, car, car, car, car, person, car, car, car, bus, truck, motorcycle, car...   
19  [car, car, car, car, car, car, car, car, car, person, car, car, car, car, truck, bus, car, car, ...   

                                                                                          yolov5.bboxes  \
0   0                     [830.513916015625, 276.9407958984375, 960.0, 360.9553527832031]
1         ...   
1   0                  [833.4142456054688, 277.43121337890625, 960.0, 363.24542236328125]
1      [61...   
2   0                          [837.3671875, 278.4643859863281, 960.0, 363.9206848144531]
1         ...   
3   0                      [840.7059326171875, 279.1480712890625, 960.0, 360.564208984375]
1        ...   
4   0           [623.8599853515625, 218.58824157714844, 729.417724609375, 280.35791015625]
1        ...   
5   0             [624.716796875, 217.99139404296875, 731.593994140625, 280.8290100097656]
1        ...   
6   0         [625.336669921875, 217.91189575195312, 734.4633178710938, 281.4993896484375]
1        ...   
7   0       [626.2813110351562, 218.29205322265625, 736.9923095703125, 282.62371826171875]
1        ...   
8   0         [628.342041015625, 219.6263427734375, 738.7610473632812, 284.00531005859375]
1        ...   
9   0            [630.125732421875, 221.2857666015625, 740.33349609375, 284.7383728027344]
1        ...   
10  0       [632.170654296875, 222.32720947265625, 743.0787353515625, 284.72711181640625]
1        [...   
11  0          [634.2802734375, 222.06613159179688, 747.0035400390625, 287.9921569824219]
1         ...   
12  0         [636.1023559570312, 222.5532989501953, 748.899658203125, 288.3439636230469]
1         ...   
13  0         [636.18408203125, 222.69622802734375, 751.6583862304688, 287.90509033203125]
1        ...   
14  0        [638.757080078125, 223.4717559814453, 753.6521606445312, 288.96051025390625]
1       [1...   
15  0        [641.4051513671875, 224.3956298828125, 757.6414794921875, 290.0587158203125]
1         ...   
16  0          [644.2322387695312, 225.87051391601562, 761.1083984375, 290.7424011230469]
1         ...   
17  0           [646.2791137695312, 225.9928436279297, 763.2777709960938, 291.8134765625]
1         ...   
18  0      [647.1568603515625, 226.51368713378906, 765.8187866210938, 292.62884521484375]
1         ...   
19  0          [648.61767578125, 227.11984252929688, 768.1045532226562, 293.3794250488281]
1        ...   

                                                                                          yolov5.scores  
0   [0.9019389748573303, 0.8878238201141357, 0.8540899157524109, 0.8021702766418457, 0.7838875651359...  
1   [0.8980059623718262, 0.8685558438301086, 0.8364439606666565, 0.8237311244010925, 0.7718729972839...  
2   [0.8956702351570129, 0.8518660068511963, 0.8487427234649658, 0.8453817963600159, 0.7860085368156...  
3   [0.8803829550743103, 0.866111695766449, 0.8498753905296326, 0.8373444676399231, 0.82564580440521...  
4   [0.8975156545639038, 0.8809236884117126, 0.8435657024383545, 0.8381263613700867, 0.7975137829780...  
5   [0.9156807661056519, 0.8994482159614563, 0.8464253544807434, 0.8432754278182983, 0.7775278091430...  
6   [0.9120901226997375, 0.9068282246589661, 0.8413792848587036, 0.8137449026107788, 0.7970511317253...  
7   [0.9046720266342163, 0.8707322478294373, 0.8454322218894958, 0.8174154162406921, 0.7925598621368...  
8   [0.8893280625343323, 0.8552685379981995, 0.8536511063575745, 0.8232781887054443, 0.7951847910881...  
9   [0.8876322507858276, 0.8557678461074829, 0.8532631993293762, 0.7946798205375671, 0.7720419764518...  
10  [0.8991596102714539, 0.835357129573822, 0.8304201364517212, 0.8152026534080505, 0.78578490018844...  
11  [0.9085388779640198, 0.8469469547271729, 0.8388872742652893, 0.7947012186050415, 0.7883725166320...  
12  [0.9089047908782959, 0.861946165561676, 0.8548004031181335, 0.8538579344749451, 0.80343031883239...  
13  [0.8987026214599609, 0.8819432854652405, 0.8584625720977783, 0.8529505729675293, 0.8020280003547...  
14  [0.8915325999259949, 0.8549790978431702, 0.8541241884231567, 0.8505778312683105, 0.8061172962188...  
15  [0.8875617980957031, 0.863188624382019, 0.8474203944206238, 0.8387583494186401, 0.82478755712509...  
16  [0.8969656229019165, 0.8630248308181763, 0.8239783644676208, 0.8124073147773743, 0.8089075684547...  
17  [0.8984967470169067, 0.8612021207809448, 0.8340322971343994, 0.8170910477638245, 0.8132005929946...  
18  [0.8983427882194519, 0.8600170016288757, 0.8409520983695984, 0.8305366635322571, 0.8134506940841...  
19  [0.8998425006866455, 0.8530007004737854, 0.8488078713417053, 0.8350291848182678, 0.8190277814865...  
@query_time: 7.09188617952168

Visualizing output of the Object Detector on the video#

import cv2
from pprint import pprint
from matplotlib import pyplot as plt

def annotate_video(detections, input_video_path, output_video_path):
    color1=(207, 248, 64)
    color2=(255, 49, 49)
    thickness=4

    vcap = cv2.VideoCapture(input_video_path)
    width = int(vcap.get(3))
    height = int(vcap.get(4))
    fps = vcap.get(5)
    fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') #codec
    video=cv2.VideoWriter(output_video_path, fourcc, fps, (width,height))

    frame_id = 0
    # Capture frame-by-frame
    # ret = 1 if the video is captured; frame is the image
    ret, frame = vcap.read() 

    while ret:
        df = detections
        df = df[['yolov5.bboxes', 'yolov5.labels']][df.index == frame_id]
        if df.size:
            dfLst = df.values.tolist()
            for bbox, label in zip(dfLst[0][0], dfLst[0][1]):
                x1, y1, x2, y2 = bbox
                x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
                # object bbox
                frame=cv2.rectangle(frame, (x1, y1), (x2, y2), color1, thickness) 
                # object label
                cv2.putText(frame, label, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, color1, thickness) 
                # frame label
                cv2.putText(frame, 'Frame ID: ' + str(frame_id), (700, 500), cv2.FONT_HERSHEY_SIMPLEX, 1.2, color2, thickness) 
            video.write(frame)

            # Stop after twenty frames (id < 20 in previous query)
            if frame_id == 20:
                break

            # Show every fifth frame
            if frame_id % 5 == 0:
                plt.imshow(frame)
                plt.show()

        
        frame_id+=1
        ret, frame = vcap.read()

    video.release()
    vcap.release()
from ipywidgets import Video, Image
input_path = 'ua_detrac.mp4'
output_path = 'video.mp4'

dataframe = response.batch.frames
annotate_video(dataframe, input_path, output_path)
Video.from_file(output_path)
../../_images/be53987808ddd0051fa459ced93ffad8bdea532ef40513771d1bbd2932e12d38.png ../../_images/d4958b68b52e23637a1114e761f11a791708c8be7c035d2f776ffd5576e382e2.png ../../_images/8bb4329bdd9dec693c13eff39846f343bf513cdc529d111fb1a9e91efaf46d27.png ../../_images/cbcf8b8b5add1ce276ec4b2253d220f214972fe7db8749ecd7891e19abfac86b.png

Dropping an User-Defined Function (UDF)#

cursor.execute("DROP UDF YoloV5;")
response = cursor.fetch_all()
print(response)
@status: ResponseStatus.SUCCESS
@batch: 
                                  0
0  UDF YoloV5 successfully dropped
@query_time: 0.019077396020293236