Beispiel #1
0
        /// <summary>
        /// Given an image, says whether classifier should go left or right int the classification tree.
        /// </summary>
        /// <param name="grayImage">integral of source image</param>
        /// <param name="squares">integral of squares</param>
        /// <param name="i">x coordinate</param>
        /// <param name="j">y coordinate</param>
        /// <param name="scale">scale to scale image to (i.e. 2 would look for stuff twice as big)</param>
        /// <returns></returns>
        public int getLeftOrRight(int[][] grayImage, int[][] squares, int i, int j, float scale)
        {
            // Figure out size of the image
            int w = (int)(scale * size.X);
            int h = (int)(scale * size.Y);

            // can fold w*h into a constant
            // division?
            double inv_area = 1 / (double)(w * h);


            // Get a normalization Coefficient
            int    total_x  = grayImage[i + w][j + h] + grayImage[i][j] - grayImage[i][j + h] - grayImage[i + w][j];
            int    total_x2 = squares[i + w][j + h] + squares[i][j] - squares[i][j + h] - squares[i + w][j];
            double moy      = total_x * inv_area;
            double vnorm    = total_x2 * inv_area - moy * moy;

            // sqrt?
            vnorm = (vnorm > 1) ? Math.Sqrt(vnorm) : 1;

            int rect_sum = 0;

            for (int k = 0; k < nb_rects; k++)
            {
                RectFeature r = rects[k];
                // Get coordinates of rectangles for computation and add them to sum
                // This is the feature value computation for each feature
                int rx1 = i + (int)(scale * r.x1);
                int rx2 = i + (int)(scale * (r.x1 + r.y1));
                int ry1 = j + (int)(scale * r.x2);
                int ry2 = j + (int)(scale * (r.x2 + r.y2));
                rect_sum += (int)((grayImage[rx2][ry2] - grayImage[rx1][ry2] - grayImage[rx2][ry1] + grayImage[rx1][ry1]) * r.weight);
            }
            // Normalize by area
            double rect_sum2 = rect_sum * inv_area;

            // If the sum of the rectangle area is less than the threshold * a normalization factor go left otherwise go right.
            return((rect_sum2 < threshold * vnorm) ? Tree.LEFT : Tree.RIGHT);
        }
Beispiel #2
0
        /// <summary>
        /// Construct the detector given an XML document describing the model file.
        /// This method parses the XML file and builds the feature medel
        /// </summary>
        /// <param name="document"></param>
        public Detector(XDocument document)
        {
            //Debug.WriteLine("loading document " + document);

            m_stages = new List <Stage>();

            var root = document.Root.Elements().First();

            Debug.Assert(root != null, "xml document root is not haarcascade_frontalface_alt");

            // Get the size of the classifier (size of the region to look at, i.e. 20 x 20
            string[] sizeStr = (from node in root.Descendants()
                                where node.Name.LocalName == "size"
                                select node.Value.Trim().Split(' ')).First().ToArray();
            m_size = new System.Windows.Point(Convert.ToDouble(sizeStr[0], CultureInfo.InvariantCulture), Convert.ToDouble(sizeStr[1], CultureInfo.InvariantCulture));

            var stagesRoot = root.Descendants().Where(x => x.Name.LocalName == "stages").First();
            var stages     = stagesRoot.Elements();

            foreach (XElement stage in stages)
            {
                // There's an extra level for some reason so we have to do down one
                var   trueStage       = stage;
                float stage_threshold = (float)Convert.ToDouble(trueStage.Element("stage_threshold").Value.Trim(), CultureInfo.InvariantCulture);
                Stage st    = new Stage(stage_threshold);
                var   trees = trueStage.Element("trees");
                foreach (XElement tree in trees.Elements())
                {
                    // There's an extra level for some reason so we have to do down one
                    XElement trueTree      = tree.Elements().First();
                    Tree     t             = new Tree();
                    XElement feature       = trueTree.Element("feature");
                    float    threshold     = (float)Convert.ToDouble(trueTree.Element("threshold").Value.Trim(), CultureInfo.InvariantCulture);
                    int      left_node     = -1;
                    float    left_val      = 0;
                    bool     has_left_val  = false;
                    int      right_node    = -1;
                    float    right_val     = 0;
                    bool     has_right_val = false;
                    XElement e             = trueTree.Element("left_val");
                    if (e != null)
                    {
                        left_val     = (float)Convert.ToDouble(e.Value.Trim(), CultureInfo.InvariantCulture);
                        has_left_val = true;
                    }
                    else
                    {
                        left_node    = Convert.ToInt32(trueTree.Element("left_node").Value.Trim(), CultureInfo.InvariantCulture);
                        has_left_val = false;
                    }
                    e = trueTree.Element("right_val");
                    if (e != null)
                    {
                        right_val     = (float)Convert.ToDouble(e.Value.Trim(), CultureInfo.InvariantCulture);
                        has_right_val = true;
                    }
                    else
                    {
                        right_node    = Convert.ToInt32(trueTree.Element("right_node").Value.Trim(), CultureInfo.InvariantCulture);
                        has_right_val = false;
                    }
                    Feature f     = new Feature(threshold, left_val, left_node, has_left_val, right_val, right_node, has_right_val, m_size);
                    var     rects = feature.Element("rects");
                    foreach (var r in rects.Elements())
                    {
                        string      rstr = r.Value.Trim();
                        RectFeature rect = RectFeature.fromString(rstr);
                        f.add(rect);
                    }

                    t.addFeature(f);
                    st.addTree(t);
                }
                m_stages.Add(st);
            }

            //Debug.WriteLine("Number of stages is " + m_stages.Count);
            //Debug.WriteLine("size str is " + m_stages.Count);
        }
Beispiel #3
0
 public void add(RectFeature r)
 {
     rects[nb_rects++] = r;
 }