| 117 | // Discard too big or small faces (this helps reduce the number of false positives) |
| 118 | |
| 119 | static void DiscardMissizedFaces( |
| 120 | std::vector<DetectorParameter>& detpars) // io |
| 121 | { |
| 122 | // constants (TODO These have not yet been rigorously empirically adjusted.) |
| 123 | static const double MIN_WIDTH = 1.33; // as fraction of median width |
| 124 | static const double MAX_WIDTH = 1.33; // as fraction of median width |
| 125 | |
| 126 | if (NSIZE(detpars) >= 3) // need at least 3 faces |
| 127 | { |
| 128 | // sort the faces on their width (smallest first) so can get median width |
| 129 | std::sort(detpars.begin(), detpars.end(), DecreasingWidth); |
| 130 | const int median = cvRound(detpars[NSIZE(detpars) / 2].width); |
| 131 | const int minallowed = cvRound(median / MIN_WIDTH); |
| 132 | const int maxallowed = cvRound(MAX_WIDTH * median); |
| 133 | // keep only faces that are not too big or small |
| 134 | std::vector<DetectorParameter> all_detpars(detpars); |
| 135 | detpars.resize(0); |
| 136 | for (int iface = 0; iface < NSIZE(all_detpars); iface++) |
| 137 | { |
| 138 | DetectorParameter* face = &all_detpars[iface]; |
| 139 | if (face->width >= minallowed && face->width <= maxallowed) |
| 140 | detpars.push_back(*face); |
| 141 | else if (trace_g || TRACE_IMAGES) |
| 142 | lprintf("[discard face%d of %d]", iface, NSIZE(all_detpars)); |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | static void TraceFaces( // write image showing detected face rects |
| 148 | const std::vector<DetectorParameter>& detpars, // in |
no test coverage detected