Mercurial > hg > nsaunier > 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 |
