├── 1. YOLOv4 Prerequisites Installation └── README.MD ├── 2. Darknet and YOLOv4 Installation └── README.MD ├── 3. YOLOv4 Video and Webcam └── darknet_video_mod.py ├── 4. App 1 Social Distancing App ├── App1_Social_Distance.py └── App1_Social_Distance_base.py ├── 5. App 2 Parked Car Counting App ├── App2_Car_Detection_in_Parking_Lot.py ├── App2_Car_Detection_in_Parking_Lot_Base.py ├── Image (1).jpg ├── Image (10).jpg └── Image (8).jpg └── README.md /1. YOLOv4 Prerequisites Installation/README.MD: -------------------------------------------------------------------------------- 1 | # 1. YOLOv4 Prerequisites Installation Documentation 2 | 3 | Watch the Full Video Tutorial Here: https://youtu.be/5pYh1rFnNZs 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /2. Darknet and YOLOv4 Installation/README.MD: -------------------------------------------------------------------------------- 1 | # 1. Darknet and YOLOV4 Installation Documentation 2 | 3 | ## Step 1 4 | - Cloned repository from official Github of Alexyab https://github.com/augmentedstartups/darknet 5 | ## Step 2 6 | - Copied OpenCV ffmpeg and world dlls for 4.1.0 version(can be used for OpenCV video processing) near to darknet.exe 7 | ## Step 3 8 | - Copied cuDNN dll(for speedup neural network process) near to darknet.exe 9 | ## Step 4 10 | - Change the cuda version if you’re not using Cuda 10.0. 11 | - I’m using 10.2 so made change in two files 12 | 1) darknet.vcxproj [Line:55] 13 | 2) yolo_cpp_dll.vcxproj [Line:309] 14 | - Save it. 15 | ## Step 5 16 | Compile yolo_cpp_dll.vcxproj with updated Cuda version 17 | - Open yolo_cpp_dll.vcxproj with VS 18 | - Open VS and Select Release and x64 19 | - Right click on yolo_cpp_dll and select build 20 | - Should be 1 succeeded without fail 21 | [Optional] 22 | - If not succeeded make sure you followed upper steps properly 23 |   24 | 25 | ## Step 6 Compile darknet.sln 26 | - Open darknet.sln with VS 27 | - Set Release and x64 28 | - Right click on darknet and select properties 29 | - Make Four changes 30 | - C/C++ -> General -> Additional Include Directories: 31 | C:\OpenCV\build\install\include Click Ok and Apply 32 | If you followed my instructions then path should be same 33 | - C/C++ -> Preprocessor -> Preprocessor Definitions 34 | Remove CUDNN_HALF as Yolo v4/3 uses Tensor cores 35 | We don’t need to use it for 1080Ti 36 | [Optional] 37 | If you have GPU with Tensor Cores (nVidia Titan V / Tesla V100 / DGX-2 and later) then add CUDNN_HALF for speedup in detection 3x and training 2x. 38 | - CUDA C/C++ -> Device -> Code Generation 39 | Remove compute_75, sm_75 if you’re not using Cuda 10.0 40 | - Linker -> General 41 | Add lib from OpenCV build 42 | C:\OpenCV\build\install\x64\vc16\lib 43 | - Right click on darknet and select build 44 | - After the successfully build try to import darknet in Python from x64 directory 45 | Should be imported otherwise right click on darknet and select clean the build and try to follow upper steps properly. 46 | 47 | ## Step 7 Run Detection on Images 48 | 49 | darknet.exe detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights 50 | It’ll ask for the input path of the image 51 | 52 | ## Step 8 Run Detection on Videos 53 | 54 | darknet.exe detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights PATH_TO_THE_VIDEO 55 | 56 | 57 | -------------------------------------------------------------------------------- /3. YOLOv4 Video and Webcam/darknet_video_mod.py: -------------------------------------------------------------------------------- 1 | from ctypes import * # Import libraries 2 | import math 3 | import random 4 | import os 5 | import cv2 6 | import numpy as np 7 | import time 8 | import darknet 9 | 10 | 11 | def convertBack(x, y, w, h): 12 | xmin = int(round(x - (w / 2))) 13 | xmax = int(round(x + (w / 2))) 14 | ymin = int(round(y - (h / 2))) 15 | ymax = int(round(y + (h / 2))) 16 | return xmin, ymin, xmax, ymax 17 | 18 | 19 | def cvDrawBoxes(detections, img): 20 | # Colored labels dictionary 21 | color_dict = { 22 | 'person' : [0, 255, 255], 'bicycle': [238, 123, 158], 'car' : [24, 245, 217], 'motorbike' : [224, 119, 227], 23 | 'aeroplane' : [154, 52, 104], 'bus' : [179, 50, 247], 'train' : [180, 164, 5], 'truck' : [82, 42, 106], 24 | 'boat' : [201, 25, 52], 'traffic light' : [62, 17, 209], 'fire hydrant' : [60, 68, 169], 'stop sign' : [199, 113, 167], 25 | 'parking meter' : [19, 71, 68], 'bench' : [161, 83, 182], 'bird' : [75, 6, 145], 'cat' : [100, 64, 151], 26 | 'dog' : [156, 116, 171], 'horse' : [88, 9, 123], 'sheep' : [181, 86, 222], 'cow' : [116, 238, 87],'elephant' : [74, 90, 143], 27 | 'bear' : [249, 157, 47], 'zebra' : [26, 101, 131], 'giraffe' : [195, 130, 181], 'backpack' : [242, 52, 233], 28 | 'umbrella' : [131, 11, 189], 'handbag' : [221, 229, 176], 'tie' : [193, 56, 44], 'suitcase' : [139, 53, 137], 29 | 'frisbee' : [102, 208, 40], 'skis' : [61, 50, 7], 'snowboard' : [65, 82, 186], 'sports ball' : [65, 82, 186], 30 | 'kite' : [153, 254, 81],'baseball bat' : [233, 80, 195],'baseball glove' : [165, 179, 213],'skateboard' : [57, 65, 211], 31 | 'surfboard' : [98, 255, 164],'tennis racket' : [205, 219, 146],'bottle' : [140, 138, 172],'wine glass' : [23, 53, 119], 32 | 'cup' : [102, 215, 88],'fork' : [198, 204, 245],'knife' : [183, 132, 233],'spoon' : [14, 87, 125], 33 | 'bowl' : [221, 43, 104],'banana' : [181, 215, 6],'apple' : [16, 139, 183],'sandwich' : [150, 136, 166],'orange' : [219, 144, 1], 34 | 'broccoli' : [123, 226, 195],'carrot' : [230, 45, 209],'hot dog' : [252, 215, 56],'pizza' : [234, 170, 131], 35 | 'donut' : [36, 208, 234],'cake' : [19, 24, 2],'chair' : [115, 184, 234],'sofa' : [125, 238, 12], 36 | 'pottedplant' : [57, 226, 76],'bed' : [77, 31, 134],'diningtable' : [208, 202, 204],'toilet' : [208, 202, 204], 37 | 'tvmonitor' : [208, 202, 204],'laptop' : [159, 149, 163],'mouse' : [148, 148, 87],'remote' : [171, 107, 183], 38 | 'keyboard' : [33, 154, 135],'cell phone' : [206, 209, 108],'microwave' : [206, 209, 108],'oven' : [97, 246, 15], 39 | 'toaster' : [147, 140, 184],'sink' : [157, 58, 24],'refrigerator' : [117, 145, 137],'book' : [155, 129, 244], 40 | 'clock' : [53, 61, 6],'vase' : [145, 75, 152],'scissors' : [8, 140, 38],'teddy bear' : [37, 61, 220], 41 | 'hair drier' : [129, 12, 229],'toothbrush' : [11, 126, 158] 42 | } 43 | 44 | for detection in detections: 45 | x, y, w, h = detection[2][0],\ 46 | detection[2][1],\ 47 | detection[2][2],\ 48 | detection[2][3] 49 | name_tag = str(detection[0].decode()) 50 | for name_key, color_val in color_dict.items(): 51 | if name_key == name_tag: 52 | color = color_val 53 | xmin, ymin, xmax, ymax = convertBack( 54 | float(x), float(y), float(w), float(h)) 55 | pt1 = (xmin, ymin) 56 | pt2 = (xmax, ymax) 57 | cv2.rectangle(img, pt1, pt2, color, 1) 58 | cv2.putText(img, 59 | detection[0].decode() + 60 | " [" + str(round(detection[1] * 100, 2)) + "]", 61 | (pt1[0], pt1[1] - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, 62 | color, 2) 63 | return img 64 | 65 | 66 | netMain = None 67 | metaMain = None 68 | altNames = None 69 | 70 | 71 | def YOLO(): 72 | 73 | global metaMain, netMain, altNames 74 | configPath = "./cfg/yolov4.cfg" # Path to cfg 75 | weightPath = "./yolov4.weights" # Path to weights 76 | metaPath = "./cfg/coco.data" # Path to meta data 77 | if not os.path.exists(configPath): # Checks whether file exists otherwise return ValueError 78 | raise ValueError("Invalid config path `" + 79 | os.path.abspath(configPath)+"`") 80 | if not os.path.exists(weightPath): 81 | raise ValueError("Invalid weight path `" + 82 | os.path.abspath(weightPath)+"`") 83 | if not os.path.exists(metaPath): 84 | raise ValueError("Invalid data file path `" + 85 | os.path.abspath(metaPath)+"`") 86 | if netMain is None: # Checks the metaMain, NetMain and altNames. Loads it in script 87 | netMain = darknet.load_net_custom(configPath.encode( 88 | "ascii"), weightPath.encode("ascii"), 0, 1) # batch size = 1 89 | if metaMain is None: 90 | metaMain = darknet.load_meta(metaPath.encode("ascii")) 91 | if altNames is None: 92 | try: 93 | with open(metaPath) as metaFH: 94 | metaContents = metaFH.read() 95 | import re 96 | match = re.search("names *= *(.*)$", metaContents, 97 | re.IGNORECASE | re.MULTILINE) 98 | if match: 99 | result = match.group(1) 100 | else: 101 | result = None 102 | try: 103 | if os.path.exists(result): 104 | with open(result) as namesFH: 105 | namesList = namesFH.read().strip().split("\n") 106 | altNames = [x.strip() for x in namesList] 107 | except TypeError: 108 | pass 109 | except Exception: 110 | pass 111 | #cap = cv2.VideoCapture(0) # Uncomment to use Webcam 112 | cap = cv2.VideoCapture("test2.mp4") # Local Stored video detection - Set input video 113 | frame_width = int(cap.get(3)) # Returns the width and height of capture video 114 | frame_height = int(cap.get(4)) 115 | # Set out for video writer 116 | out = cv2.VideoWriter( # Set the Output path for video writer 117 | "./Demo/output.avi", cv2.VideoWriter_fourcc(*"MJPG"), 10.0, 118 | (frame_width, frame_height)) 119 | 120 | print("Starting the YOLO loop...") 121 | 122 | # Create an image we reuse for each detect 123 | darknet_image = darknet.make_image(frame_width, frame_height, 3) # Create image according darknet for compatibility of network 124 | while True: # Load the input frame and write output frame. 125 | prev_time = time.time() 126 | ret, frame_read = cap.read() # Capture frame and return true if frame present 127 | # For Assertion Failed Error in OpenCV 128 | if not ret: # Check if frame present otherwise he break the while loop 129 | break 130 | 131 | frame_rgb = cv2.cvtColor(frame_read, cv2.COLOR_BGR2RGB) # Convert frame into RGB from BGR and resize accordingly 132 | frame_resized = cv2.resize(frame_rgb, 133 | (frame_width, frame_height), 134 | interpolation=cv2.INTER_LINEAR) 135 | 136 | darknet.copy_image_from_bytes(darknet_image,frame_resized.tobytes()) # Copy that frame bytes to darknet_image 137 | 138 | detections = darknet.detect_image(netMain, metaMain, darknet_image, thresh=0.25) # Detection occurs at this line and return detections, for customize we can change the threshold. 139 | image = cvDrawBoxes(detections, frame_resized) # Call the function cvDrawBoxes() for colored bounding box per class 140 | image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 141 | print(1/(time.time()-prev_time)) 142 | cv2.imshow('Demo', image) # Display Image window 143 | cv2.waitKey(3) 144 | out.write(image) # Write that frame into output video 145 | cap.release() # For releasing cap and out. 146 | out.release() 147 | print(":::Video Write Completed") 148 | 149 | if __name__ == "__main__": 150 | YOLO() # Calls the main function YOLO() -------------------------------------------------------------------------------- /4. App 1 Social Distancing App/App1_Social_Distance.py: -------------------------------------------------------------------------------- 1 | #================================================================ 2 | # To learn how to Develop Advance YOLOv4 Apps - Then check out: 3 | # https://augmentedstartups.info/yolov4release 4 | #================================================================ 5 | from ctypes import * 6 | import math 7 | import random 8 | import os 9 | import cv2 10 | import numpy as np 11 | import time 12 | import darknet 13 | from itertools import combinations 14 | 15 | 16 | def is_close(p1, p2): 17 | """ 18 | #================================================================ 19 | # 1. Purpose : Calculate Euclidean Distance between two points 20 | #================================================================ 21 | :param: 22 | p1, p2 = two points for calculating Euclidean Distance 23 | 24 | :return: 25 | dst = Euclidean Distance between two 2d points 26 | """ 27 | dst = math.sqrt(p1**2 + p2**2) 28 | #=================================================================# 29 | return dst 30 | 31 | 32 | def convertBack(x, y, w, h): 33 | #================================================================ 34 | # 2.Purpose : Converts center coordinates to rectangle coordinates 35 | #================================================================ 36 | """ 37 | :param: 38 | x, y = midpoint of bbox 39 | w, h = width, height of the bbox 40 | 41 | :return: 42 | xmin, ymin, xmax, ymax 43 | """ 44 | xmin = int(round(x - (w / 2))) 45 | xmax = int(round(x + (w / 2))) 46 | ymin = int(round(y - (h / 2))) 47 | ymax = int(round(y + (h / 2))) 48 | return xmin, ymin, xmax, ymax 49 | 50 | 51 | def cvDrawBoxes(detections, img): 52 | """ 53 | :param: 54 | detections = total detections in one frame 55 | img = image from detect_image method of darknet 56 | 57 | :return: 58 | img with bbox 59 | """ 60 | #================================================================ 61 | # 3.1 Purpose : Filter out Persons class from detections and get 62 | # bounding box centroid for each person detection. 63 | #================================================================ 64 | if len(detections) > 0: # At least 1 detection in the image and check detection presence in a frame 65 | centroid_dict = dict() # Function creates a dictionary and calls it centroid_dict 66 | objectId = 0 # We inialize a variable called ObjectId and set it to 0 67 | for detection in detections: # In this if statement, we filter all the detections for persons only 68 | # Check for the only person name tag 69 | name_tag = str(detection[0].decode()) # Coco file has string of all the names 70 | if name_tag == 'person': 71 | x, y, w, h = detection[2][0],\ 72 | detection[2][1],\ 73 | detection[2][2],\ 74 | detection[2][3] # Store the center points of the detections 75 | xmin, ymin, xmax, ymax = convertBack(float(x), float(y), float(w), float(h)) # Convert from center coordinates to rectangular coordinates, We use floats to ensure the precision of the BBox 76 | # Append center point of bbox for persons detected. 77 | centroid_dict[objectId] = (int(x), int(y), xmin, ymin, xmax, ymax) # Create dictionary of tuple with 'objectId' as the index center points and bbox 78 | objectId += 1 #Increment the index for each detection 79 | #=================================================================# 80 | 81 | #================================================================= 82 | # 3.2 Purpose : Determine which person bbox are close to each other 83 | #================================================================= 84 | red_zone_list = [] # List containing which Object id is in under threshold distance condition. 85 | red_line_list = [] 86 | for (id1, p1), (id2, p2) in combinations(centroid_dict.items(), 2): # Get all the combinations of close detections, #List of multiple items - id1 1, points 2, 1,3 87 | dx, dy = p1[0] - p2[0], p1[1] - p2[1] # Check the difference between centroid x: 0, y :1 88 | distance = is_close(dx, dy) # Calculates the Euclidean distance 89 | if distance < 75.0: # Set our social distance threshold - If they meet this condition then.. 90 | if id1 not in red_zone_list: 91 | red_zone_list.append(id1) # Add Id to a list 92 | red_line_list.append(p1[0:2]) # Add points to the list 93 | if id2 not in red_zone_list: 94 | red_zone_list.append(id2) # Same for the second id 95 | red_line_list.append(p2[0:2]) 96 | 97 | for idx, box in centroid_dict.items(): # dict (1(key):red(value), 2 blue) idx - key box - value 98 | if idx in red_zone_list: # if id is in red zone list 99 | cv2.rectangle(img, (box[2], box[3]), (box[4], box[5]), (255, 0, 0), 2) # Create Red bounding boxes #starting point, ending point size of 2 100 | else: 101 | cv2.rectangle(img, (box[2], box[3]), (box[4], box[5]), (0, 255, 0), 2) # Create Green bounding boxes 102 | #=================================================================# 103 | 104 | #================================================================= 105 | # 3.3 Purpose : Display Risk Analytics and Show Risk Indicators 106 | #================================================================= 107 | text = "People at Risk: %s" % str(len(red_zone_list)) # Count People at Risk 108 | location = (10,25) # Set the location of the displayed text 109 | cv2.putText(img, text, location, cv2.FONT_HERSHEY_SIMPLEX, 1, (246,86,86), 2, cv2.LINE_AA) # Display Text 110 | 111 | for check in range(0, len(red_line_list)-1): # Draw line between nearby bboxes iterate through redlist items 112 | start_point = red_line_list[check] 113 | end_point = red_line_list[check+1] 114 | check_line_x = abs(end_point[0] - start_point[0]) # Calculate the line coordinates for x 115 | check_line_y = abs(end_point[1] - start_point[1]) # Calculate the line coordinates for y 116 | if (check_line_x < 75) and (check_line_y < 25): # If both are We check that the lines are below our threshold distance. 117 | cv2.line(img, start_point, end_point, (255, 0, 0), 2) # Only above the threshold lines are displayed. 118 | #=================================================================# 119 | return img 120 | 121 | 122 | netMain = None 123 | metaMain = None 124 | altNames = None 125 | 126 | 127 | def YOLO(): 128 | """ 129 | Perform Object detection 130 | """ 131 | global metaMain, netMain, altNames 132 | configPath = "./cfg/yolov4.cfg" 133 | weightPath = "./yolov4.weights" 134 | metaPath = "./cfg/coco.data" 135 | if not os.path.exists(configPath): 136 | raise ValueError("Invalid config path `" + 137 | os.path.abspath(configPath)+"`") 138 | if not os.path.exists(weightPath): 139 | raise ValueError("Invalid weight path `" + 140 | os.path.abspath(weightPath)+"`") 141 | if not os.path.exists(metaPath): 142 | raise ValueError("Invalid data file path `" + 143 | os.path.abspath(metaPath)+"`") 144 | if netMain is None: 145 | netMain = darknet.load_net_custom(configPath.encode( 146 | "ascii"), weightPath.encode("ascii"), 0, 1) # batch size = 1 147 | if metaMain is None: 148 | metaMain = darknet.load_meta(metaPath.encode("ascii")) 149 | if altNames is None: 150 | try: 151 | with open(metaPath) as metaFH: 152 | metaContents = metaFH.read() 153 | import re 154 | match = re.search("names *= *(.*)$", metaContents, 155 | re.IGNORECASE | re.MULTILINE) 156 | if match: 157 | result = match.group(1) 158 | else: 159 | result = None 160 | try: 161 | if os.path.exists(result): 162 | with open(result) as namesFH: 163 | namesList = namesFH.read().strip().split("\n") 164 | altNames = [x.strip() for x in namesList] 165 | except TypeError: 166 | pass 167 | except Exception: 168 | pass 169 | #cap = cv2.VideoCapture(0) 170 | cap = cv2.VideoCapture("./Input/test5.mp4") 171 | frame_width = int(cap.get(3)) 172 | frame_height = int(cap.get(4)) 173 | new_height, new_width = frame_height // 2, frame_width // 2 174 | # print("Video Reolution: ",(width, height)) 175 | 176 | out = cv2.VideoWriter( 177 | "./Demo/test5_output.avi", cv2.VideoWriter_fourcc(*"MJPG"), 10.0, 178 | (new_width, new_height)) 179 | 180 | # print("Starting the YOLO loop...") 181 | 182 | # Create an image we reuse for each detect 183 | darknet_image = darknet.make_image(new_width, new_height, 3) 184 | 185 | while True: 186 | prev_time = time.time() 187 | ret, frame_read = cap.read() 188 | # Check if frame present :: 'ret' returns True if frame present, otherwise break the loop. 189 | if not ret: 190 | break 191 | 192 | frame_rgb = cv2.cvtColor(frame_read, cv2.COLOR_BGR2RGB) 193 | frame_resized = cv2.resize(frame_rgb, 194 | (new_width, new_height), 195 | interpolation=cv2.INTER_LINEAR) 196 | 197 | darknet.copy_image_from_bytes(darknet_image,frame_resized.tobytes()) 198 | 199 | detections = darknet.detect_image(netMain, metaMain, darknet_image, thresh=0.25) 200 | image = cvDrawBoxes(detections, frame_resized) 201 | image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 202 | print(1/(time.time()-prev_time)) 203 | cv2.imshow('Demo', image) 204 | cv2.waitKey(3) 205 | out.write(image) 206 | 207 | cap.release() 208 | out.release() 209 | print(":::Video Write Completed") 210 | 211 | if __name__ == "__main__": 212 | YOLO() 213 | -------------------------------------------------------------------------------- /4. App 1 Social Distancing App/App1_Social_Distance_base.py: -------------------------------------------------------------------------------- 1 | #================================================================ 2 | # To learn how to Develop Advance YOLOv4 Apps - Then check out: 3 | # https://augmentedstartups.info/yolov4release 4 | #================================================================ 5 | from ctypes import * 6 | import math 7 | import random 8 | import os 9 | import cv2 10 | import numpy as np 11 | import time 12 | import darknet 13 | from itertools import combinations 14 | 15 | 16 | def is_close(p1, p2): 17 | """ 18 | #================================================================ 19 | # 1. Purpose : Calculate Euclidean Distance between two points 20 | #================================================================ 21 | :param: 22 | p1, p2 = two points for calculating Euclidean Distance 23 | 24 | :return: 25 | dst = Euclidean Distance between two 2d points 26 | """ 27 | 28 | #=================================================================# 29 | return dst 30 | 31 | 32 | def convertBack(x, y, w, h): 33 | #================================================================ 34 | # 2.Purpose : Converts center coordinates to rectangle coordinates 35 | #================================================================ 36 | """ 37 | :param: 38 | x, y = midpoint of bbox 39 | w, h = width, height of the bbox 40 | 41 | :return: 42 | xmin, ymin, xmax, ymax 43 | """ 44 | xmin = int(round(x - (w / 2))) 45 | xmax = int(round(x + (w / 2))) 46 | ymin = int(round(y - (h / 2))) 47 | ymax = int(round(y + (h / 2))) 48 | return xmin, ymin, xmax, ymax 49 | 50 | 51 | def cvDrawBoxes(detections, img): 52 | """ 53 | :param: 54 | detections = total detections in one frame 55 | img = image from detect_image method of darknet 56 | 57 | :return: 58 | img with bbox 59 | """ 60 | #================================================================ 61 | # 3.1 Purpose : Filter out Persons class from detections and get 62 | # bounding box centroid for each person detection. 63 | #================================================================ 64 | 65 | #=================================================================# 66 | 67 | #================================================================= 68 | # 3.2 Purpose : Determine which person bbox are close to each other 69 | #================================================================= 70 | 71 | #=================================================================# 72 | 73 | #================================================================= 74 | # 3.3 Purpose : Display Risk Analytics and Show Risk Indicators 75 | #================================================================= 76 | 77 | #=================================================================# 78 | return img 79 | 80 | 81 | netMain = None 82 | metaMain = None 83 | altNames = None 84 | 85 | 86 | def YOLO(): 87 | """ 88 | Perform Object detection 89 | """ 90 | global metaMain, netMain, altNames 91 | configPath = "./cfg/yolov4.cfg" 92 | weightPath = "./yolov4.weights" 93 | metaPath = "./cfg/coco.data" 94 | if not os.path.exists(configPath): 95 | raise ValueError("Invalid config path `" + 96 | os.path.abspath(configPath)+"`") 97 | if not os.path.exists(weightPath): 98 | raise ValueError("Invalid weight path `" + 99 | os.path.abspath(weightPath)+"`") 100 | if not os.path.exists(metaPath): 101 | raise ValueError("Invalid data file path `" + 102 | os.path.abspath(metaPath)+"`") 103 | if netMain is None: 104 | netMain = darknet.load_net_custom(configPath.encode( 105 | "ascii"), weightPath.encode("ascii"), 0, 1) # batch size = 1 106 | if metaMain is None: 107 | metaMain = darknet.load_meta(metaPath.encode("ascii")) 108 | if altNames is None: 109 | try: 110 | with open(metaPath) as metaFH: 111 | metaContents = metaFH.read() 112 | import re 113 | match = re.search("names *= *(.*)$", metaContents, 114 | re.IGNORECASE | re.MULTILINE) 115 | if match: 116 | result = match.group(1) 117 | else: 118 | result = None 119 | try: 120 | if os.path.exists(result): 121 | with open(result) as namesFH: 122 | namesList = namesFH.read().strip().split("\n") 123 | altNames = [x.strip() for x in namesList] 124 | except TypeError: 125 | pass 126 | except Exception: 127 | pass 128 | #cap = cv2.VideoCapture(0) 129 | cap = cv2.VideoCapture("./Input/test5.mp4") # <----- Replace with your video directory 130 | frame_width = int(cap.get(3)) 131 | frame_height = int(cap.get(4)) 132 | new_height, new_width = frame_height // 2, frame_width // 2 133 | # print("Video Reolution: ",(width, height)) 134 | 135 | out = cv2.VideoWriter( 136 | "./Demo/test5_output.avi", cv2.VideoWriter_fourcc(*"MJPG"), 10.0, # <----- Replace with your output directory 137 | (new_width, new_height)) 138 | 139 | # print("Starting the YOLO loop...") 140 | 141 | # Create an image we reuse for each detect 142 | darknet_image = darknet.make_image(new_width, new_height, 3) 143 | 144 | while True: 145 | prev_time = time.time() 146 | ret, frame_read = cap.read() 147 | # Check if frame present :: 'ret' returns True if frame present, otherwise break the loop. 148 | if not ret: 149 | break 150 | 151 | frame_rgb = cv2.cvtColor(frame_read, cv2.COLOR_BGR2RGB) 152 | frame_resized = cv2.resize(frame_rgb, 153 | (new_width, new_height), 154 | interpolation=cv2.INTER_LINEAR) 155 | 156 | darknet.copy_image_from_bytes(darknet_image,frame_resized.tobytes()) 157 | 158 | detections = darknet.detect_image(netMain, metaMain, darknet_image, thresh=0.25) 159 | image = cvDrawBoxes(detections, frame_resized) 160 | image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 161 | print(1/(time.time()-prev_time)) 162 | cv2.imshow('Demo', image) 163 | cv2.waitKey(3) 164 | out.write(image) 165 | 166 | cap.release() 167 | out.release() 168 | print(":::Video Write Completed") 169 | 170 | if __name__ == "__main__": 171 | YOLO() -------------------------------------------------------------------------------- /5. App 2 Parked Car Counting App/App2_Car_Detection_in_Parking_Lot.py: -------------------------------------------------------------------------------- 1 | #================================================================ 2 | # To learn how to Develop Advance YOLOv4 Apps - Then check out: 3 | # https://augmentedstartups.info/yolov4release 4 | #================================================================ 5 | from ctypes import * 6 | import os 7 | import cv2 8 | import darknet 9 | import glob 10 | 11 | def convertBack(x, y, w, h): # Convert from center coordinates to bounding box coordinates 12 | xmin = int(round(x - (w / 2))) 13 | xmax = int(round(x + (w / 2))) 14 | ymin = int(round(y - (h / 2))) 15 | ymax = int(round(y + (h / 2))) 16 | return xmin, ymin, xmax, ymax 17 | 18 | 19 | def cvDrawBoxes(detections, img): 20 | #================================================================ 21 | # 1. Purpose : Vehicle Counting 22 | #================================================================ 23 | if len(detections) > 0: # If there are any detections 24 | car_detection = 0 25 | for detection in detections: # For each detection 26 | name_tag = detection[0].decode() # Decode list of classes 27 | if name_tag == 'car': # Filter detections for car class 28 | x, y, w, h = detection[2][0],\ 29 | detection[2][1],\ 30 | detection[2][2],\ 31 | detection[2][3] # Obtain the detection coordinates 32 | xmin, ymin, xmax, ymax = convertBack( 33 | float(x), float(y), float(w), float(h)) # Convert to bounding box coordinates 34 | pt1 = (xmin, ymin) # Format Coordinates for Point 1 and 2 35 | pt2 = (xmax, ymax) 36 | cv2.rectangle(img, pt1, pt2, (0, 255, 0), 1) # Draw our rectangles 37 | car_detection += 1 # Increment to the next detected car 38 | cv2.putText(img, 39 | "Total cars %s" % str(car_detection), (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 1, 40 | [0, 255, 50], 2) # Place text to display the car count 41 | return img # Return Image with detections 42 | #=================================================================# 43 | 44 | 45 | netMain = None 46 | metaMain = None 47 | altNames = None 48 | 49 | 50 | def YOLO(image_list): 51 | 52 | global metaMain, netMain, altNames 53 | configPath = "./cfg/yolov4.cfg" 54 | weightPath = "./yolov4.weights" 55 | metaPath = "./cfg/coco.data" 56 | if not os.path.exists(configPath): 57 | raise ValueError("Invalid config path `" + 58 | os.path.abspath(configPath)+"`") 59 | if not os.path.exists(weightPath): 60 | raise ValueError("Invalid weight path `" + 61 | os.path.abspath(weightPath)+"`") 62 | if not os.path.exists(metaPath): 63 | raise ValueError("Invalid data file path `" + 64 | os.path.abspath(metaPath)+"`") 65 | if netMain is None: 66 | netMain = darknet.load_net_custom(configPath.encode( 67 | "ascii"), weightPath.encode("ascii"), 0, 1) # batch size = 1 68 | if metaMain is None: 69 | metaMain = darknet.load_meta(metaPath.encode("ascii")) 70 | if altNames is None: 71 | try: 72 | with open(metaPath) as metaFH: 73 | metaContents = metaFH.read() 74 | import re 75 | match = re.search("names *= *(.*)$", metaContents, 76 | re.IGNORECASE | re.MULTILINE) 77 | if match: 78 | result = match.group(1) 79 | else: 80 | result = None 81 | try: 82 | if os.path.exists(result): 83 | with open(result) as namesFH: 84 | namesList = namesFH.read().strip().split("\n") 85 | altNames = [x.strip() for x in namesList] 86 | except TypeError: 87 | pass 88 | except Exception: 89 | pass 90 | i = 0 91 | while True: 92 | image = cv2.imread(image_list[i]) 93 | width = image.shape[1] 94 | height = image.shape[0] 95 | 96 | # Create an image we reuse for each detect 97 | darknet_image = darknet.make_image(width, height, 3) 98 | 99 | image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 100 | image_rgb = cv2.resize(image_rgb, 101 | (width, height), 102 | interpolation=cv2.INTER_LINEAR) 103 | 104 | darknet.copy_image_from_bytes(darknet_image, image_rgb.tobytes()) 105 | 106 | detections = darknet.detect_image(netMain, metaMain, darknet_image, thresh=0.25) 107 | image = cvDrawBoxes(detections, image_rgb) 108 | image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 109 | cv2.imshow('Output', image) 110 | cv2.waitKey(0) 111 | i += 1 112 | cv2.destroyAllWindows() 113 | 114 | if __name__ == "__main__": 115 | #================================================================ 116 | # 2. Purpose : Get the list of Input Image Files 117 | #================================================================ 118 | image_path = "D:\YOLOv4\darknet-master\Input\\" # Directory of the image folder 119 | image_list = glob.glob(image_path + "*.jpg") # Get list of Images 120 | print(image_list) 121 | #=================================================================# 122 | YOLO(image_list) 123 | -------------------------------------------------------------------------------- /5. App 2 Parked Car Counting App/App2_Car_Detection_in_Parking_Lot_Base.py: -------------------------------------------------------------------------------- 1 | #================================================================ 2 | # To learn how to Develop Advance YOLOv4 Apps - Then check out: 3 | # https://augmentedstartups.info/yolov4release 4 | #================================================================ 5 | from ctypes import * 6 | import os 7 | import cv2 8 | import darknet 9 | import glob 10 | 11 | def convertBack(x, y, w, h): # Convert from center coordinates to bounding box coordinates 12 | xmin = int(round(x - (w / 2))) 13 | xmax = int(round(x + (w / 2))) 14 | ymin = int(round(y - (h / 2))) 15 | ymax = int(round(y + (h / 2))) 16 | return xmin, ymin, xmax, ymax 17 | 18 | 19 | def cvDrawBoxes(detections, img): 20 | #================================================================ 21 | # 1. Purpose : Vehicle Counting 22 | #================================================================ 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | return img # Return Image with detections 35 | #=================================================================# 36 | 37 | 38 | netMain = None 39 | metaMain = None 40 | altNames = None 41 | 42 | 43 | def YOLO(image_list): 44 | 45 | global metaMain, netMain, altNames 46 | configPath = "./cfg/yolov4.cfg" 47 | weightPath = "./yolov4.weights" 48 | metaPath = "./cfg/coco.data" 49 | if not os.path.exists(configPath): 50 | raise ValueError("Invalid config path `" + 51 | os.path.abspath(configPath)+"`") 52 | if not os.path.exists(weightPath): 53 | raise ValueError("Invalid weight path `" + 54 | os.path.abspath(weightPath)+"`") 55 | if not os.path.exists(metaPath): 56 | raise ValueError("Invalid data file path `" + 57 | os.path.abspath(metaPath)+"`") 58 | if netMain is None: 59 | netMain = darknet.load_net_custom(configPath.encode( 60 | "ascii"), weightPath.encode("ascii"), 0, 1) # batch size = 1 61 | if metaMain is None: 62 | metaMain = darknet.load_meta(metaPath.encode("ascii")) 63 | if altNames is None: 64 | try: 65 | with open(metaPath) as metaFH: 66 | metaContents = metaFH.read() 67 | import re 68 | match = re.search("names *= *(.*)$", metaContents, 69 | re.IGNORECASE | re.MULTILINE) 70 | if match: 71 | result = match.group(1) 72 | else: 73 | result = None 74 | try: 75 | if os.path.exists(result): 76 | with open(result) as namesFH: 77 | namesList = namesFH.read().strip().split("\n") 78 | altNames = [x.strip() for x in namesList] 79 | except TypeError: 80 | pass 81 | except Exception: 82 | pass 83 | i = 0 84 | while True: 85 | image = cv2.imread(image_list[i]) 86 | width = image.shape[1] 87 | height = image.shape[0] 88 | 89 | # Create an image we reuse for each detect 90 | darknet_image = darknet.make_image(width, height, 3) 91 | 92 | image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 93 | image_rgb = cv2.resize(image_rgb, 94 | (width, height), 95 | interpolation=cv2.INTER_LINEAR) 96 | 97 | darknet.copy_image_from_bytes(darknet_image, image_rgb.tobytes()) 98 | 99 | detections = darknet.detect_image(netMain, metaMain, darknet_image, thresh=0.25) 100 | image = cvDrawBoxes(detections, image_rgb) 101 | image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 102 | cv2.imshow('Output', image) 103 | cv2.waitKey(0) 104 | i += 1 105 | cv2.destroyAllWindows() 106 | 107 | if __name__ == "__main__": 108 | #================================================================ 109 | # 2. Purpose : Get the list of Input Image Files 110 | #================================================================ 111 | 112 | 113 | 114 | #=================================================================# 115 | YOLO(image_list) 116 | -------------------------------------------------------------------------------- /5. App 2 Parked Car Counting App/Image (1).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/augmentedstartups/YOLOv4-Tutorials/f06836f7733ac79794957c990d3b2a7aef80b33a/5. App 2 Parked Car Counting App/Image (1).jpg -------------------------------------------------------------------------------- /5. App 2 Parked Car Counting App/Image (10).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/augmentedstartups/YOLOv4-Tutorials/f06836f7733ac79794957c990d3b2a7aef80b33a/5. App 2 Parked Car Counting App/Image (10).jpg -------------------------------------------------------------------------------- /5. App 2 Parked Car Counting App/Image (8).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/augmentedstartups/YOLOv4-Tutorials/f06836f7733ac79794957c990d3b2a7aef80b33a/5. App 2 Parked Car Counting App/Image (8).jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YOLOv4-Tutorials 2 | This video tutorial series shows you how to infer and train your own custom YOLOv4 models, Step-by-step 3 | --------------------------------------------------------------------------------