comparison 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
comparison
equal deleted inserted replaced
1241:ab4c72b9475c 1242:4cd8ace3552f
304 def homographyProject(self, homography): 304 def homographyProject(self, homography):
305 projected = cvutils.homographyProject(array([[self.x], [self.y]]), homography) 305 projected = cvutils.homographyProject(array([[self.x], [self.y]]), homography)
306 return Point(projected[0], projected[1]) 306 return Point(projected[0], projected[1])
307 307
308 def inRectangle(self, xmin, xmax, ymin, ymax): 308 def inRectangle(self, xmin, xmax, ymin, ymax):
309 return (xmin <= p.x <= xmax) and (ymin <= p.y <= ymax) 309 return (xmin <= self.x <= xmax) and (ymin <= self.y <= ymax)
310 310
311 def inPolygon(self, polygon): 311 def inPolygon(self, polygon):
312 '''Indicates if the point x, y is inside the polygon 312 '''Indicates if the point x, y is inside the polygon
313 (array of Nx2 coordinates of the polygon vertices) 313 (array of Nx2 coordinates of the polygon vertices)
314 314
1399 1399
1400 userTypeNames = ['unknown', 1400 userTypeNames = ['unknown',
1401 'car', 1401 'car',
1402 'pedestrian', 1402 'pedestrian',
1403 'motorcycle', 1403 'motorcycle',
1404 'bicycle', 1404 'cyclist',
1405 'bus', 1405 'bus',
1406 'truck', 1406 'truck',
1407 'automated'] 1407 'automated']
1408 1408
1409 coco2Types = {0: 2, 1: 4, 2: 1, 3: 3, 5: 5, 7: 6} 1409 coco2Types = {0: 2, 1: 4, 2: 1, 3: 3, 5: 5, 7: 6}
2079 computes HOG on this cropped image (with parameters rescaleSize, orientations, pixelsPerCell, cellsPerBlock) 2079 computes HOG on this cropped image (with parameters rescaleSize, orientations, pixelsPerCell, cellsPerBlock)
2080 and applies the SVM model on it''' 2080 and applies the SVM model on it'''
2081 croppedImg = cvutils.imageBox(img, self, instant, width, height, px, py, minNPixels) 2081 croppedImg = cvutils.imageBox(img, self, instant, width, height, px, py, minNPixels)
2082 if croppedImg is not None and len(croppedImg) > 0: 2082 if croppedImg is not None and len(croppedImg) > 0:
2083 hog = cvutils.HOG(croppedImg, rescaleSize, orientations, pixelsPerCell, cellsPerBlock, blockNorm) 2083 hog = cvutils.HOG(croppedImg, rescaleSize, orientations, pixelsPerCell, cellsPerBlock, blockNorm)
2084 self.userTypes[instant] = self.appearanceClassifier.predict(hog.reshape(1,hog.size)) 2084 self.userTypes[instant] = int(self.appearanceClassifier.predict(hog.reshape(1,hog.size)))
2085 else: 2085 else:
2086 self.userTypes[instant] = userType2Num['unknown'] 2086 self.userTypes[instant] = userType2Num['unknown']
2087 2087
2088 def classifyUserTypeYoloAtInstant(self, img, instant, width, height, px, py, minNPixels, bboxes): 2088 def classifyUserTypeYoloAtInstant(self, instant, bboxes):
2089 '''Finds the user type based on where the feature fall in detected bboxes''' 2089 '''Finds the user type based on where the feature fall at instant in detected bboxes'''
2090 userTypes = [] 2090 userTypes = []
2091 if self.hasFeatures(): 2091 if self.hasFeatures():
2092 for f in self.getFeatures(): 2092 for f in self.getFeatures():
2093 if f.existsAtInstant(frameNum): 2093 if f.existsAtInstant(instant):
2094 p = f.getPositionAtInstant(frameNum) 2094 p = f.getPositionAtInstant(instant)
2095 for box in bboxes: 2095 for box in bboxes:
2096 if box.id is not None: 2096 xyxy = box.xyxy[0].tolist()
2097 xyxy = box.xyxy[0].tolist() 2097 if p.inRectangle(xyxy[0], xyxy[2], xyxy[1], xyxy[3]):
2098 if p.inRectangle(xyxy[0], xyxy[1], xyxy[2], xyxy[3]): 2098 userTypes.append(coco2Types[int(box.cls.item())])
2099 userTypes.append(moving.coco2Types[int(box.cls.item())])
2100 if len(userTypes) > 0: 2099 if len(userTypes) > 0:
2101 pass 2100 if userType2Num['cyclist'] in userTypes:
2101 self.userTypes[instant] = userType2Num['cyclist']
2102 else:
2103 self.userTypes[instant] = utils.mostCommon(userTypes)
2102 else: 2104 else:
2103 self.userTypes[instant] = userType2Num['unknown'] 2105 self.userTypes[instant] = userType2Num['unknown']
2104 2106
2105 def classifyUserTypeHoGSVM(self, minSpeedEquiprobable = -1, speedProbabilities = None, aggregationFunc = median, maxPercentUnknown = 0.5): 2107 def classifyUserTypeHoGSVM(self, minSpeedEquiprobable = -1, speedProbabilities = None, maxPercentUnknown = 0.5):
2106 '''Agregates SVM detections in each image and returns probability 2108 '''Agregates SVM detections in each image and returns probability
2107 (proportion of instants with classification in each category) 2109 (proportion of instants with classification in each category)
2108 2110
2109 images is a dictionary of images indexed by instant 2111 images is a dictionary of images indexed by instant
2110 With default parameters, the general (ped-bike-car) classifier will be used 2112 With default parameters, the general (ped-bike-car) classifier will be used
2116 2118
2117 # if len(self.userTypes) != self.length() and images is not None: # if classification has not been done previously 2119 # if len(self.userTypes) != self.length() and images is not None: # if classification has not been done previously
2118 # for t in self.getTimeInterval(): 2120 # for t in self.getTimeInterval():
2119 # if t not in self.userTypes: 2121 # if t not in self.userTypes:
2120 # self.classifyUserTypeHoGSVMAtInstant(images[t], t, homography, width, height, px, py, minNPixels, rescaleSize, orientations, pixelsPerCell, cellsPerBlock) 2122 # self.classifyUserTypeHoGSVMAtInstant(images[t], t, homography, width, height, px, py, minNPixels, rescaleSize, orientations, pixelsPerCell, cellsPerBlock)
2123
2121 # compute P(Speed|Class) 2124 # compute P(Speed|Class)
2122 if speedProbabilities is None or self.aggregatedSpeed < minSpeedEquiprobable: # equiprobable information from speed 2125 if speedProbabilities is None or self.aggregatedSpeed < minSpeedEquiprobable: # equiprobable information from speed
2123 userTypeProbabilities = {userType2Num['car']: 1., userType2Num['pedestrian']: 1., userType2Num['bicycle']: 1.} 2126 userTypeProbabilities = {userTypeNum: 1. for userTypeNum in speedProbabilities}
2124 else: 2127 else:
2125 userTypeProbabilities = {userType2Num[userTypename]: speedProbabilities[userTypename](self.aggregatedSpeed) for userTypename in speedProbabilities} 2128 userTypeProbabilities = {userTypeNum: speedProbabilities[userTypeNum](self.aggregatedSpeed) for userTypeNum in speedProbabilities}
2126 # compute P(Class|Appearance) 2129 # compute P(Class|Appearance)
2127 nInstantsUserType = {userTypeNum: 0 for userTypeNum in userTypeProbabilities}# number of instants the object is classified as userTypename 2130 nInstantsUserType = {userTypeNum: 0 for userTypeNum in userTypeProbabilities}# number of instants the object is classified as userTypename
2128 nInstantsUserType[userType2Num['unknown']] = 0 2131 nInstantsUserType[userType2Num['unknown']] = 0
2129 for t in self.userTypes: 2132 for t in self.userTypes:
2130 nInstantsUserType[self.userTypes[t]] += 1 #nInstantsUserType.get(self.userTypes[t], 0) + 1 2133 nInstantsUserType[self.userTypes[t]] += 1 #nInstantsUserType.get(self.userTypes[t], 0) + 1
2133 for userTypeNum in userTypeProbabilities: 2136 for userTypeNum in userTypeProbabilities:
2134 userTypeProbabilities[userTypeNum] *= nInstantsUserType[userTypeNum] 2137 userTypeProbabilities[userTypeNum] *= nInstantsUserType[userTypeNum]
2135 # class is the user type that maximizes usertype probabilities 2138 # class is the user type that maximizes usertype probabilities
2136 if nInstantsUserType[userType2Num['unknown']] >= maxPercentUnknown*self.length() and (speedProbabilities is None or self.aggregatedSpeed < minSpeedEquiprobable): # if no speed information and too many unknowns 2139 if nInstantsUserType[userType2Num['unknown']] >= maxPercentUnknown*self.length() and (speedProbabilities is None or self.aggregatedSpeed < minSpeedEquiprobable): # if no speed information and too many unknowns
2137 self.setUserType(userType2Num['unknown']) 2140 self.setUserType(userType2Num['unknown'])
2138 else: 2141 else: # if too many unknowns here, probas are just speed probas
2139 self.setUserType(utils.argmaxDict(userTypeProbabilities)) 2142 self.setUserType(utils.argmaxDict(userTypeProbabilities))
2140 2143
2141 def classifyUserTypeArea(self, areas, homography): 2144 def classifyUserTypeArea(self, areas, homography):
2142 '''Classifies the object based on its location (projected to image space) 2145 '''Classifies the object based on its location (projected to image space)
2143 areas is a dictionary of matrix of the size of the image space 2146 areas is a dictionary of matrix of the size of the image space