Browse Source

The skeleton works until the numberplate function.

refactoring
Atmadeep Arya 3 years ago
parent
commit
78a3a54f75
5 changed files with 208 additions and 40 deletions
  1. +30
    -0
      example.py
  2. +44
    -0
      example2.py
  3. +100
    -0
      skeleton.py
  4. +10
    -40
      src/trafficApp.py
  5. +24
    -0
      src/workflow.txt

+ 30
- 0
example.py View File

@@ -0,0 +1,30 @@
from threading import Thread
import time
import random
from queue import Queue

queue = Queue(10)

class ProducerThread(Thread):
def run(self):
nums = range(40)
global queue
while True:
num = random.choice(nums)
queue.put(num)
print ("Produced", num)
time.sleep(random.random())


class ConsumerThread(Thread):
def run(self):
global queue
while True:
num = queue.get()
queue.task_done()
print ("Consumed", num)
time.sleep(random.random())


ProducerThread().start()
ConsumerThread().start()

+ 44
- 0
example2.py View File

@@ -0,0 +1,44 @@
from threading import Thread
import multiprocessing as mp
import time
import random
from queue import Queue

inputQueue = mp.Queue(10)
inputQueue2 = mp.Queue(10)

class ProducerThread(Thread):
global inputQueue
def run(self):
numbers = range(40)
while True:
num = random.choice(numbers)
inputQueue.put(num)
print("\nPut",num)
time.sleep(.05)

class ConsumerProcess1(mp.Process):
global inputQueue
def run(self):
while True:
num = inputQueue.get()
print("\nGot", num)
time.sleep(.1)

class ConsumerProcess2(mp.Process):
global


if __name__ == "__main__":
print("this is example 2")
time.sleep(2)
a=ProducerThread()
b=ConsumerProcess1()
a.start()
b.start()
a.join()
b.join()


+ 100
- 0
skeleton.py View File

@@ -0,0 +1,100 @@
import os
import cv2
import argparse
import time
import random
import multiprocessing as mp
import threading as th
from queue import Queue

inputQueue = mp.Queue()
vehicleDetectionQueue = mp.Queue()
numberPlateOcrQueue = mp.Queue()
displayQueue = mp.Queue()
outputQueue = mp.Queue()
class ReadFrame(th.Thread):
def __init__(self,source) -> None:
super().__init__()
self.frameId = 1
self.stopped = False
self.grabbed = True

self.videoCaptureObject = cv2.VideoCapture(source)
print(f'Reading from source = {source}')

global inputQueue
def run(self):
while self.grabbed:
(self.grabbed, self.frame) = self.videoCaptureObject.read()
inputQueue.put((self.frame,self.frameId))
print(f"IP frame added with id {self.frameId}\n")
self.frameId+=1

class VehicleDetection(mp.Process):
global inputQueue
def run(self):
while True:
(frame,frameId) = inputQueue.get()
#inputQueue.task_done()
print(f"\n VD Got frame with ID {frameId}")
#do some processing here.
vehicleDetectionQueue.put((frame,frameId))

class NumberPlateOcr(mp.Process):
global inputQueue
global numberPlateOcrQueue
def run(self):
while True:
(frame,frameId) = vehicleDetectionQueue.get()
#inputQueue.task_done()
print(f"\n NP Got frame with ID {frameId}")
#do some processing here.
numberPlateOcrQueue.put((frame,frameId))

class DisplayFrame(mp.Process):
global numberPlateOcrQueue
global displayQueue
def run(self):
while True:
(frame,frameId) = numberPlateOcrQueue.get()
print(f'DF got frame with ID {frameId}')
#display image here with frame ID
outputQueue.put((frame,frameId))

class SaveOutput(mp.Process):
global displayQueue
#Takes all the (frame,frameId) and then sorts them and merges them in a video using some tool.


if __name__ == '__main__':
import cProfile

app_profiler = cProfile.Profile()

parser = argparse.ArgumentParser(description='BitSilica Traffic Analysis Solution')
parser.add_argument('--image', help=' Full Path to image file.')
parser.add_argument('--video', help='Full Path to video file.')
parser.add_argument('--realtime',help='Camera Connected Input')
args = parser.parse_args()
#enable profiler here.
app_profiler.enable()

readFramesThread = ReadFrame(args.video)
vehicleDetectionProcess = VehicleDetection()
numberPlateOcrProcess = NumberPlateOcr()
readFramesThread.start()
vehicleDetectionProcess.start()
numberPlateOcrProcess.start()
#disable profiler here.
app_profiler.disable()
profile_name = str('temp.prof'.format(os.path.basename(args.video)[0:-4]))
print("------------------------\nEnd of execution, dumping profile stats\n-------------------------")
app_profiler.dump_stats(profile_name)

+ 10
- 40
src/trafficApp.py View File

@@ -1,12 +1,11 @@
import argparse import argparse
import ntpath
import cv2 as cv import cv2 as cv
import numpy as np import numpy as np
from tqdm import tqdm from tqdm import tqdm
import os import os
os.environ['DISPLAY'] = ':0' os.environ['DISPLAY'] = ':0'



from config.config import PARAMS from config.config import PARAMS
from src.numberPlateRoiDetection import NumberPlateROIDetection from src.numberPlateRoiDetection import NumberPlateROIDetection
from src.objectDetection import ObjectDetection from src.objectDetection import ObjectDetection
@@ -17,7 +16,7 @@ from src.trackingManager import TrackerManager
class TrafficApp(object): class TrafficApp(object):
def __init__(self,args): def __init__(self,args):
self.args = args self.args = args
#get Object Detection Up #get Object Detection Up
self.objectDetection = ObjectDetection(debug=args.debug,target=args.target) self.objectDetection = ObjectDetection(debug=args.debug,target=args.target)
self.numberPlateDetection = NumberPlateROIDetection(args= args,algoType='NumberPlate') self.numberPlateDetection = NumberPlateROIDetection(args= args,algoType='NumberPlate')
@@ -32,8 +31,6 @@ class TrafficApp(object):


def runVideoFlow(self): def runVideoFlow(self):
frame_count = 0 frame_count = 0
successfulDetections=0

if args.video is not None: if args.video is not None:
try: try:
videoObj = cv.VideoCapture(args.video) videoObj = cv.VideoCapture(args.video)
@@ -70,11 +67,11 @@ class TrafficApp(object):
print('Frames-{},Height-{}, Width-{}'.format(totalFrames,imgH,imgW)) print('Frames-{},Height-{}, Width-{}'.format(totalFrames,imgH,imgW))


if self.args.saveoutput and (imgH > 0 and imgW > 0): if self.args.saveoutput and (imgH > 0 and imgW > 0):
outputfile = "output-{}-{}.mp4".format(ntpath.basename(args.video)[0:-4],args.jump)
self.vid_writer = cv.VideoWriter(outputfile,cv.VideoWriter_fourcc(*"MJPG"), 30,(round(imgW),round(imgH)))
self.vid_writer = cv.VideoWriter(self.args.outputfile,
cv.VideoWriter_fourcc(*"MJPG"), 30,
(round(imgW),round(imgH)))
progress_bar=tqdm(total = totalFrames) progress_bar=tqdm(total = totalFrames)
total_frame_processed = 0
# start reading frame # start reading frame
while True: while True:
grabbed, frame = videoObj.read() grabbed, frame = videoObj.read()
@@ -83,10 +80,11 @@ class TrafficApp(object):
if not grabbed: if not grabbed:
break break
frame_count +=1 frame_count +=1

#print('Frame_count-',frame_count) #print('Frame_count-',frame_count)
#Use jump argument to skip frames. #Use jump argument to skip frames.
if (frame_count % self.args.jump == 0): if (frame_count % self.args.jump == 0):
total_frame_processed+=1
# get object detection on this frame # get object detection on this frame
img_objectMarking, boxes, confidences, classids, idxs,status = self.objectDetection.run_object_detection(frame.copy(),imageH=imgH,imageW=imgW) img_objectMarking, boxes, confidences, classids, idxs,status = self.objectDetection.run_object_detection(frame.copy(),imageH=imgH,imageW=imgW)
'''Assign Trcakers''' '''Assign Trcakers'''
@@ -110,18 +108,11 @@ class TrafficApp(object):
''' Get Number plate OCR ''' ''' Get Number plate OCR '''
number_plate_ocr_dict = get_number_plate_ocr_from_rois(frame.copy(),detected_np_info, False) number_plate_ocr_dict = get_number_plate_ocr_from_rois(frame.copy(),detected_np_info, False)


if any(x > PARAMS._YOLOV3_OD_CONFIDENCE for x in confidences):
successfulDetections+=1
<<<<<<< Updated upstream

=======
>>>>>>> Stashed changes
#Display frame #Display frame
displayFrame = self.displayFrame(frame.copy(),detected_np_info,number_plate_ocr_dict,object_detect_info) displayFrame = self.displayFrame(frame.copy(),detected_np_info,number_plate_ocr_dict,object_detect_info)


winName = 'YOLOV3 Object Detection' winName = 'YOLOV3 Object Detection'
#cv.namedWindow(winName, cv.WINDOW_NORMAL)
cv.namedWindow(winName, cv.WINDOW_NORMAL)
#cv.imshow(winName, displayFrame) #cv.imshow(winName, displayFrame)
#cv.resizeWindow('objectDetection',680,420) #cv.resizeWindow('objectDetection',680,420)
if self.vid_writer: if self.vid_writer:
@@ -132,19 +123,6 @@ class TrafficApp(object):
videoObj.release() videoObj.release()
break break
progress_bar.close() progress_bar.close()
<<<<<<< Updated upstream
=======
>>>>>>> Stashed changes
with open("{}-{}-metric.txt".format(ntpath.basename(args.video)[0:-4],args.jump),"w") as f:
line = "Successful detection = {} total_frame_processed = {}".format(successfulDetections,total_frame_processed)
f.write(line)
f.close()

<<<<<<< Updated upstream

=======
>>>>>>> Stashed changes
def parseObjDetectInfo(self,object_roi_info): def parseObjDetectInfo(self,object_roi_info):
boxes, confidences, classids, idxs, status = object_roi_info boxes, confidences, classids, idxs, status = object_roi_info
#[[list of bbox ][list of conf and labels]] #[[list of bbox ][list of conf and labels]]
@@ -271,27 +249,19 @@ if __name__ == '__main__':


import cProfile, pstats import cProfile, pstats
app_profiler = cProfile.Profile() app_profiler = cProfile.Profile()
<<<<<<< Updated upstream


=======
part_files = ["{}.{}".format(i,'mp4') for i in range(1,num_processes+1)]
>>>>>>> Stashed changes
parser = argparse.ArgumentParser(description='BitSilica Traffic Analysis Solution') parser = argparse.ArgumentParser(description='BitSilica Traffic Analysis Solution')
parser.add_argument('--image', help=' Full Path to image file.') parser.add_argument('--image', help=' Full Path to image file.')
parser.add_argument('--video', help='Full Path to video file.') parser.add_argument('--video', help='Full Path to video file.')
parser.add_argument('--realtime', help='Camera Connected Input') parser.add_argument('--realtime', help='Camera Connected Input')
parser.add_argument('--target', type=str,default = 'CPU',help='Target for CNN to run') parser.add_argument('--target', type=str,default = 'CPU',help='Target for CNN to run')
parser.add_argument('--saveoutput',type=bool,default=True, help='save video or not') parser.add_argument('--saveoutput',type=bool,default=True, help='save video or not')
parser.add_argument('--outputfile',type=str,default='./result.avi', help='save video path')
parser.add_argument('--debug',type=bool,default=False, help='print time taken by function') parser.add_argument('--debug',type=bool,default=False, help='print time taken by function')
parser.add_argument('--jump',type=int,default=1,help='integer value for jumping frames') parser.add_argument('--jump',type=int,default=1,help='integer value for jumping frames')
parser.add_argument('--cores',type=int,default=1,help='enables usage of multiple cores.')
args = parser.parse_args() args = parser.parse_args()
app_profiler.enable() app_profiler.enable()
app = TrafficApp(args = args) app = TrafficApp(args = args)
app_profiler.disable() app_profiler.disable()
<<<<<<< Updated upstream
profile_name = str('{}-{}.prof'.format(ntpath.basename(args.video)[0:-4],args.jump))
=======
profile_name = str('{}-{}-{}.prof'.format(ntpath.basename(args.video)[:-4],args.jump,rgs.cores))
>>>>>>> Stashed changes
profile_name = str('profile_info-{}.prof'.format(args.jump))
app_profiler.dump_stats(profile_name) app_profiler.dump_stats(profile_name)

+ 24
- 0
src/workflow.txt View File

@@ -0,0 +1,24 @@
A general flow of the work:
(readFrames) --> [buffer] --> (vehicleDetection) --> [buffer] --> (number plate)--> (OCR) --> [buffer] --> display --> [buffer] --> save video.

.Parallelizing the pipeline
a. Start reading frames and add them in an input buffer.
b. Take the frames from input buffer and run vehicleDetection on them (2-4 processes)
c. Add the frames in an output buffer and sort them.
d. Take the frames from output buffer and then perform numberplate and ocr detection on them.
e. display the frames
f. write the frames in an output video buffer and save it.

+++++++++++++++++++++++++
1. Create a function which can read files and put them into buffer along with frame ID
2. Create the buffer which can hold the object from 1.
3. Integrate these 1.2. -- core 1 --
4. Consumer/producer for vehicle detection. -- core 1 --
5. Buffer for storing detected objets and integrate with 4
6. Consumer/Producer for numberplate and ocr
8. Add these into a buffer.
9. consumer for taking video and sorting and merging the frames.

+++++++++++++++++++++++++++++
1. >>
a. Create a class for reading frames given the path and store it in a queue.

Loading…
Cancel
Save