Mercurial Hosting > traffic-intelligence
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 |