{"id":1489,"date":"2021-08-13T10:42:19","date_gmt":"2021-08-13T01:42:19","guid":{"rendered":"https:\/\/blog.testworks.co.kr\/en\/?p=1489"},"modified":"2021-08-24T19:13:55","modified_gmt":"2021-08-24T10:13:55","slug":"deep-learning-for-traffic-counting","status":"publish","type":"post","link":"https:\/\/blog.aiworkx.ai\/en\/deep-learning-for-traffic-counting\/","title":{"rendered":"Deep Learning for Traffic Counting"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"501\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/cctv_video_bounding_box_labeling-1_1-1024x501.png\" alt=\"\" class=\"wp-image-1511\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/cctv_video_bounding_box_labeling-1_1-1024x501.png 1024w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/cctv_video_bounding_box_labeling-1_1-300x147.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/cctv_video_bounding_box_labeling-1_1-768x376.png 768w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/cctv_video_bounding_box_labeling-1_1.png 1136w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-1 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-2 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<figure class=\"wp-block-image size-large is-resized is-style-rounded\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/07\/\uc774\ucc3d\uc2e0-\uc18c\uc7a5.jpg\" alt=\"\" class=\"wp-image-1443\" width=\"143\" height=\"133\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/07\/\uc774\ucc3d\uc2e0-\uc18c\uc7a5.jpg 652w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/07\/\uc774\ucc3d\uc2e0-\uc18c\uc7a5-300x276.jpg 300w\" sizes=\"auto, (max-width: 143px) 100vw, 143px\" \/><\/figure>\n\n\n\n<p style=\"font-size:22px\"><strong>Changsin Lee l Tech Evangelist l Testworks<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-3 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-4 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">Did you know that traffic counting is behind the rise of Microsoft and thus modern personal computing? Traffic counting is used by city officials to determine transportation needs. The most popular method is by laying a strip of pneumatic rubber tube on the roadway of interest and analyze metrics like vehicle volume, vehicle types, axle counts, etc. This method, however, is not quite accurate or safe so a better method is researched. In this article, you will find how you can build your own traffic counter using a Deep Learning approach (YOLO V5) using a public dataset from the ground up. The entire source code is available in the\u00a0<a href=\"https:\/\/github.com\/changsin\/DLTrafficCounter\/blob\/main\/notebooks\/traffic_counter_yolov5.ipynb\" target=\"_blank\" rel=\"noreferrer noopener\">Colab notebook<\/a>. The sample training dataset used is AI Hub dataset number\u00a0<a href=\"https:\/\/aihub.or.kr\/aidata\/30743\" target=\"_blank\" rel=\"noreferrer noopener\">30743<\/a> which <a href=\"https:\/\/testworks.co.kr\/\" target=\"_blank\" rel=\"noreferrer noopener\">Testworks<\/a> delivered as a public dataset.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image.png\" alt=\"\uc774 \uc774\ubbf8\uc9c0\ub294 \ub300\uccb4 \uc18d\uc131\uc774 \ube44\uc5b4\uc788\uc2b5\ub2c8\ub2e4. \uadf8 \ud30c\uc77c \uc774\ub984\uc740 image.png\uc785\ub2c8\ub2e4\"\/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-5 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Problems<\/strong><\/p>\n\n\n\n<p style=\"font-size:17px\">Interestingly, before they founded Microsoft, Bill Gates and Paul Allen first tried their hands on automating some manual processes in punching in the pneumatic road tube data. The business partnership was named as\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Traf-O-Data\" target=\"_blank\" rel=\"noreferrer noopener\">Traf-O-Data<\/a>\u00a0which later became Microsoft. While the project itself was not very successful on its own, the experience they gained eventually led to founding Microsoft and the rest is history.<\/p>\n\n\n\n<p style=\"font-size:17px\">Though pneumatic rubber tube counters are easy and widely used solutions, there are a few problems:<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\" style=\"font-size:17px\"><li>Setup risks: To set up the tubes, someone has to go out in the middle of a high-traffic roadway. This is risky and poses an insignificant amount of liability issues.<\/li><li>Wear-and-tear: Rubber tubes invariably suffer from natural wear-and-tear and thus need to be replaced on regular basis. A more sinister problem is that the device might start reporting inaccurate metrics without people realizing it.<\/li><li>Inaccuracy: A bigger problem is that the metrics that can be gathered from pneumatic tubes are rough guestimates at best. Vehicle speed and traffic conditions can all contribute to inaccurate measurement.<\/li><li>Scalability issues: While the tube provides a simple method of counting, if you want to gather other information like pedestrians, cyclists, motorists, models of vehicles, etc., there is simply no way the pneumatic rubber tubes can scale up.<\/li><\/ol>\n\n\n\n<p style=\"font-size:17px\">For these reasons, a safer and more scalable method is sought after in the field of Computer Vision, especially Deep Learning. The key to a good performing Deep Learning model is, of course, quality training data. The good news is that there are many publicly available free datasets. In what follows, I am going to show how you can enhance the performance of a traffic counting model through transfer learning on public data. For the experiment,\u00a0<a href=\"https:\/\/aihub.or.kr\/aidata\/30743\" target=\"_blank\" rel=\"noreferrer noopener\">a sample surveillance camera dataset<\/a>\u00a0from\u00a0<a href=\"https:\/\/aihub.or.kr\/\" target=\"_blank\" rel=\"noreferrer noopener\">AI Hub Korea<\/a>. There are 100 images taken from a fixed point surveillance camera and they were tagged with bounding boxes.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-6 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Baseline Model: YOLO V5<\/strong><\/p>\n\n\n\n<p style=\"font-size:17px\"><a href=\"https:\/\/pjreddie.com\/darknet\/yolo\/\" target=\"_blank\" rel=\"noreferrer noopener\">YOLO<\/a>\u00a0(You Only Look Once) is an open-source Deep Learning system that is used successfully used for object detection. There are also pre-trained models from which you can train with your own dataset. This is called \u2018<a href=\"https:\/\/en.wikipedia.org\/wiki\/Transfer_learning\" target=\"_blank\" rel=\"noreferrer noopener\">transfer learning<\/a>\u2019 and a good way to bootstrap your own vehicle detection system. To do so, let\u2019s get YOLO V5 together with the pre-trained model.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"794\" height=\"213\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-1.png\" alt=\"\" class=\"wp-image-1491\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-1.png 794w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-1-300x80.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-1-768x206.png 768w\" sizes=\"auto, (max-width: 794px) 100vw, 794px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">Now get some test image data and run through the model. You are welcome to use any images but since we are interested in traffic data, let\u2019s grab some images from a highway surveillance camera\u00a0<a href=\"https:\/\/github.com\/changsin\/DLTrafficCounter\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>\u00a0and then run the detect command to obtain yolov5 predictions.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"785\" height=\"51\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-2.png\" alt=\"\" class=\"wp-image-1492\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-2.png 785w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-2-300x19.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-2-768x50.png 768w\" sizes=\"auto, (max-width: 785px) 100vw, 785px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">Detailed descriptions of what each command line parameter means can be found in the yolov5 repository. For our purposes, we just need to specify the weights file (weights parameter), image size (img parameter), confidence threshold (conf parameter: 0.5 means that the confidence probability should be at least 50%), and the source folder where the test images are located (source parameter). Here is sample output from the detection:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-3.png\" alt=\"\" class=\"wp-image-1493\" width=\"624\" height=\"351\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-3.png 624w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-3-300x169.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><figcaption>YOLO V5 detection result<\/figcaption><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">While the pre-trained model did a pretty good job in detecting and recognizing vehicles, it missed a lot of vehicles in the back. Even worse, in some cases, it recognized a row of cars as a train as in the below example. Ouch!<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-4.png\" alt=\"\" class=\"wp-image-1494\" width=\"624\" height=\"351\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-4.png 624w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-4-300x169.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Train a Vehicle Counting Model<\/strong><\/p>\n\n\n\n<p style=\"font-size:17px\">To enhance the pre-trained model, we need some labeled data. AI Hub is a public dataset repository in Korea and we can find a\u00a0<a href=\"https:\/\/aihub.or.kr\/aidata\/30743\" target=\"_blank\" rel=\"noreferrer noopener\">labeled highway image dataset<\/a>\u00a0from a surveillance camera. The whole dataset contains 500,000 images. For an illustration purpose, let\u2019s just use the sample dataset that has 100 images labels. The same sample test image shows the target labels that YOLO V5 missed:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"347\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-5.png\" alt=\"\" class=\"wp-image-1495\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-5.png 624w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-5-300x167.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><figcaption><strong>Trains in a highway? No way!<\/strong><\/figcaption><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">To train the YOLO model, we need to configure a few things. The most important thing is the label format and the train configuration file. Let\u2019s look at the configuration file first. This file must contain the datasets you want to use (train, validation, and test data folders), the number of classes, and the class names. Since our purpose is vehicle counting, there are only three vehicle classes. Here is the entirety of the train configuration YAML file.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"792\" height=\"207\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-6.png\" alt=\"\" class=\"wp-image-1496\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-6.png 792w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-6-300x78.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-6-768x201.png 768w\" sizes=\"auto, (max-width: 792px) 100vw, 792px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">Second, for each image file, there must be the corresponding *.txt file with the same file name. In each label text file, the labels must be of the following format:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-8.png\" alt=\"\" class=\"wp-image-1498\" width=\"785\" height=\"24\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-8.png 785w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-8-300x9.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-8-768x23.png 768w\" sizes=\"auto, (max-width: 785px) 100vw, 785px\" \/><\/figure><\/div>\n\n\n\n<ul class=\"wp-block-list\" style=\"font-size:17px\"><li>The first number is the class id. The id refers to the index in the class names list in the training configuration file. In this case, 2 means \u2018truck\u2019 which is index 2 in the list.<\/li><li>The next two numbers refer to the x and y coordinates of the image center (x and y center).<\/li><li>The last two numbers are the width and the height of the label.<\/li><li>Note that all numbers except the class id are normalized between 0 and 1. For instance, if the image size is (1920, 1080) as in our case, the actual coordinates should be scaled back to: (0.62772&#215;1920=1205.22, 0.58336&#215;1080=630.03, 0.02264&#215;1920=43.47, 0.0359&#215;1080=38.77)<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">Based on this information, the annotation files are generated and put in the same folder as the training image files. Now let\u2019s run the training script to train the model. We are using 400 epochs with 10 images per batch.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"785\" height=\"73\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-9.png\" alt=\"\" class=\"wp-image-1499\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-9.png 785w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-9-300x28.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-9-768x71.png 768w\" sizes=\"auto, (max-width: 785px) 100vw, 785px\" \/><\/figure><\/div>\n\n\n\n<p style=\"font-size:17px\">A sample training run looks like the following:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"788\" height=\"295\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-10.png\" alt=\"\" class=\"wp-image-1500\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-10.png 788w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-10-300x112.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-10-768x288.png 768w\" sizes=\"auto, (max-width: 788px) 100vw, 788px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">The best model (best.pt) and the last model (last.pt) are saved under \u2018runs\/train\/exp\/weights\u2019 folder unless \u2018nosave\u2019 option is specified.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"312\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-11.png\" alt=\"\" class=\"wp-image-1501\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-11.png 624w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-11-300x150.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><figcaption><strong>Train results with 400 epochs<\/strong><\/figcaption><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Detect and Count<\/strong><\/p>\n\n\n\n<p style=\"font-size:17px\">Running against the same test image, we now get quite a different result. It seems to have detected all the vehicles.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"351\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-12.png\" alt=\"\" class=\"wp-image-1502\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-12.png 624w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-12-300x169.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">How about the trains on the highway? Nope. They are gone and replaced with detected vehicle types.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"351\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-13.png\" alt=\"\" class=\"wp-image-1503\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-13.png 624w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-13-300x169.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">To see whether the newly trained model correctly detected all vehicles, let\u2019s actually count vehicles for each type in the test images and tally them up. To do so, we need to parse the detection results returned by the model.<\/p>\n\n\n\n<p style=\"font-size:17px\">The detection results returned by YOLO contains the following information that is useful for our purpose:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">1. results.names contain the names of classes: e.g., \u2018person\u2019. There are 80 of them by default corresponding to 80 COCO dataset classes including car, bus, and truck<\/p>\n\n\n\n<p style=\"font-size:17px\">2. results.xyxyn: xy coordinates followed by the confidence and the class id. For instance, the first item is class_id=0 with 90% confidence which refers to the \u2018person\u2019 class<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"783\" height=\"226\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-14.png\" alt=\"\" class=\"wp-image-1504\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-14.png 783w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-14-300x87.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-14-768x222.png 768w\" sizes=\"auto, (max-width: 783px) 100vw, 783px\" \/><\/figure><\/div>\n\n\n\n<p style=\"font-size:17px\">3. results.imgs is the labeled image containing the detection results.<\/p>\n\n\n\n<p style=\"font-size:17px\">4. results.save(\u2018folder\u2019) saves the detection result image to the folder.<\/p>\n\n\n\n<p style=\"font-size:17px\">Here is the code snippet that counts vehicles per type:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"789\" height=\"191\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-15.png\" alt=\"\" class=\"wp-image-1505\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-15.png 789w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-15-300x73.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-15-768x186.png 768w\" sizes=\"auto, (max-width: 789px) 100vw, 789px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">Using the counting code, let\u2019s compare the custom trained highway vehicle detection model against the YOLO pre-trained baseline model together with the ground truth:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"786\" height=\"180\" src=\"https:\/\/blog.testworks.co.kr\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-18.png\" alt=\"\" class=\"wp-image-1524\" srcset=\"https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-18.png 786w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-18-300x69.png 300w, https:\/\/blog.aiworkx.ai\/en\/wp-content\/uploads\/sites\/3\/2021\/08\/image-18-768x176.png 768w\" sizes=\"auto, (max-width: 786px) 100vw, 786px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p style=\"font-size:17px\">We can see that the custom model did quite well with just less than 100 images. Nice!<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-medium-font-size\"><strong>Conclusion<\/strong><\/p>\n\n\n\n<p style=\"font-size:17px\">Are we done yet? Sort of, except that the model will over-count if it is processing a stream of video images. To correctly count, you need to track vehicles across different frames. This problem requires a different article. A different problem is that the current model is biased towards a dataset from a fixed position of a highway surveillance camera whose images are taken during the day. To make the model more robust, you need to train it with more diverse datasets. But now you know how to do it. Thanks for reading.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-10 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-11 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-12 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator is-style-wide\"\/>\n\n\n\n<p style=\"font-size:18px\"><strong>Reference<\/strong><\/p>\n\n\n\n<ul class=\"has-normal-font-size wp-block-list\"><li>Source code for converting and generating YOLO V5 formats as well as all other plotting functions can be found in this\u00a0<a href=\"https:\/\/github.com\/changsin\/DLTrafficCounter\/blob\/main\/notebooks\/traffic_counter_yolov5.ipynb\" target=\"_blank\" rel=\"noreferrer noopener\">Colab notebook<\/a>.<\/li><li>The sample dataset used came from AI Hub dataset number\u00a0<a href=\"https:\/\/aihub.or.kr\/aidata\/30743\" target=\"_blank\" rel=\"noreferrer noopener\">30743<\/a>. The converted YOLO annotation files are found in this\u00a0<a href=\"https:\/\/github.com\/changsin\/DLTrafficCounter\" target=\"_blank\" rel=\"noreferrer noopener\">git repository<\/a>.<\/li><\/ul>\n\n\n\n<hr class=\"wp-block-separator is-style-wide\"\/>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-13 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-14 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to build a custom Traffic Counting System in Deep Learning<\/p>\n","protected":false},"author":1,"featured_media":1508,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[23,71,84,377,402,138,400,403],"class_list":["post-1489","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-use-case","tag-ai-data-2","tag-blackolive","tag-data-labeling","tag-deep-learning","tag-highway-image-dataset","tag-testworks","tag-traffic-counting-system","tag-yolomodel"],"_links":{"self":[{"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/posts\/1489","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/comments?post=1489"}],"version-history":[{"count":13,"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/posts\/1489\/revisions"}],"predecessor-version":[{"id":1529,"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/posts\/1489\/revisions\/1529"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/media\/1508"}],"wp:attachment":[{"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/media?parent=1489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/categories?post=1489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.aiworkx.ai\/en\/wp-json\/wp\/v2\/tags?post=1489"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}