diff trafficintelligence/moving.py @ 1242:4cd8ace3552f

major update for classification, allowing the use of neural network classification
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Wed, 07 Feb 2024 11:43:03 -0500
parents ab4c72b9475c
children 371c718e57d7
line wrap: on
line diff
--- a/trafficintelligence/moving.py	Mon Feb 05 17:06:01 2024 -0500
+++ b/trafficintelligence/moving.py	Wed Feb 07 11:43:03 2024 -0500
@@ -306,7 +306,7 @@
         return Point(projected[0], projected[1])
 
     def inRectangle(self, xmin, xmax, ymin, ymax):
-        return (xmin <= p.x <= xmax) and (ymin <= p.y <= ymax)
+        return (xmin <= self.x <= xmax) and (ymin <= self.y <= ymax)
     
     def inPolygon(self, polygon):
         '''Indicates if the point x, y is inside the polygon
@@ -1401,7 +1401,7 @@
                  'car',
                  'pedestrian',
                  'motorcycle',
-                 'bicycle',
+                 'cyclist',
                  'bus',
                  'truck',
                  'automated']
@@ -2081,28 +2081,30 @@
         croppedImg = cvutils.imageBox(img, self, instant, width, height, px, py, minNPixels)
         if croppedImg is not None and len(croppedImg) > 0:
             hog = cvutils.HOG(croppedImg, rescaleSize, orientations, pixelsPerCell, cellsPerBlock, blockNorm)
-            self.userTypes[instant] = self.appearanceClassifier.predict(hog.reshape(1,hog.size))
+            self.userTypes[instant] = int(self.appearanceClassifier.predict(hog.reshape(1,hog.size)))
         else:
             self.userTypes[instant] = userType2Num['unknown']
 
-    def classifyUserTypeYoloAtInstant(self, img, instant, width, height, px, py, minNPixels, bboxes):
-        '''Finds the user type based on where the feature fall in detected bboxes'''
+    def classifyUserTypeYoloAtInstant(self, instant, bboxes):
+        '''Finds the user type based on where the feature fall at instant in detected bboxes'''
         userTypes = []
         if self.hasFeatures():
             for f in self.getFeatures():
-                if f.existsAtInstant(frameNum):
-                    p = f.getPositionAtInstant(frameNum)
+                if f.existsAtInstant(instant):
+                    p = f.getPositionAtInstant(instant)
                     for box in bboxes:
-                        if box.id is not None:
-                            xyxy = box.xyxy[0].tolist()
-                            if p.inRectangle(xyxy[0], xyxy[1], xyxy[2], xyxy[3]):
-                                userTypes.append(moving.coco2Types[int(box.cls.item())])
+                        xyxy = box.xyxy[0].tolist()
+                        if p.inRectangle(xyxy[0], xyxy[2], xyxy[1], xyxy[3]):
+                            userTypes.append(coco2Types[int(box.cls.item())])
         if len(userTypes) > 0:
-            pass
+            if userType2Num['cyclist'] in userTypes:
+                self.userTypes[instant] = userType2Num['cyclist']
+            else:
+                self.userTypes[instant] = utils.mostCommon(userTypes)
         else:
             self.userTypes[instant] = userType2Num['unknown']
 
-    def classifyUserTypeHoGSVM(self, minSpeedEquiprobable = -1, speedProbabilities = None, aggregationFunc = median, maxPercentUnknown = 0.5):
+    def classifyUserTypeHoGSVM(self, minSpeedEquiprobable = -1, speedProbabilities = None, maxPercentUnknown = 0.5):
         '''Agregates SVM detections in each image and returns probability
         (proportion of instants with classification in each category)
 
@@ -2118,11 +2120,12 @@
         #     for t in self.getTimeInterval():
         #         if t not in self.userTypes:
         #             self.classifyUserTypeHoGSVMAtInstant(images[t], t, homography, width, height, px, py, minNPixels, rescaleSize, orientations, pixelsPerCell, cellsPerBlock)
+        
         # compute P(Speed|Class)
         if speedProbabilities is None or self.aggregatedSpeed < minSpeedEquiprobable: # equiprobable information from speed
-            userTypeProbabilities = {userType2Num['car']: 1., userType2Num['pedestrian']: 1., userType2Num['bicycle']: 1.}
+            userTypeProbabilities = {userTypeNum: 1. for userTypeNum in speedProbabilities}
         else:
-            userTypeProbabilities = {userType2Num[userTypename]: speedProbabilities[userTypename](self.aggregatedSpeed) for userTypename in speedProbabilities}
+            userTypeProbabilities = {userTypeNum: speedProbabilities[userTypeNum](self.aggregatedSpeed) for userTypeNum in speedProbabilities}
         # compute P(Class|Appearance)
         nInstantsUserType = {userTypeNum: 0 for userTypeNum in userTypeProbabilities}# number of instants the object is classified as userTypename
         nInstantsUserType[userType2Num['unknown']] = 0
@@ -2135,7 +2138,7 @@
         # class is the user type that maximizes usertype probabilities
         if nInstantsUserType[userType2Num['unknown']] >= maxPercentUnknown*self.length() and (speedProbabilities is None or self.aggregatedSpeed < minSpeedEquiprobable): # if no speed information and too many unknowns
             self.setUserType(userType2Num['unknown'])
-        else:
+        else: # if too many unknowns here, probas are just speed probas
             self.setUserType(utils.argmaxDict(userTypeProbabilities))
 
     def classifyUserTypeArea(self, areas, homography):