public void capture()
        {
            this.log("capturing...");
            Image <Bgr, Byte>  currentFrame = grabber.QueryFrame().Resize(320, 240, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
            Image <Gray, byte> gray         = currentFrame.Convert <Gray, Byte>();

            this.log("capture done");

            // check train done
            if (this.frameCount % 10 == 0 && this.trainCount >= 0 && this.trainCount < TRAIN_THRESHOLD)
            {
                if (this.train(gray, this.personToTrain))
                {
                    this.trainCount++;
                    this.log("training..." + trainCount);
                }
                this.match("", TRAINING);
                return;
            }
            else if (this.trainCount == TRAIN_THRESHOLD)
            {
                MCvTermCriteria termCrit = new MCvTermCriteria(50, 0.001);
                recognizer = new EigenObjectRecognizer(this.appPath, trainingImages.ToArray(), this.labels.ToArray(), 5000, ref termCrit);

                this.trainComplete();
                this.trainCount = -1;
            }


            // Face detect
            this.log("face detecting...");
            Image <Gray, byte> result;

            MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(face, 1.2, 10, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(20, 20));
            this.log("face detecting done");

            // find the best matched again.
            if (facesDetected[0].Length != 1)
            {
                this.log("no faces detected");
                this.match(this.bestMatchPerson, 0);

                if (this.frameCount % NOFACE_COUNT == 0)
                {
                    this.matchPersons.Clear();
                    this.bestMatchPerson = "";
                    this.log("reset");
                    this.match("", 0);

                    // clean up all apps when no use
                    if (this.frameCount % CLEANUP_COUNT == 0)
                    {
                        this.cleanup();
                    }
                }
            }
            else
            {
                this.log("faces detected");

                foreach (MCvAvgComp f in facesDetected[0])
                {
                    result = currentFrame.Copy(f.rect).Convert <Gray, byte>().Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);

                    // Find the best match person
                    int testCount = 0;
                    foreach (KeyValuePair <string, int> iter in this.matchPersons)
                    {
                        testCount += iter.Value;
                    }

                    if (trainingImages.ToArray().Length != 0)
                    {
                        string name = recognizer.Recognize(result, testCount, TRAIN_THRESHOLD);
                        this.log("found:" + name + ", maxCount:" + testCount);

                        // Find the best match until threshold
                        if (testCount < MATCH_THRESHOLD)
                        {
                            if (this.matchPersons.ContainsKey(name))
                            {
                                this.matchPersons[name]++;
                            }
                            else
                            {
                                this.matchPersons[name] = 1;
                            }

                            this.match("", testCount);
                        }
                        else
                        {
                            IEnumerable <KeyValuePair <string, int> > sortedDict = from entry in matchPersons orderby entry.Value descending select entry;
                            string matchPersonsOut = "";
                            string bestMatch       = "";
                            int    i = 0;
                            foreach (KeyValuePair <string, int> iter in sortedDict)
                            {
                                matchPersonsOut += iter.Key + ": " + iter.Value + "\n";
                                if (i++ == 0)
                                {
                                    if (iter.Value >= 7)
                                    {
                                        bestMatch            = iter.Key;
                                        this.bestMatchPerson = bestMatch;
                                    }
                                    else
                                    {
                                        this.matchPersons.Clear();
                                        this.bestMatchPerson = "";
                                        this.log("cannot find the person over 7");
                                    }
                                }
                            }
                            this.match(bestMatch, testCount);

                            this.logger(matchPersonsOut);
                        }
                    }
                }
            }
            this.frameCount++;
        }