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.

[  -z "$(lsof -ti:5432)" ] || kill -9 $(lsof -ti:5432)
nohup eva_server > eva.log 2>&1 &

WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
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
# Getting the Yolo object detector
!wget -nc https://raw.githubusercontent.com/georgia-tech-db/eva/master/eva/udfs/yolo_object_detector.py
--2022-12-18 17:38:12--  https://www.dropbox.com/s/k00wge9exwkfxz6/ua_detrac.mp4
Resolving www.dropbox.com (www.dropbox.com)... 162.125.81.18, 2620:100:6031:18::a27d:5112
Connecting to www.dropbox.com (www.dropbox.com)|162.125.81.18|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: /s/raw/k00wge9exwkfxz6/ua_detrac.mp4 [following]
--2022-12-18 17:38:14--  https://www.dropbox.com/s/raw/k00wge9exwkfxz6/ua_detrac.mp4
Reusing existing connection to www.dropbox.com:443.
HTTP request sent, awaiting response... 302 Found
Location: https://ucc182f7290bf0f438c01b8fc207.dl.dropboxusercontent.com/cd/0/inline/By37SE7JfGI9ZH1VKwVKYxa0-Asp7zMnwk4ZDt5wCtUiFDTf56SBzPl1l-tjPlWUUpBM-7aoMOiHeLHG4Wm9IyY2q8dD5A9wO77NbHxJhIEnxmRXCLMqHXaIIamCY1bxRRJoBsx8H-K0XupGg-5VwbVL4NA4xufvjpraiqjb2BmMmA/file# [following]
--2022-12-18 17:38:15--  https://ucc182f7290bf0f438c01b8fc207.dl.dropboxusercontent.com/cd/0/inline/By37SE7JfGI9ZH1VKwVKYxa0-Asp7zMnwk4ZDt5wCtUiFDTf56SBzPl1l-tjPlWUUpBM-7aoMOiHeLHG4Wm9IyY2q8dD5A9wO77NbHxJhIEnxmRXCLMqHXaIIamCY1bxRRJoBsx8H-K0XupGg-5VwbVL4NA4xufvjpraiqjb2BmMmA/file
Resolving ucc182f7290bf0f438c01b8fc207.dl.dropboxusercontent.com (ucc182f7290bf0f438c01b8fc207.dl.dropboxusercontent.com)... 162.125.81.15, 2620:100:6031:15::a27d:510f
Connecting to ucc182f7290bf0f438c01b8fc207.dl.dropboxusercontent.com (ucc182f7290bf0f438c01b8fc207.dl.dropboxusercontent.com)|162.125.81.15|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1661565 (1.6M) [video/mp4]
Saving to: 'ua_detrac.mp4'

ua_detrac.mp4       100%[===================>]   1.58M   781KB/s    in 2.1s    

2022-12-18 17:38:19 (781 KB/s) - 'ua_detrac.mp4' saved [1661565/1661565]

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 "*.mp4" INTO ObjectDetectionVideos;')
response = cursor.fetch_all()
print(response)
@status: ResponseStatus.SUCCESS
@batch: 
                                                    0
0  Table Successfully dropped: ObjectDetectionVideos
@query_time: 0.025422052000067197
@status: ResponseStatus.SUCCESS
@batch: 
                            0
0  Number of loaded VIDEO: 1
@query_time: 0.0706567309998718

Visualize Video#

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

Register FasterRCNN Object Detection model in 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.011802855000496493

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, truck, car, car, motorcycle, car, car, car...   
1   [car, car, car, car, car, car, car, car, car, person, truck, car, car, car, motorcycle, car, car...   
2   [car, car, car, car, car, car, car, car, car, person, car, motorcycle, truck, car, car, car, car...   
3   [car, car, car, car, car, car, car, person, car, car, car, motorcycle, truck, car, car, car, car...   
4   [car, car, car, car, car, car, car, car, car, person, motorcycle, car, car, truck, car, car, car...   
5   [car, car, car, car, car, car, car, car, person, car, car, truck, motorcycle, car, car, car, car...   
6   [car, car, car, car, car, car, car, person, car, car, car, truck, motorcycle, car, car, car, car...   
7   [car, car, car, car, car, car, car, car, person, car, car, truck, motorcycle, car, car, car, car...   
8   [car, car, car, car, car, car, car, car, car, car, person, motorcycle, truck, car, car, car, car...   
9   [car, car, car, car, car, car, car, car, car, car, person, motorcycle, truck, car, car, car, per...   
10  [car, car, car, car, car, car, car, car, car, person, car, motorcycle, truck, car, car, car, car...   
11  [car, car, car, car, car, car, car, person, car, car, motorcycle, truck, car, car, car, car, car...   
12  [car, car, car, car, car, car, car, car, person, car, car, motorcycle, truck, car, motorcycle, c...   
13  [car, car, car, car, car, car, car, car, car, car, person, motorcycle, truck, motorcycle, car, c...   
14  [car, car, car, car, car, car, car, car, car, person, car, truck, motorcycle, motorcycle, car, c...   
15  [car, car, car, car, car, car, car, car, car, person, car, truck, motorcycle, motorcycle, car, c...   
16  [car, car, car, car, car, car, car, car, car, person, car, truck, motorcycle, motorcycle, car, c...   
17  [car, car, car, car, car, car, car, car, car, person, car, truck, motorcycle, car, motorcycle, c...   
18  [car, car, car, car, car, car, car, car, car, person, car, motorcycle, truck, car, car, car, mot...   
19  [car, car, car, car, car, car, car, car, car, person, car, truck, car, motorcycle, car, car, mot...   

                                                                                          yolov5.bboxes  \
0   0          [615.0177612304688, 216.3213653564453, 720.9974365234375, 275.111572265625]
1        ...   
1   0                     [831.301025390625, 277.3231201171875, 960.0, 361.05999755859375]
1        ...   
2   0                    [835.5813598632812, 278.3633728027344, 960.0, 363.2155456542969]
1       [6...   
3   0                     [839.367431640625, 279.6907653808594, 960.0, 363.5947570800781]
1         ...   
4   0                     [842.60888671875, 280.20977783203125, 960.0, 364.7884826660156]
1       [6...   
5   0        [623.1436767578125, 219.5082550048828, 732.8285522460938, 279.24090576171875]
1        ...   
6   0        [624.30029296875, 219.43482971191406, 734.7637939453125, 280.71990966796875]
1         ...   
7   0        [626.1150512695312, 220.81576538085938, 738.7499389648438, 281.8699951171875]
1        ...   
8   0        [628.3634643554688, 222.46876525878906, 740.7850341796875, 283.034423828125]
1         ...   
9   0        [629.4367065429688, 223.33621215820312, 743.2886352539062, 284.0799255371094]
1        ...   
10  0        [631.0487060546875, 223.26512145996094, 744.9122924804688, 284.6850891113281]
1        ...   
11  0         [633.354736328125, 223.0447540283203, 747.6873779296875, 285.7002868652344]
1         ...   
12  0          [634.788818359375, 222.9927978515625, 750.9302368164062, 286.6802978515625]
1        ...   
13  0           [636.74267578125, 223.11041259765625, 753.564208984375, 287.9838562011719]
1        ...   
14  0          [639.1224365234375, 224.44171142578125, 755.95166015625, 288.9028015136719]
1        ...   
15  0           [640.0598754882812, 225.69580078125, 759.0479736328125, 289.3109436035156]
1        ...   
16  0      [642.4671630859375, 225.98965454101562, 762.2179565429688, 289.93438720703125]
1       [8...   
17  0          [645.32177734375, 226.70974731445312, 765.315673828125, 290.7102355957031]
1         ...   
18  0       [646.6506958007812, 227.46324157714844, 767.5223388671875, 291.5223083496094]
1      [87...   
19  0        [647.9537353515625, 227.8091278076172, 770.7684326171875, 293.2703857421875]
1         ...   

                                                                                          yolov5.scores  
0   [0.8976882100105286, 0.8935549855232239, 0.8289322853088379, 0.7905623316764832, 0.7743207812309...  
1   [0.9067937135696411, 0.8873312473297119, 0.8370824456214905, 0.8034706711769104, 0.7769310474395...  
2   [0.9066715240478516, 0.8586532473564148, 0.8389688730239868, 0.8235833048820496, 0.8092166185379...  
3   [0.9023867845535278, 0.8771656155586243, 0.8301073908805847, 0.8268834948539734, 0.8094114661216...  
4   [0.896634578704834, 0.8964879512786865, 0.8297851085662842, 0.819599986076355, 0.805158317089080...  
5   [0.89455246925354, 0.8825252056121826, 0.8602745532989502, 0.8407530188560486, 0.819087028503418...  
6   [0.8903160095214844, 0.882999062538147, 0.8565676808357239, 0.852742075920105, 0.820769965648651...  
7   [0.885131299495697, 0.8641898036003113, 0.849159300327301, 0.825408399105072, 0.8131763935089111...  
8   [0.876154899597168, 0.8475751280784607, 0.8426569104194641, 0.8185160756111145, 0.81222361326217...  
9   [0.8814646601676941, 0.863688588142395, 0.8601973056793213, 0.824044942855835, 0.819191694259643...  
10  [0.8830854892730713, 0.8734780550003052, 0.8712114095687866, 0.8251326084136963, 0.8065017461776...  
11  [0.8828203678131104, 0.8745031356811523, 0.873845100402832, 0.8063143491744995, 0.79807716608047...  
12  [0.8927742838859558, 0.8842470049858093, 0.8785963654518127, 0.8073289394378662, 0.8001264333724...  
13  [0.8936073184013367, 0.889167845249176, 0.8754433989524841, 0.8336893916130066, 0.81425130367279...  
14  [0.9018194675445557, 0.8859033584594727, 0.8765249252319336, 0.8446862697601318, 0.7918393611907...  
15  [0.903704047203064, 0.8661507964134216, 0.8648058772087097, 0.8274555206298828, 0.79597485065460...  
16  [0.9109856486320496, 0.8697980642318726, 0.8593540191650391, 0.8282628059387207, 0.7935148477554...  
17  [0.9092430472373962, 0.8774811029434204, 0.8753392696380615, 0.8411900401115417, 0.8310673832893...  
18  [0.9049761295318604, 0.8759952187538147, 0.8713913559913635, 0.8551534414291382, 0.8345064520835...  
19  [0.9039984941482544, 0.8782926797866821, 0.876212477684021, 0.8406674861907959, 0.81912362575531...  
@query_time: 5.126413627000147

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)

            # 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/1d041ce096f016f3178366a36588d09aa3e9df878be576251254a0a47e0991f6.png ../../_images/085283036797efd594ace8a8ded035eff488eb4edc27c12ffba6f1e5edea1eb3.png ../../_images/220435317c0708c3df9b55429ba42e9e04b0a2f4749906093d7e164526788393.png ../../_images/d22b83e26fee9920fe09597acbe38d1a723d940ed55171b5b89b7ae2a600537a.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.0143039120002868