├── Input └── 02-1.avi ├── README.md ├── Results ├── output_camshift.txt ├── output_kalman.txt ├── output_of.txt └── output_particle.txt └── Source └── detection_tracking.py /Input/02-1.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shreyasbhatia09/Face-Detection-and-Tracking/a3f09bcee76f15c8ed8b103a45b3cedf7511f075/Input/02-1.avi -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Face-Detection-and-Tracking 2 | Face Detection and tracking using 3 | 1. CamShift 4 | 2. Kalman Filter 5 | 3. Optical Flow 6 | 7 | Implemented using opencv and python 8 | 9 | Special thanks to Professor Roy Shilkrot for providing the skeleton code. 10 | -------------------------------------------------------------------------------- /Results/output_camshift.txt: -------------------------------------------------------------------------------- 1 | 0,92,67 2 | 1,85,70 3 | 2,86,72 4 | 3,85,71 5 | 4,86,71 6 | 5,85,72 7 | 6,85,71 8 | 7,85,71 9 | 8,85,71 10 | 9,86,69 11 | 10,86,70 12 | 11,86,70 13 | 12,86,70 14 | 13,87,69 15 | 14,87,67 16 | 15,87,68 17 | 16,86,67 18 | 17,88,64 19 | 18,88,65 20 | 19,88,68 21 | 20,89,67 22 | 21,89,66 23 | 22,90,64 24 | 23,92,63 25 | 24,90,65 26 | 25,92,63 27 | 26,92,64 28 | 27,93,63 29 | 28,94,59 30 | 29,93,60 31 | 30,94,60 32 | 31,93,59 33 | 32,94,60 34 | 33,94,61 35 | 34,94,60 36 | 35,94,59 37 | 36,96,60 38 | 37,94,61 39 | 38,95,60 40 | 39,93,61 41 | 40,93,62 42 | 41,91,63 43 | 42,90,64 44 | 43,87,63 45 | 44,85,67 46 | 45,81,66 47 | 46,78,67 48 | 47,76,67 49 | 48,73,68 50 | 49,71,70 51 | 50,70,72 52 | 51,67,73 53 | 52,65,74 54 | 53,63,74 55 | 54,62,76 56 | 55,62,76 57 | 56,62,75 58 | 57,60,75 59 | 58,63,77 60 | 59,62,78 61 | 60,63,76 62 | 61,63,75 63 | 62,65,77 64 | 63,65,77 65 | 64,65,77 66 | 65,66,75 67 | 66,66,74 68 | 67,67,75 69 | 68,67,75 70 | 69,68,75 71 | 70,69,74 72 | 71,67,73 73 | 72,68,72 74 | 73,67,69 75 | 74,69,67 76 | 75,69,66 77 | 76,70,64 78 | 77,71,62 79 | 78,71,61 80 | 79,71,61 81 | 80,76,61 82 | 81,77,60 83 | 82,78,60 84 | 83,80,58 85 | 84,86,60 86 | 85,88,59 87 | 86,93,59 88 | 87,93,56 89 | 88,98,57 90 | 89,99,59 91 | 90,104,57 92 | 91,106,58 93 | 92,110,58 94 | 93,110,55 95 | 94,111,55 96 | 95,112,55 97 | 96,111,55 98 | 97,110,56 99 | 98,110,55 100 | 99,109,60 101 | 100,105,62 102 | 101,102,62 103 | 102,101,61 104 | 103,96,64 105 | 104,94,61 106 | 105,91,63 107 | 106,88,64 108 | 107,86,63 109 | 108,84,63 110 | 109,83,62 111 | 110,81,62 112 | 111,80,61 113 | 112,78,61 114 | 113,78,60 115 | 114,77,61 116 | 115,77,60 117 | 116,76,61 118 | 117,76,59 119 | 118,77,60 120 | 119,77,60 121 | 120,77,59 122 | 121,76,60 123 | 122,76,60 124 | 123,77,61 125 | 124,76,60 126 | 125,77,60 127 | 126,76,59 128 | 127,76,57 129 | 128,75,58 130 | 129,75,57 131 | 130,76,59 132 | 131,76,57 133 | 132,75,58 134 | 133,75,59 135 | 134,75,57 136 | 135,75,55 137 | 136,75,56 138 | 137,75,57 139 | 138,77,58 140 | 139,78,59 141 | 140,79,58 142 | 141,79,58 143 | 142,81,56 144 | 143,82,58 145 | 144,82,58 146 | 145,82,57 147 | 146,82,57 148 | 147,81,56 149 | 148,83,56 150 | 149,83,57 151 | 150,83,56 152 | 151,83,56 153 | 152,82,56 154 | 153,83,55 155 | 154,83,56 156 | 155,82,58 157 | 156,82,56 158 | 157,83,57 159 | 158,83,57 160 | 159,83,58 161 | 160,82,57 162 | 161,83,61 163 | 162,83,60 164 | 163,82,59 165 | 164,83,59 166 | 165,84,59 167 | 166,84,61 168 | 167,84,61 169 | 168,85,61 170 | 169,84,60 171 | 170,85,61 172 | 171,84,63 173 | 172,85,64 174 | 173,86,64 175 | 174,87,65 176 | 175,87,66 177 | 176,87,65 178 | 177,86,66 179 | 178,87,67 180 | 179,87,66 181 | 180,87,65 182 | 181,87,64 183 | 182,87,67 184 | 183,89,65 185 | 184,89,66 186 | 185,91,68 187 | 186,92,68 188 | 187,93,70 189 | 188,94,71 190 | 189,95,72 191 | 190,99,73 192 | 191,99,75 193 | 192,102,76 194 | 193,103,74 195 | 194,104,77 196 | 195,107,78 197 | 196,107,78 198 | 197,109,81 199 | 198,110,83 200 | 199,112,83 201 | 200,115,85 202 | 201,116,84 203 | 202,118,85 204 | 203,119,84 205 | 204,119,84 206 | 205,121,82 207 | 206,122,80 208 | 207,121,78 209 | 208,121,76 210 | 209,120,75 211 | 210,117,73 212 | 211,113,68 213 | 212,107,66 214 | 213,101,65 215 | 214,96,65 216 | 215,90,63 217 | 216,85,62 218 | 217,80,61 219 | 218,75,62 220 | 219,73,61 221 | 220,68,61 222 | 221,66,60 223 | 222,64,63 224 | 223,61,62 225 | 224,60,63 226 | 225,59,63 227 | 226,59,63 228 | 227,59,63 229 | 228,60,66 230 | 229,61,66 231 | 230,64,66 232 | 231,67,69 233 | 232,70,68 234 | 233,74,70 235 | 234,76,70 236 | 235,79,73 237 | 236,82,72 238 | 237,85,72 239 | 238,87,72 240 | 239,89,73 241 | 240,91,73 242 | 241,93,73 243 | 242,94,73 244 | 243,96,73 245 | 244,93,74 246 | 245,94,75 247 | 246,95,73 248 | 247,93,73 249 | 248,94,71 250 | 249,93,69 251 | 250,90,69 252 | 251,89,69 253 | 252,87,67 254 | 253,87,68 255 | 254,86,69 256 | 255,84,67 257 | 256,85,67 -------------------------------------------------------------------------------- /Results/output_kalman.txt: -------------------------------------------------------------------------------- 1 | 0,92,67 2 | 1,91,67 3 | 2,91,68 4 | 3,90,68 5 | 4,92,66 6 | 5,93,65 7 | 6,93,66 8 | 7,93,66 9 | 8,93,65 10 | 9,92,66 11 | 10,92,65 12 | 11,92,65 13 | 12,92,64 14 | 13,92,64 15 | 14,92,64 16 | 15,92,62 17 | 16,92,61 18 | 17,93,61 19 | 18,93,61 20 | 19,94,60 21 | 20,94,59 22 | 21,94,58 23 | 22,94,57 24 | 23,95,57 25 | 24,96,56 26 | 25,96,55 27 | 26,97,55 28 | 27,98,54 29 | 28,98,53 30 | 29,99,53 31 | 30,99,52 32 | 31,99,52 33 | 32,100,51 34 | 33,100,51 35 | 34,101,50 36 | 35,101,51 37 | 36,101,51 38 | 37,102,50 39 | 38,102,50 40 | 39,102,51 41 | 40,102,50 42 | 41,101,51 43 | 42,100,51 44 | 43,98,52 45 | 44,98,51 46 | 45,95,53 47 | 46,93,54 48 | 47,90,55 49 | 48,87,56 50 | 49,87,56 51 | 50,86,56 52 | 51,86,56 53 | 52,85,56 54 | 53,79,61 55 | 54,73,62 56 | 55,68,64 57 | 56,66,64 58 | 57,65,65 59 | 58,64,65 60 | 59,63,65 61 | 60,61,66 62 | 61,60,66 63 | 62,59,67 64 | 63,58,67 65 | 64,56,67 66 | 65,55,68 67 | 66,54,68 68 | 67,59,69 69 | 68,61,70 70 | 69,61,70 71 | 70,60,71 72 | 71,61,69 73 | 72,62,68 74 | 73,62,68 75 | 74,63,67 76 | 75,64,65 77 | 76,65,63 78 | 77,66,61 79 | 78,67,59 80 | 79,69,58 81 | 80,71,56 82 | 81,73,55 83 | 82,75,53 84 | 83,78,52 85 | 84,81,50 86 | 85,84,49 87 | 86,87,48 88 | 87,90,47 89 | 88,93,46 90 | 89,97,46 91 | 90,98,45 92 | 91,99,45 93 | 92,103,45 94 | 93,107,45 95 | 94,109,44 96 | 95,110,43 97 | 96,112,43 98 | 97,113,42 99 | 98,115,42 100 | 99,115,44 101 | 100,115,45 102 | 101,115,46 103 | 102,114,47 104 | 103,113,48 105 | 104,114,48 106 | 105,111,49 107 | 106,108,50 108 | 107,106,51 109 | 108,103,51 110 | 109,100,51 111 | 110,98,51 112 | 111,95,51 113 | 112,93,50 114 | 113,90,50 115 | 114,88,50 116 | 115,87,50 117 | 116,85,49 118 | 117,83,49 119 | 118,82,49 120 | 119,80,48 121 | 120,79,48 122 | 121,78,48 123 | 122,77,48 124 | 123,77,48 125 | 124,76,48 126 | 125,76,48 127 | 126,75,48 128 | 127,75,48 129 | 128,74,48 130 | 129,74,48 131 | 130,74,48 132 | 131,74,48 133 | 132,73,48 134 | 133,73,48 135 | 134,73,48 136 | 135,73,48 137 | 136,73,48 138 | 137,73,48 139 | 138,73,48 140 | 139,73,48 141 | 140,74,48 142 | 141,74,48 143 | 142,75,48 144 | 143,75,48 145 | 144,76,48 146 | 145,76,48 147 | 146,78,48 148 | 147,79,48 149 | 148,80,48 150 | 149,80,48 151 | 150,81,48 152 | 151,82,48 153 | 152,82,48 154 | 153,83,48 155 | 154,83,48 156 | 155,83,48 157 | 156,84,48 158 | 157,84,48 159 | 158,84,48 160 | 159,84,48 161 | 160,84,48 162 | 161,85,48 163 | 162,85,48 164 | 163,85,48 165 | 164,85,49 166 | 165,85,49 167 | 166,85,50 168 | 167,85,51 169 | 168,86,51 170 | 169,86,52 171 | 170,86,53 172 | 171,86,54 173 | 172,87,55 174 | 173,87,55 175 | 174,87,55 176 | 175,87,57 177 | 176,88,58 178 | 177,88,58 179 | 178,88,59 180 | 179,89,59 181 | 180,89,60 182 | 181,89,60 183 | 182,90,60 184 | 183,91,60 185 | 184,91,60 186 | 185,91,61 187 | 186,93,61 188 | 187,93,61 189 | 188,93,62 190 | 189,94,62 191 | 190,97,63 192 | 191,97,64 193 | 192,101,66 194 | 193,104,67 195 | 194,104,68 196 | 195,105,68 197 | 196,106,69 198 | 197,107,69 199 | 198,107,70 200 | 199,108,70 201 | 200,109,71 202 | 201,110,71 203 | 202,110,72 204 | 203,111,72 205 | 204,112,73 206 | 205,113,74 207 | 206,113,74 208 | 207,114,75 209 | 208,115,75 210 | 209,116,76 211 | 210,116,76 212 | 211,117,77 213 | 212,118,77 214 | 213,112,64 215 | 214,109,60 216 | 215,106,59 217 | 216,102,57 218 | 217,98,56 219 | 218,94,55 220 | 219,89,54 221 | 220,85,53 222 | 221,82,53 223 | 222,79,53 224 | 223,75,53 225 | 224,72,53 226 | 225,69,53 227 | 226,67,53 228 | 227,65,54 229 | 228,64,54 230 | 229,63,55 231 | 230,63,56 232 | 231,64,57 233 | 232,65,58 234 | 233,64,58 235 | 234,63,59 236 | 235,62,59 237 | 236,61,59 238 | 237,60,59 239 | 238,59,59 240 | 239,71,62 241 | 240,70,62 242 | 241,70,62 243 | 242,70,63 244 | 243,69,63 245 | 244,69,63 246 | 245,82,63 247 | 246,88,64 248 | 247,92,64 249 | 248,94,64 250 | 249,95,63 251 | 250,96,63 252 | 251,96,63 253 | 252,96,63 254 | 253,96,63 255 | 254,96,62 256 | 255,95,61 257 | 256,94,61 -------------------------------------------------------------------------------- /Results/output_of.txt: -------------------------------------------------------------------------------- 1 | 0,92,67 2 | 1,91,68 3 | 2,90,64 4 | 3,90,64 5 | 4,93,66 6 | 5,90,64 7 | 6,93,67 8 | 7,93,66 9 | 8,93,66 10 | 9,92,67 11 | 10,91,64 12 | 11,92,65 13 | 12,92,65 14 | 13,92,60 15 | 14,92,59 16 | 15,92,61 17 | 16,94,61 18 | 17,95,62 19 | 18,94,61 20 | 19,95,59 21 | 20,95,59 22 | 21,95,58 23 | 22,95,56 24 | 23,97,56 25 | 24,98,56 26 | 25,98,56 27 | 26,100,55 28 | 27,99,54 29 | 28,100,54 30 | 29,100,53 31 | 30,100,53 32 | 31,100,49 33 | 32,100,49 34 | 33,100,49 35 | 34,101,49 36 | 35,102,54 37 | 36,102,54 38 | 37,101,49 39 | 38,101,49 40 | 39,100,54 41 | 40,100,50 42 | 41,98,54 43 | 42,96,55 44 | 43,92,55 45 | 44,90,54 46 | 45,85,59 47 | 46,84,61 48 | 47,79,61 49 | 48,77,62 50 | 49,71,60 51 | 50,68,62 52 | 51,64,64 53 | 52,60,66 54 | 53,64,72 55 | 54,55,68 56 | 55,54,69 57 | 56,52,66 58 | 57,53,66 59 | 58,55,66 60 | 59,57,66 61 | 60,58,66 62 | 61,60,66 63 | 62,61,66 64 | 63,61,66 65 | 64,61,66 66 | 65,60,66 67 | 66,60,66 68 | 67,66,70 69 | 68,69,71 70 | 69,60,66 71 | 70,61,65 72 | 71,65,66 73 | 72,69,65 74 | 73,64,59 75 | 74,70,62 76 | 75,69,57 77 | 76,71,56 78 | 77,73,54 79 | 78,76,52 80 | 79,79,52 81 | 80,81,51 82 | 81,84,49 83 | 82,87,48 84 | 83,91,46 85 | 84,95,46 86 | 85,96,47 87 | 86,100,46 88 | 87,104,47 89 | 88,106,46 90 | 89,109,47 91 | 90,112,42 92 | 91,114,42 93 | 92,117,48 94 | 93,117,47 95 | 94,118,42 96 | 95,118,42 97 | 96,118,42 98 | 97,117,43 99 | 98,116,43 100 | 99,114,49 101 | 100,112,51 102 | 101,111,52 103 | 102,107,53 104 | 103,103,54 105 | 104,99,49 106 | 105,97,53 107 | 106,94,54 108 | 107,92,54 109 | 108,89,53 110 | 109,86,51 111 | 110,84,51 112 | 111,83,51 113 | 112,81,49 114 | 113,81,50 115 | 114,80,50 116 | 115,80,48 117 | 116,79,48 118 | 117,79,48 119 | 118,78,48 120 | 119,77,48 121 | 120,78,48 122 | 121,77,49 123 | 122,78,49 124 | 123,78,49 125 | 124,78,49 126 | 125,78,49 127 | 126,77,50 128 | 127,77,49 129 | 128,77,49 130 | 129,77,49 131 | 130,76,49 132 | 131,76,49 133 | 132,76,48 134 | 133,76,49 135 | 134,76,49 136 | 135,77,49 137 | 136,77,49 138 | 137,76,47 139 | 138,77,47 140 | 139,77,47 141 | 140,80,48 142 | 141,80,48 143 | 142,81,49 144 | 143,81,46 145 | 144,83,49 146 | 145,82,46 147 | 146,85,49 148 | 147,85,49 149 | 148,85,49 150 | 149,83,46 151 | 150,85,49 152 | 151,85,49 153 | 152,84,48 154 | 153,85,49 155 | 154,84,48 156 | 155,84,48 157 | 156,84,48 158 | 157,85,49 159 | 158,85,49 160 | 159,84,48 161 | 160,85,49 162 | 161,83,48 163 | 162,83,49 164 | 163,83,50 165 | 164,84,52 166 | 165,85,52 167 | 166,86,53 168 | 167,86,54 169 | 168,84,51 170 | 169,87,56 171 | 170,87,55 172 | 171,87,59 173 | 172,87,58 174 | 173,86,57 175 | 174,86,58 176 | 175,89,61 177 | 176,88,61 178 | 177,87,59 179 | 178,87,59 180 | 179,90,61 181 | 180,90,61 182 | 181,90,60 183 | 182,92,59 184 | 183,93,59 185 | 184,93,60 186 | 185,93,57 187 | 186,97,61 188 | 187,96,58 189 | 188,98,60 190 | 189,100,61 191 | 190,106,66 192 | 191,105,64 193 | 192,110,71 194 | 193,111,71 195 | 194,111,68 196 | 195,113,69 197 | 196,116,70 198 | 197,118,71 199 | 198,120,73 200 | 199,122,74 201 | 200,124,75 202 | 201,126,75 203 | 202,127,76 204 | 203,129,75 205 | 204,130,73 206 | 205,132,71 207 | 206,134,69 208 | 207,135,66 209 | 208,134,64 210 | 209,132,61 211 | 210,128,58 212 | 211,123,55 213 | 212,117,53 214 | 213,109,57 215 | 214,104,55 216 | 215,98,56 217 | 216,90,53 218 | 217,84,53 219 | 218,79,53 220 | 219,73,53 221 | 220,70,52 222 | 221,69,54 223 | 222,66,54 224 | 223,64,55 225 | 224,61,56 226 | 225,61,55 227 | 226,61,57 228 | 227,63,56 229 | 228,64,57 230 | 229,67,60 231 | 230,70,64 232 | 231,74,64 233 | 232,78,65 234 | 233,84,61 235 | 234,87,62 236 | 235,90,62 237 | 236,93,63 238 | 237,95,63 239 | 238,97,63 240 | 239,98,68 241 | 240,99,63 242 | 241,100,62 243 | 242,101,62 244 | 243,101,62 245 | 244,102,61 246 | 245,103,64 247 | 246,101,66 248 | 247,102,65 249 | 248,99,62 250 | 249,98,61 251 | 250,96,62 252 | 251,94,62 253 | 252,93,61 254 | 253,92,61 255 | 254,91,59 256 | 255,89,58 257 | 256,88,58 -------------------------------------------------------------------------------- /Results/output_particle.txt: -------------------------------------------------------------------------------- 1 | 0,92,67 2 | 1,91,66 3 | 2,90,65 4 | 3,89,65 5 | 4,88,65 6 | 5,87,65 7 | 6,86,65 8 | 7,85,65 9 | 8,85,65 10 | 9,86,64 11 | 10,85,65 12 | 11,86,64 13 | 12,85,65 14 | 13,87,64 15 | 14,86,64 16 | 15,86,63 17 | 16,85,64 18 | 17,87,62 19 | 18,87,63 20 | 19,87,64 21 | 20,87,64 22 | 21,87,66 23 | 22,88,65 24 | 23,91,63 25 | 24,91,63 26 | 25,93,63 27 | 26,93,64 28 | 27,92,61 29 | 28,94,59 30 | 29,95,61 31 | 30,95,61 32 | 31,94,62 33 | 32,96,61 34 | 33,94,63 35 | 34,95,61 36 | 35,94,63 37 | 36,95,62 38 | 37,95,63 39 | 38,96,62 40 | 39,95,64 41 | 40,93,63 42 | 41,93,63 43 | 42,92,63 44 | 43,90,63 45 | 44,88,66 46 | 45,85,64 47 | 46,84,64 48 | 47,82,65 49 | 48,79,66 50 | 49,77,65 51 | 50,76,66 52 | 51,73,66 53 | 52,71,67 54 | 53,70,67 55 | 54,68,69 56 | 55,65,72 57 | 56,66,72 58 | 57,63,69 59 | 58,64,72 60 | 59,62,70 61 | 60,62,71 62 | 61,63,71 63 | 62,62,73 64 | 63,62,73 65 | 64,62,74 66 | 65,63,71 67 | 66,62,70 68 | 67,61,70 69 | 68,62,71 70 | 69,63,72 71 | 70,65,71 72 | 71,64,71 73 | 72,65,70 74 | 73,63,68 75 | 74,63,65 76 | 75,65,64 77 | 76,67,65 78 | 77,67,63 79 | 78,66,61 80 | 79,66,60 81 | 80,69,59 82 | 81,70,59 83 | 82,72,58 84 | 83,74,56 85 | 84,77,58 86 | 85,82,58 87 | 86,84,58 88 | 87,88,56 89 | 88,92,56 90 | 89,95,57 91 | 90,101,58 92 | 91,105,59 93 | 92,104,58 94 | 93,105,58 95 | 94,110,59 96 | 95,106,58 97 | 96,108,60 98 | 97,108,59 99 | 98,108,60 100 | 99,109,61 101 | 100,106,61 102 | 101,105,62 103 | 102,105,62 104 | 103,101,61 105 | 104,99,60 106 | 105,96,60 107 | 106,93,63 108 | 107,90,61 109 | 108,89,60 110 | 109,87,60 111 | 110,85,60 112 | 111,83,60 113 | 112,81,60 114 | 113,80,60 115 | 114,78,60 116 | 115,78,58 117 | 116,77,60 118 | 117,77,60 119 | 118,77,59 120 | 119,76,58 121 | 120,77,58 122 | 121,76,60 123 | 122,76,59 124 | 123,76,60 125 | 124,76,60 126 | 125,76,58 127 | 126,76,58 128 | 127,74,55 129 | 128,75,57 130 | 129,75,58 131 | 130,74,57 132 | 131,76,56 133 | 132,76,57 134 | 133,75,56 135 | 134,75,56 136 | 135,75,55 137 | 136,75,55 138 | 137,74,54 139 | 138,75,55 140 | 139,75,55 141 | 140,76,56 142 | 141,77,57 143 | 142,78,55 144 | 143,80,56 145 | 144,79,56 146 | 145,80,55 147 | 146,80,55 148 | 147,79,55 149 | 148,80,56 150 | 149,82,56 151 | 150,83,54 152 | 151,81,56 153 | 152,81,55 154 | 153,82,53 155 | 154,82,54 156 | 155,82,55 157 | 156,82,53 158 | 157,84,55 159 | 158,83,55 160 | 159,83,55 161 | 160,82,54 162 | 161,83,56 163 | 162,82,55 164 | 163,81,56 165 | 164,81,57 166 | 165,82,58 167 | 166,83,60 168 | 167,83,62 169 | 168,84,59 170 | 169,84,59 171 | 170,85,59 172 | 171,85,61 173 | 172,85,62 174 | 173,85,62 175 | 174,87,64 176 | 175,86,63 177 | 176,87,64 178 | 177,85,64 179 | 178,85,65 180 | 179,85,65 181 | 180,86,64 182 | 181,86,63 183 | 182,86,65 184 | 183,88,63 185 | 184,89,63 186 | 185,89,65 187 | 186,91,67 188 | 187,91,67 189 | 188,93,69 190 | 189,93,70 191 | 190,94,73 192 | 191,95,73 193 | 192,96,73 194 | 193,98,74 195 | 194,100,74 196 | 195,100,74 197 | 196,100,75 198 | 197,103,75 199 | 198,105,77 200 | 199,106,80 201 | 200,107,80 202 | 201,107,79 203 | 202,109,79 204 | 203,112,81 205 | 204,113,83 206 | 205,114,80 207 | 206,117,83 208 | 207,116,79 209 | 208,117,79 210 | 209,119,79 211 | 210,117,78 212 | 211,115,75 213 | 212,112,73 214 | 213,107,72 215 | 214,101,70 216 | 215,97,69 217 | 216,93,67 218 | 217,90,68 219 | 218,85,68 220 | 219,82,67 221 | 220,80,67 222 | 221,76,65 223 | 222,74,65 224 | 223,71,66 225 | 224,69,67 226 | 225,67,66 227 | 226,66,65 228 | 227,64,65 229 | 228,64,65 230 | 229,64,66 231 | 230,65,67 232 | 231,67,66 233 | 232,68,66 234 | 233,70,67 235 | 234,70,67 236 | 235,74,68 237 | 236,76,70 238 | 237,78,66 239 | 238,80,66 240 | 239,81,68 241 | 240,82,68 242 | 241,84,71 243 | 242,85,70 244 | 243,86,68 245 | 244,87,67 246 | 245,88,68 247 | 246,90,71 248 | 247,89,71 249 | 248,90,69 250 | 249,89,69 251 | 250,87,68 252 | 251,86,67 253 | 252,85,65 254 | 253,85,65 255 | 254,84,66 256 | 255,83,64 257 | 256,83,64 -------------------------------------------------------------------------------- /Source/detection_tracking.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import cv2 4 | import matplotlib.pyplot as plt 5 | import numpy as np 6 | 7 | face_cascade = cv2.CascadeClassifier('/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml') 8 | 9 | 10 | def help_message(): 11 | print("Usage: [Question_Number] [Input_Video] [Output_Directory]") 12 | print("[Question Number]") 13 | print("1 Camshift") 14 | print("2 Particle Filter") 15 | print("3 Kalman Filter") 16 | print("4 Optical Flow") 17 | print("[Input_Video]") 18 | print("Path to the input video") 19 | print("[Output_Directory]") 20 | print("Output directory") 21 | print("Example usages:") 22 | print(sys.argv[0] + " 1 " + "02-1.avi " + "./") 23 | 24 | 25 | def detect_one_face(im): 26 | gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) 27 | 28 | faces = face_cascade.detectMultiScale(gray, 1.2, 3) 29 | if len(faces) == 0: 30 | return (0, 0, 0, 0) 31 | return faces[0] 32 | 33 | 34 | def hsv_histogram_for_window(frame, window): 35 | # set up the ROI for tracking 36 | c, r, w, h = window 37 | roi = frame[r:r + h, c:c + w] 38 | hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) 39 | mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.))) 40 | roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180]) 41 | cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) 42 | return roi_hist 43 | 44 | 45 | def resample(weights): 46 | n = len(weights) 47 | indices = [] 48 | C = [0.] + [sum(weights[:i + 1]) for i in range(n)] 49 | u0, j = np.random.random(), 0 50 | for u in [(u0 + i) / n for i in range(n)]: 51 | while u > C[j]: 52 | j += 1 53 | indices.append(j - 1) 54 | return indices 55 | 56 | 57 | def draw_on_image(ret, frame): 58 | # find four vertices of the rectangle from ret 59 | pt = cv2.boxPoints(ret) 60 | # round them to integers 61 | pt = np.int0(np.around(pt)) 62 | img = cv2.polylines( 63 | img=frame, 64 | pts=[pt], 65 | isClosed=True, 66 | color=255, 67 | thickness=2 68 | ) 69 | cv2.imshow('img', img) 70 | k = cv2.waitKey(60) & 0xff 71 | if k == 27: 72 | return 73 | 74 | 75 | def display_particle_filter(frame, particle): 76 | pt = np.int0(np.around(particle)) 77 | for pt in particle: 78 | img = cv2.circle(frame, (pt[0], pt[1]), 1, (0, 255, 0), -1) 79 | # img = cv2.rectangle(frame, (c, r), (c + w, r + h), 255, 2) 80 | 81 | cv2.imshow('img', img) 82 | k = cv2.waitKey(60) & 0xff 83 | if k == 27: 84 | return 85 | 86 | 87 | def display_kalman2(frame, pos): 88 | pt = np.int0(np.around(pos)) 89 | img = cv2.circle(frame, (pt[0], pt[1]), 10, (0, 255, 0), -1) 90 | 91 | cv2.imshow('img', frame) 92 | k = cv2.waitKey(60) & 0xff 93 | if k == 27: 94 | return 95 | 96 | 97 | def display_kalman3(frame, pos, ret): 98 | pt = np.int0(np.around(pos)) 99 | img = cv2.circle(frame, (pt[0], pt[1]), 10, (0, 255, 0), -1) 100 | pt1 = (ret[0],ret[1]) 101 | pt2 = (ret[0]+ret[2],ret[1]+ret[3]) 102 | 103 | cv2.rectangle(img, pt1, pt2, (0, 255, 0), 3) 104 | 105 | 106 | cv2.imshow('img', frame) 107 | k = cv2.waitKey(60) & 0xff 108 | if k == 27: 109 | return 110 | 111 | def display_of(frame , mask, pos): 112 | 113 | frame = cv2.circle(frame, (pos[0], pos[1]), 5) 114 | img = cv2.add(frame, mask) 115 | cv2.imshow('frame', img) 116 | k = cv2.waitKey(30) & 0xff 117 | if k == 27: 118 | return 119 | 120 | def skeleton_tracker(v, file_name): 121 | # Open output file 122 | output_name = sys.argv[3] + file_name 123 | output = open(output_name, "w") 124 | 125 | frameCounter = 0 126 | # read first frame 127 | ret, frame = v.read() 128 | if ret == False: 129 | return 130 | 131 | # detect face in first frame 132 | c, r, w, h = detect_one_face(frame) 133 | 134 | # Write track point for first frame 135 | output.write("%d,%d,%d\n" % pt) # Write as 0,pt_x,pt_y 136 | frameCounter = frameCounter + 1 137 | 138 | # set the initial tracking window 139 | track_window = (c, r, w, h) 140 | 141 | # calculate the HSV histogram in the window 142 | # NOTE: you do not need this in the Kalman, Particle or OF trackers 143 | roi_hist = hsv_histogram_for_window(frame, (c, r, w, h)) # this is provided for you 144 | 145 | # initialize the tracker 146 | # e.g. kf = cv2.KalmanFilter(4,2,0) 147 | # or: particles = np.ones((n_particles, 2), int) * initial_pos 148 | 149 | while (1): 150 | ret, frame = v.read() # read another frame 151 | if ret == False: 152 | break 153 | 154 | # perform the tracking 155 | # e.g. cv2.meanShift, cv2.CamShift, or kalman.predict(), kalman.correct() 156 | 157 | # use the tracking result to get the tracking point (pt): 158 | # if you track a rect (e.g. face detector) take the mid point, 159 | # if you track particles - take the weighted average 160 | # the Kalman filter already has the tracking point in the state vector 161 | 162 | # write the result to the output file 163 | output.write("%d,%d,%d\n" % pt) # Write as frame_index,pt_x,pt_y 164 | frameCounter = frameCounter + 1 165 | 166 | output.close() 167 | 168 | 169 | def optical_flow_tracker(v, file_name): 170 | 171 | # Open output file 172 | output_name = sys.argv[3] + file_name 173 | output = open(output_name, "w") 174 | 175 | frameCounter = 0 176 | 177 | # read first frame 178 | ret, frame = v.read() 179 | if not ret: 180 | return 181 | 182 | c, r, w, h = detect_one_face(frame) 183 | 184 | frameCounter += 1 185 | 186 | # Parameters for lucas kanade optical flow 187 | lk_params_winSize=(15, 15) 188 | lk_params_maxLevel=2 189 | lk_params_criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03) 190 | 191 | ret, old_frame = ret, frame 192 | old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY) 193 | 194 | p0 = [] 195 | num = 8 196 | for i in range(num - 1): 197 | p0_temp = np.random.rand(1,2)*(w/2,h/2) + (c+w/4,r+h/4) 198 | p0.append(p0_temp) 199 | 200 | p0_temp = [[c+w/2, r+h/2]] 201 | p0.append(p0_temp) 202 | p0 = np.array(p0).astype('float32') 203 | 204 | pt = (0, c + w/2, r + h/ 2) 205 | output.write("%d,%d,%d\n" % pt) # Write as 0,pt_x,pt_y 206 | 207 | while (1): 208 | ret, frame = v.read() # read another frame 209 | 210 | if not ret: 211 | break 212 | 213 | # perform the tracking 214 | # e.g. cv2.meanShift, cv2.CamShift, or kalman.predict(), kalman.correct() 215 | 216 | # use the tracking result to get the tracking point (pt): 217 | # if you track a rect (e.g. face detector) take the mid point, 218 | # if you track particles - take the weighted average 219 | # the Kalman filter already has the tracking point in the state vector 220 | 221 | frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 222 | 223 | # calculate optical flow 224 | p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, 225 | frame_gray, 226 | p0, 227 | None, 228 | maxLevel = lk_params_maxLevel, 229 | winSize = lk_params_winSize, 230 | criteria = lk_params_criteria 231 | ) 232 | 233 | # Select good points 234 | good_new = p1[st == 1] 235 | good_old = p0[st == 1] 236 | 237 | # draw the tracks 238 | for i, (new, old) in enumerate(zip(good_new, good_old)): 239 | a, b = new.ravel() 240 | c, d = old.ravel() 241 | 242 | # Now update the previous frame and previous points 243 | old_gray = frame_gray.copy() 244 | 245 | p0 = good_new.reshape(-1, 1, 2) 246 | 247 | c, r, w, h = detect_one_face(frame) 248 | 249 | # Use face detector else use optical flow 250 | if w != 0 and h != 0: 251 | pos = (c + w/2, r + h/2) 252 | else: 253 | pos = sum(zip(*p0)[0]) / num 254 | 255 | pt = (frameCounter, pos[0], pos[1]) 256 | # output.write("%d,%d,%d\n" % pt) # Write as 0,pt_x,pt_y 257 | if frameCounter != 256: 258 | output.write("%d,%d,%d\n" % pt) # Write as frame_index,pt_x,pt_y 259 | else: 260 | output.write("%d,%d,%d" % pt) # Write as frame_index,pt_x,pt_y 261 | frameCounter += 1 262 | 263 | output.close() 264 | 265 | 266 | def kalman_filter_tracker(v, file_name): 267 | # Open output file 268 | output_name = sys.argv[3] + file_name 269 | output = open(output_name, "w") 270 | 271 | frameCounter = 0 272 | # read first frame 273 | ret, frame = v.read() 274 | if not ret: 275 | return 276 | 277 | # detect face in first frame 278 | c, r, w, h = detect_one_face(frame) 279 | 280 | # Write track point for first frame 281 | pt = (0, c + w/2.0, r + h/2.0) 282 | output.write("%d,%d,%d\n" % pt) # Write as 0,pt_x,pt_y 283 | frameCounter += 1 284 | 285 | kalman = cv2.KalmanFilter(4, 2, 0) 286 | 287 | state = np.array([c + w / 2, r + h / 2, 0, 0], dtype='float64') # initial position 288 | kalman.transitionMatrix = np.array([[1., 0., .1, 0.], 289 | [0., 1., 0., .1], 290 | [0., 0., 1., 0.], 291 | [0., 0., 0., 1.]]) 292 | kalman.measurementMatrix = 1. * np.eye(2, 4) 293 | kalman.processNoiseCov = 1e-5 * np.eye(4, 4) 294 | kalman.measurementNoiseCov = 1e-3 * np.eye(2, 2) 295 | kalman.errorCovPost = 1e-1 * np.eye(4, 4) 296 | kalman.statePost = state 297 | while (1): 298 | # use prediction or posterior as your tracking result 299 | ret, frame = v.read() # read another frame 300 | if not ret: 301 | break 302 | 303 | img_width = frame.shape[0] 304 | img_height = frame.shape[1] 305 | 306 | def calc_point(angle): 307 | return (np.around(img_width / 2 + img_width / 3 * np.cos(angle), 0).astype(int), 308 | np.around(img_height / 2 - img_width / 3 * np.sin(angle), 1).astype(int)) 309 | 310 | # e.g. cv2.meanS hift, cv2.CamShift, or kalman.predict(), kalman.correct() 311 | 312 | # use the tracking result to get the tracking point (pt): 313 | # if you track a rect (e.g. face detector) take the mid point, 314 | # if you track particles - take the weighted average 315 | # the Kalman filter already has the tracking point in the state vector 316 | 317 | prediction = kalman.predict() 318 | 319 | pos = 0 320 | c, r, w, h = detect_one_face(frame) 321 | if w != 0 and h != 0: 322 | state = np.array([c + w / 2, r + h / 2, 0, 0], dtype='float64') 323 | # kalman.statePost = state 324 | measurement = (np.dot(kalman.measurementNoiseCov, np.random.randn(2, 1))).reshape(-1) 325 | measurement = np.dot(kalman.measurementMatrix, state) + measurement 326 | posterior = kalman.correct(measurement) 327 | pos = (posterior[0], posterior[1]) 328 | else: 329 | measurement = (np.dot(kalman.measurementNoiseCov, np.random.randn(2, 1))).reshape(-1) 330 | measurement = np.dot(kalman.measurementMatrix, state) + measurement 331 | pos = (prediction[0], prediction[1]) 332 | 333 | # display_kalman3(frame, pos, (c, r, w, h)) 334 | process_noise = np.sqrt(kalman.processNoiseCov[0, 0]) * np.random.randn(4, 1) 335 | state = np.dot(kalman.transitionMatrix, state) + process_noise.reshape(-1) 336 | 337 | pt = (frameCounter, pos[0], pos[1]) 338 | if frameCounter != 256: 339 | output.write("%d,%d,%d\n" % pt) # Write as frame_index,pt_x,pt_y 340 | else: 341 | output.write("%d,%d,%d" % pt) # Write as frame_index,pt_x,pt_y 342 | frameCounter += 1 343 | output.close() 344 | 345 | 346 | def particle_filter_tracker(v, file_name): 347 | def particleevaluator(back_proj, particle): 348 | return back_proj[particle[1], particle[0]] 349 | 350 | # Open output file 351 | output_name = sys.argv[3] + file_name 352 | output = open(output_name, "w") 353 | 354 | frameCounter = 0 355 | # read first frame 356 | ret, frame = v.read() 357 | if ret == False: 358 | return 359 | 360 | # detect face in first frame 361 | c, r, w, h = detect_one_face(frame) 362 | n_particles = 300 363 | init_pos = np.array([c + w / 2.0, r + h / 2.0], int) 364 | 365 | hist = hsv_histogram_for_window(frame, (c, r, w, h)) 366 | frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 367 | frame_dst = cv2.calcBackProject([frame_hsv], [0], hist, [0, 180], 1) 368 | particles = np.ones((n_particles, 2), int) * init_pos 369 | f0 = particleevaluator(frame_dst, init_pos) * np.ones(n_particles) 370 | weights = np.ones(n_particles) / n_particles 371 | pt = (0, c + w/2.0, r + h/ 2.0) 372 | # Write track point for first frame 373 | output.write("%d,%d,%d\n" % pt) # Write as 0,pt_x,pt_y 374 | frameCounter = frameCounter + 1 375 | 376 | # initialize the tracker 377 | # e.g. kf = cv2.KalmanFilter(4,2,0) 378 | # or: particles = np.ones((n_particles, 2), int) * initial_pos 379 | stepsize = 10 380 | while (1): 381 | ret, frame = v.read() # read another frame 382 | if not ret: 383 | break 384 | 385 | # perform the tracking 386 | # e.g. cv2.meanShift, cv2.CamShift, or kalman.predict(), kalman.correct() 387 | 388 | # Particle motion model: uniform step (TODO: find a better motion model) 389 | np.add(particles, np.random.uniform(-stepsize, stepsize, particles.shape), out=particles, casting="unsafe") 390 | 391 | # Clip out-of-bounds particles 392 | particles = particles.clip(np.zeros(2), np.array((frame.shape[1], frame.shape[0])) - 1).astype(int) 393 | 394 | frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 395 | frame_dst = cv2.calcBackProject([frame_hsv], [0], hist, [0, 180], 1) 396 | 397 | f = particleevaluator(frame_dst, particles.T) # Evaluate particles 398 | weights = np.float32(f.clip(1)) # Weight ~ histogram response 399 | weights /= np.sum(weights) # Normalize w 400 | pos = np.sum(particles.T * weights, axis=1).astype(int) # expected position: weighted average 401 | 402 | if 1. / np.sum(weights ** 2) < n_particles / 2.: # If particle cloud degenerate: 403 | particles = particles[resample(weights), :] # Resample particles according to weights 404 | 405 | # display_particle_filter(frame, particles) 406 | weights = resample(weights) 407 | 408 | # use the tracking result to get the tracking point (pt): 409 | # if you track a rect (e.g. face detector) take the mid point, 410 | # if you track particles - take the weighted average 411 | # the Kalman filter already has the tracking point in the state vector 412 | 413 | # write the result to the output file 414 | # output.write("%d,%d,%d\n" % (frameCounter, pos.item(0), pos.item(1))) # Write as frame_index,pt_x,pt_y 415 | pt = (frameCounter, pos.item(0), pos.item(1)) 416 | if frameCounter != 256: 417 | output.write("%d,%d,%d\n" % pt) # Write as frame_index,pt_x,pt_y 418 | else: 419 | output.write("%d,%d,%d" % pt) # Write as frame_index,pt_x,pt_y 420 | frameCounter += 1 421 | 422 | output.close() 423 | 424 | 425 | def CAM_shift_tracker(v, file_name): 426 | # Open output file 427 | output_name = sys.argv[3] + file_name 428 | output = open(output_name, "w") 429 | 430 | frameCounter = 0 431 | # read first frame 432 | ret, frame = v.read() 433 | if not ret: 434 | return 435 | # detect face in first frame 436 | c, r, w, h = detect_one_face(frame) 437 | 438 | # Write track point for first frame 439 | pt = (0, c + w/2.0, r + h/2.0) 440 | output.write("%d,%d,%d\n" % pt) # Write as 0,pt_x,pt_y 441 | frameCounter = frameCounter + 1 442 | 443 | # set the initial tracking window 444 | track_window = (c, r, w, h) 445 | # calculate the HSV histogram in the window 446 | # NOTE: you do not need this in the Kalman, Particle or OF trackers 447 | roi_hist = hsv_histogram_for_window(frame, (c, r, w, h)) 448 | 449 | term_convergence_condition = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1) 450 | 451 | # initialize the tracker 452 | # e.g. kf = cv2.KalmanFilter(4,2,0) 453 | # or: particles = np.ones((n_particles, 2), int) * initial_pos 454 | 455 | while 1: 456 | ret, frame = v.read() # read another frame 457 | if not ret: 458 | break 459 | 460 | # perform the tracking 461 | # e.g. cv2.meanShift, cv2.CamShift, or kalman.predict(), kalman.correct() 462 | 463 | frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 464 | frame_dst = cv2.calcBackProject([frame_hsv], [0], roi_hist, [0, 180], 1) 465 | ret, track_window = cv2.CamShift(frame_dst, track_window, term_convergence_condition) 466 | 467 | # use the tracking result to get the tracking point (pt): 468 | # if you track a rect (e.g. face detector) take the mid point, 469 | # if you track particles - take the weighted average 470 | # the Kalman filter already has the tracking point in the state vector 471 | 472 | # write the result to the output file 473 | pos = track_window 474 | x = pos[0] + pos[2]/2.0 475 | y = pos[1]+ pos[3]/2.0 476 | pt = (frameCounter, x, y) 477 | # cv2.circle(frame, ( int(pt[1]),int(pt[2]) ), 5, (0, 255, 0), -1) 478 | # draw_on_image(ret, frame) 479 | # output.write("%d,%d,%d\n" % pt) # Write as frame_index,pt_x,pt_y 480 | if frameCounter != 256: 481 | output.write("%d,%d,%d\n" % pt) # Write as frame_index,pt_x,pt_y 482 | else: 483 | output.write("%d,%d,%d" % pt) # Write as frame_index,pt_x,pt_y 484 | frameCounter = frameCounter + 1 485 | 486 | output.close() 487 | 488 | 489 | if __name__ == '__main__': 490 | question_number = -1 491 | 492 | # Validate the input arguments 493 | if (len(sys.argv) != 4): 494 | help_message() 495 | sys.exit() 496 | else: 497 | question_number = int(sys.argv[1]) 498 | if (question_number > 4 or question_number < 1): 499 | print("Input parameters out of bound ...") 500 | sys.exit() 501 | 502 | # read video file 503 | video = cv2.VideoCapture(sys.argv[2]); 504 | 505 | if (question_number == 1): 506 | CAM_shift_tracker(video, "output_camshift.txt") 507 | elif (question_number == 2): 508 | particle_filter_tracker(video, "output_particle.txt") 509 | elif (question_number == 3): 510 | kalman_filter_tracker(video, "output_kalman.txt") 511 | elif question_number == 4: 512 | optical_flow_tracker(video, "output_of.txt") 513 | 514 | ''' 515 | For Kalman Filter: 516 | 517 | # --- init 518 | 519 | state = np.array([c+w/2,r+h/2,0,0], dtype='float64') # initial position 520 | kalman.transitionMatrix = np.array([[1., 0., .1, 0.], 521 | [0., 1., 0., .1], 522 | [0., 0., 1., 0.], 523 | [0., 0., 0., 1.]]) 524 | kalman.measurementMatrix = 1. * np.eye(2, 4) 525 | kalman.processNoiseCov = 1e-5 * np.eye(4, 4) 526 | kalman.measurementNoiseCov = 1e-3 * np.eye(2, 2) 527 | kalman.errorCovPost = 1e-1 * np.eye(4, 4) 528 | kalman.statePost = state 529 | 530 | 531 | # --- tracking 532 | 533 | prediction = kalman.predict() 534 | 535 | # ... 536 | # obtain measurement 537 | 538 | if measurement_valid: # e.g. face found 539 | # ... 540 | posterior = kalman.correct(measurement) 541 | 542 | # use prediction or posterior as your tracking result 543 | ''' 544 | 545 | ''' 546 | For Particle Filter: 547 | 548 | # --- init 549 | 550 | # a function that, given a particle position, will return the particle's "fitness" 551 | def particleevaluator(back_proj, particle): 552 | return back_proj[particle[1],particle[0]] 553 | 554 | # hist_bp: obtain using cv2.calcBackProject and the HSV histogram 555 | # c,r,w,h: obtain using detect_one_face() 556 | n_particles = 200 557 | 558 | init_pos = np.array([c + w/2.0,r + h/2.0], int) # Initial position 559 | particles = np.ones((n_particles, 2), int) * init_pos # Init particles to init position 560 | f0 = particleevaluator(hist_bp, pos) * np.ones(n_particles) # Evaluate appearance model 561 | weights = np.ones(n_particles) / n_particles # weights are uniform (at first) 562 | 563 | 564 | # --- tracking 565 | 566 | # Particle motion model: uniform step (TODO: find a better motion model) 567 | np.add(particles, np.random.uniform(-stepsize, stepsize, particles.shape), out=particles, casting="unsafe") 568 | 569 | # Clip out-of-bounds particles 570 | particles = particles.clip(np.zeros(2), np.array((im_w,im_h))-1).astype(int) 571 | 572 | f = particleevaluator(hist_bp, particles.T) # Evaluate particles 573 | weights = np.float32(f.clip(1)) # Weight ~ histogram response 574 | weights /= np.sum(weights) # Normalize w 575 | pos = np.sum(particles.T * weights, axis=1).astype(int) # expected position: weighted average 576 | 577 | if 1. / np.sum(weights**2) < n_particles / 2.: # If particle cloud degenerate: 578 | particles = particles[resample(weights),:] # Resample particles according to weights 579 | # resample() function is provided for you 580 | ''' 581 | --------------------------------------------------------------------------------