Пример #1
0
        public DetectResult[] DetectWithRotationModels(Image <Gray, byte> image)
        {
            const double zhong_prob_threshold  = 0.75;
            const double biaoke_prob_threshold = 0.90;

            List <List <DetectResult> > chongs = new List <List <DetectResult> >();

            {   //Detect Zhong Chong
                List <DetectResult> zhongs = DetectZhongWithRotationModels(image);
                for (int i = zhongs.Count - 1; i >= 0; i--)
                {
                    DetectResult result = zhongs[i];
                    //image.ROI = result.rect;
                    //Image<Gray, byte> patch = image.Resize(winSize_64.Width, winSize_64.Height, Emgu.CV.CvEnum.Inter.Linear);
                    //image.ROI = Rectangle.Empty;

                    float[]  features = FeatureExtractionVerfication(result.patch);
                    double[] probs; svmZhong.PredictProb(features, out probs);

                    if (probs[0] < zhong_prob_threshold)
                    {
                        zhongs.RemoveAt(i);
                    }
                    else
                    {
                        result.score = probs[0];
                        zhongs[i]    = result;
                    }
                }
                chongs.Add(zhongs);
            }

            {   //Detect BiaoKe Chong
                List <DetectResult> biaokes = DetectBiaoKeWithRotationModels(image);
                for (int i = biaokes.Count - 1; i >= 0; i--)
                {
                    DetectResult result = biaokes[i];
                    //image.ROI = result.rect;
                    //Image<Gray, byte> patch = image.Resize(winSize_64.Width, winSize_64.Height, Emgu.CV.CvEnum.Inter.Linear);
                    //image.ROI = Rectangle.Empty;

                    float[]  features = FeatureExtractionVerfication(result.patch);
                    double[] probs; svmBiaoKe.PredictProb(features, out probs);

                    if (probs[0] < biaoke_prob_threshold)
                    {
                        biaokes.RemoveAt(i);
                    }
                    else
                    {
                        result.score = probs[0];
                        biaokes[i]   = result;
                    }
                }
                chongs.Add(biaokes);
            }

            //Check Overlapping cases
            for (int i = 0; i < chongs.Count; i++)
            {
                for (int j = chongs[i].Count - 1; j >= 0; j--)
                {
                    DetectResult chong1      = chongs[i][j];
                    double       chong1_area = chong1.rect.Width * chong1.rect.Height;

                    for (int m = i + 1; m < chongs.Count; m++)
                    {
                        for (int n = chongs[m].Count - 1; n >= 0; n--)
                        {
                            DetectResult chong2 = chongs[m][n];
                            //Check whether overlapping
                            Rectangle intersection = Rectangle.Intersect(chong1.rect, chong2.rect);
                            if (intersection.IsEmpty)
                            {
                                continue;
                            }
                            double intersection_area = intersection.Width * intersection.Height;
                            double chong2_area       = chong2.rect.Width * chong2.rect.Height;

                            if (intersection_area > chong1_area / 2 || intersection_area > chong2_area / 2)
                            { //Overlap detected
                                double[] probs;
                                float[]  feature1 = FeatureExtractionVerfication(chong1.patch);
                                svm.PredictProb(feature1, out probs);
                                double  prob1    = probs[(int)chong1.chong_type];
                                float[] feature2 = FeatureExtractionVerfication(chong2.patch);
                                svm.PredictProb(feature2, out probs);
                                double prob2 = probs[(int)chong2.chong_type];

                                if (prob1 < prob2)
                                {
                                    chongs[i].RemoveAt(j);
                                }
                                else
                                {
                                    chongs[m].RemoveAt(n);
                                }
                            }
                        }
                    }
                }
            }

            List <DetectResult> results = new List <DetectResult>();

            for (int i = 0; i < chongs.Count; i++)
            {
                results.AddRange(chongs[i]);
            }

            return(results.ToArray());

            //List<DetectResult> total_objs = new List<DetectResult>();
            ////total_objs.AddRange(DetectZhongWithRotationModels(image)); //Detecting Zhong Chong
            ////total_objs.AddRange(DetectBiaoKeWithRotationModels(image)); //Detecting Biaoke Chong
            ////total_objs.AddRange(DetectChuiXiGuanWithRotationModels(image)); //Detecting ChuiXiGuan Chong
            ////total_objs.AddRange(DetectDanZhiLunWithRotationModels(image)); //Detecting DanZhiLun Chong
            ////total_objs.AddRange(DetectZhuWenLunWithRotationModels(image)); //Detecting ZhuWenLun Chong
            ////total_objs.AddRange(DetectQiaoJuWithRotationModels(image)); //Detecting QiaoJu Chong

            ////Computes the prob for each obj and remove those are classified as NEGATIVE
            //List<DetectResult> result_list = new List<DetectResult>();
            //List<double> score_list = new List<double>();
            //for (int i = 0; i < total_objs.Count; i++)
            //{
            //    DetectResult result = total_objs[i];

            //    image.ROI = result.rect;
            //    Image<Gray, byte> patch = image.Resize(winSize_64.Width, winSize_64.Height, Emgu.CV.CvEnum.Inter.Linear);
            //    image.ROI = Rectangle.Empty;

            //    result.patch = patch;

            //    float[] features = FeatureExtractionVerfication(patch);
            //    double[] probs; svm.PredictProb(features, out probs);

            //    //Negative prob
            //    double prob_negative = probs[0];
            //    double max_prob = prob_negative; CHONG_VERF_TYPE max_type = CHONG_VERF_TYPE.NEGATIVE;

            //    {//ZHONG CHONG prob
            //        //double prob_zhong = 0; for (int k = (int)CHONG_VERF_TYPE.ZHONG_0; k <= (int)CHONG_VERF_TYPE.ZHONG_315; k++) prob_zhong += probs[k];
            //        double prob_zhong = probs[1];
            //        if (prob_zhong > max_prob) { max_prob = prob_zhong; max_type = CHONG_VERF_TYPE.ZHONG_0; }
            //    }

            //    {//BIAOKE CHONG prob
            //        //double prob_biaoke = 0; for (int k = (int)CHONG_VERF_TYPE.BIAOKE_0; k <= (int)CHONG_VERF_TYPE.BIAOKE_315; k++) prob_biaoke += probs[k];
            //        double prob_biaoke = probs[2];
            //        if (prob_biaoke > max_prob) { max_prob = prob_biaoke; max_type = CHONG_VERF_TYPE.BIAOKE_0; }
            //    }

            //    {//CHUIXIGUAN CHONG prob
            //        //double prob_chuixiguan = 0; for (int k = (int)CHONG_VERF_TYPE.CHUIXIGUAN_0; k <= (int)CHONG_VERF_TYPE.CHUIXIGUAN_315; k++) prob_chuixiguan += probs[k];
            //        double prob_chuixiguan = probs[3];
            //        if (prob_chuixiguan > max_prob) { max_prob = prob_chuixiguan; max_type = CHONG_VERF_TYPE.CHUIXIGUAN_0; }
            //    }

            //    {//DANZHILUN CHONG prob
            //        //double prob_danzhilun = 0; for (int k = (int)CHONG_VERF_TYPE.DANZHILUN_0; k <= (int)CHONG_VERF_TYPE.DANZHILUN_315; k++) prob_danzhilun += probs[k];
            //        double prob_danzhilun = probs[4];
            //        if (prob_danzhilun > max_prob) { max_prob = prob_danzhilun; max_type = CHONG_VERF_TYPE.DANZHILUN_0; }
            //    }

            //    {//ZHUWENLUN CHONG prob
            //        //double prob_zhuwenlun = 0; for (int k = (int)CHONG_VERF_TYPE.DANZHILUN_0; k <= (int)CHONG_VERF_TYPE.DANZHILUN_315; k++) prob_zhuwenlun += probs[k];
            //        double prob_zhuwenlun = probs[5];
            //        if (prob_zhuwenlun > max_prob) { max_prob = prob_zhuwenlun; max_type = CHONG_VERF_TYPE.ZHUWENLUN_0; }
            //    }

            //    if (max_type == CHONG_VERF_TYPE.NEGATIVE) continue;

            //    result.score = max_prob;
            //    if (max_type == CHONG_VERF_TYPE.ZHONG_0)
            //    {
            //        if (result.chong_type != CHONG_TYPE.ZHONG_CHONG) continue; //If the detected type is different from verified type, we ignore. So, verification is mostly used for rejecting.
            //        result.chong_type = CHONG_TYPE.ZHONG_CHONG;
            //    }
            //    else if (max_type == CHONG_VERF_TYPE.BIAOKE_0)
            //    {
            //        if (result.chong_type != CHONG_TYPE.BIAO_KE_CHONG) continue; //If the detected type is different from verified type, we ignore. So, verification is mostly used for rejecting.
            //        result.chong_type = CHONG_TYPE.BIAO_KE_CHONG;
            //    }
            //    else if (max_type == CHONG_VERF_TYPE.CHUIXIGUAN_0)
            //    {
            //        if (result.chong_type != CHONG_TYPE.CHUI_XI_GUAN_CHONG) continue; //If the detected type is different from verified type, we ignore. So, verification is mostly used for rejecting.
            //        result.chong_type = CHONG_TYPE.CHUI_XI_GUAN_CHONG;
            //    }
            //    else if (max_type == CHONG_VERF_TYPE.DANZHILUN_0)
            //    {
            //        if (result.chong_type != CHONG_TYPE.DAN_ZHI_LUN_CHONG) continue; //If the detected type is different from verified type, we ignore. So, verification is mostly used for rejecting.
            //        result.chong_type = CHONG_TYPE.DAN_ZHI_LUN_CHONG;
            //    }
            //    else if (max_type == CHONG_VERF_TYPE.ZHUWENLUN_0)
            //    {
            //        if (result.chong_type != CHONG_TYPE.ZHU_WEN_LUN_CHONG) continue; //If the detected type is different from verified type, we ignore. So, verification is mostly used for rejecting.
            //        result.chong_type = CHONG_TYPE.ZHU_WEN_LUN_CHONG;
            //    }

            //    result_list.Add(result);
            //    score_list.Add(-max_prob);
            //}

            //if (result_list.Count == 0) return null;

            ////Sort them in descenting order of prob
            //DetectResult[] result_arr = result_list.ToArray();
            //double[] score_arr = score_list.ToArray();
            //Array.Sort(score_arr, result_arr);

            ////Remove overlapping ones
            //List<DetectResult> results = new List<DetectResult>(); results.Add(result_arr[0]);
            //for (int i = 1; i < result_arr.Length; i++)
            //{
            //    DetectResult obj = result_arr[i];
            //    Rectangle obj_rect = obj.rect;
            //    double obj_area = obj_rect.Width * obj_rect.Height;

            //    //Check with existing ones, if signficantly overlapping with existing ones, ignore
            //    bool overlapping = false;
            //    for (int k = 0; k < results.Count; k++)
            //    {
            //        Rectangle result_rect = results[k].rect;
            //        Rectangle intersection = Rectangle.Intersect(obj_rect, result_rect);
            //        if (intersection.IsEmpty) continue;
            //        double intersection_area = intersection.Width * intersection.Height;
            //        double result_area = result_rect.Width * result_rect.Height;

            //        if (intersection_area > obj_area / 2 || intersection_area > result_area / 2)
            //        {
            //            overlapping = true; break;
            //        }
            //    }

            //    if (!overlapping) results.Add(obj);
            //}

            ////Remove low prob ones
            //for (int i = results.Count - 1; i >= 0; i--)
            //{
            //    DetectResult obj = results[i];
            //    if (obj.chong_type == CHONG_TYPE.ZHONG_CHONG && obj.score < 0.90) { results.RemoveAt(i); continue; }
            //    if (obj.chong_type == CHONG_TYPE.BIAO_KE_CHONG && obj.score < 0.80) { results.RemoveAt(i); continue; }
            //    if (obj.chong_type == CHONG_TYPE.CHUI_XI_GUAN_CHONG && obj.score < 0.80) { results.RemoveAt(i); continue; }
            //    if (obj.chong_type == CHONG_TYPE.DAN_ZHI_LUN_CHONG && obj.score < 0.95) { results.RemoveAt(i); continue; }
            //    if (obj.chong_type == CHONG_TYPE.ZHU_WEN_LUN_CHONG && obj.score < 0.95) { results.RemoveAt(i); continue; }
            //}

            ////2nd level SVM (which is for individual chong only) to reduce false alarms.
            //List<DetectResult> final_results = new List<DetectResult>();
            //for (int i = 0; i < results.Count; i++)
            //{
            //    DetectResult obj = results[i];
            //    if (obj.chong_type == CHONG_TYPE.ZHONG_CHONG)
            //    {
            //        float[] features = FeatureExtractionVerfication(obj.patch);
            //        double[] probs; svmZhong.PredictProb(features, out probs);
            //        if (probs[0] > 0.5) continue;
            //        obj.score = 1 - probs[0];
            //        final_results.Add(obj);
            //    }
            //    else
            //        final_results.Add(obj);
            //}

            //return final_results.ToArray();
        }
Пример #2
0
        private List <DetectResult> DetectBiaoKeWithRotationModels(Image <Gray, byte> image)
        {
            //resize the image
            double             scale      = winSize_64.Height / 160.0; //check statistics.txt to decide this scaling factor.
            Image <Gray, byte> img_scaled = image.Resize(scale, Emgu.CV.CvEnum.Inter.Linear);

            MCvObjectDetection[]      objects; int id = -1;
            List <MCvObjectDetection> total_objs = new List <MCvObjectDetection>();

            for (int deg = 0; deg < 360; deg += 30)
            {
                switch (deg)
                {
                case 0: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_0); id = 0; break;

                case 30: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_30); id = 30; break;

                case 60: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_60); id = 60; break;

                case 90: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_90); id = 90; break;

                case 120: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_120); id = 120; break;

                case 150: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_150); id = 150; break;

                case 180: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_180); id = 180; break;

                case 210: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_210); id = 210; break;

                case 240: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_240); id = 240; break;

                case 270: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_270); id = 270; break;

                case 300: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_300); id = 300; break;

                case 330: hog_detection.SetSVMDetector(svm_model_biaoke_chong_64_330); id = 330; break;
                }
                objects = hog_detection.DetectMultiScale(img_scaled, hitThreshold, winStride, testPadding, scaleStep, groupThreshold, useMeanShiftGrouping);
                for (int i = 0; i < objects.Length; i++)
                {
                    objects[i].ClassId = id;
                }
                total_objs.AddRange(objects);
            }

            //Rescale back to orignal size and Remove some obvious false alarms
            List <DetectResult> results = new List <DetectResult>();

            for (int i = 0; i < total_objs.Count; i++)
            {
                Rectangle rect      = total_objs[i].Rect;
                Rectangle orig_rect = new Rectangle((int)(rect.X / scale + .5), (int)(rect.Y / scale + .5), (int)(rect.Width / scale + .5), (int)(rect.Height / scale + .5));

                //Remove some obvious false alarms
                if (OutsideImage(orig_rect, image.Width, image.Height))
                {
                    continue;
                }

                //if (orig_rect.Width < 120 || orig_rect.Height < 120) continue;
                if (orig_rect.Width > 250 || orig_rect.Height > 250)
                {
                    continue;
                }

                DetectResult result = new DetectResult();
                result.chong_type = CHONG_TYPE.BIAO_KE_CHONG;
                result.rect       = orig_rect;
                result.score      = total_objs[i].Score;
                result.deg        = total_objs[i].ClassId;
                results.Add(result);
            }

            if (results.Count == 0)
            {
                return(results);
            }

            //Sort patches
            DetectResult[] result_arr = results.ToArray();
            double[]       score_arr  = new double[results.Count];
            for (int k = 0; k < results.Count; k++)
            {
                score_arr[k] = -results[k].score;
            }
            Array.Sort(score_arr, result_arr);

            //Remove overlapping ones
            results = new List <DetectResult>(); results.Add(result_arr[0]);
            for (int i = 1; i < result_arr.Length; i++)
            {
                DetectResult obj      = result_arr[i];
                Rectangle    obj_rect = obj.rect;
                double       obj_area = obj_rect.Width * obj_rect.Height;

                //Check with existing ones, if signficantly overlapping with existing ones, ignore
                bool overlapping = false;
                for (int k = 0; k < results.Count; k++)
                {
                    Rectangle result_rect  = results[k].rect;
                    Rectangle intersection = Rectangle.Intersect(obj_rect, result_rect);
                    if (intersection.IsEmpty)
                    {
                        continue;
                    }
                    double intersection_area = intersection.Width * intersection.Height;
                    double result_area       = result_rect.Width * result_rect.Height;

                    if (intersection_area > obj_area / 2 || intersection_area > result_area / 2)
                    {
                        overlapping = true; break;
                    }
                }

                if (!overlapping)
                {
                    results.Add(obj);
                }
            }

            //Cropp the patch out and save into results
            for (int i = 0; i < results.Count; i++)
            {
                DetectResult result = results[i];
                image.ROI    = result.rect;
                result.patch = image.Resize(winSize_64.Width, winSize_64.Height, Emgu.CV.CvEnum.Inter.Linear);
                image.ROI    = Rectangle.Empty;
                results[i]   = result;
            }

            return(results);
        }
Пример #3
0
        private List <DetectResult> DetectQiaoJuWithRotationModels(Image <Gray, byte> image)
        {
            //resize the image
            double             scale      = winSize_64.Height / 192.0; //check statistics.txt to decide this scaling factor.
            Image <Gray, byte> img_scaled = image.Resize(scale, Emgu.CV.CvEnum.Inter.Linear);

            MCvObjectDetection[]      objects;
            List <MCvObjectDetection> total_objs = new List <MCvObjectDetection>();

            //0 degree model
            hog_detection.SetSVMDetector(svm_model_qiaoju_chong_64_0);
            objects = hog_detection.DetectMultiScale(img_scaled, hitThreshold, winStride, testPadding, scaleStep, groupThreshold, useMeanShiftGrouping);
            total_objs.AddRange(objects);

            //45 degree model
            hog_detection.SetSVMDetector(svm_model_qiaoju_chong_64_45);
            objects = hog_detection.DetectMultiScale(img_scaled, hitThreshold, winStride, testPadding, scaleStep, groupThreshold, useMeanShiftGrouping);
            total_objs.AddRange(objects);

            //90 degree model
            hog_detection.SetSVMDetector(svm_model_qiaoju_chong_64_90);
            objects = hog_detection.DetectMultiScale(img_scaled, hitThreshold, winStride, testPadding, scaleStep, groupThreshold, useMeanShiftGrouping);
            total_objs.AddRange(objects);

            //135 degree model
            hog_detection.SetSVMDetector(svm_model_qiaoju_chong_64_135);
            objects = hog_detection.DetectMultiScale(img_scaled, hitThreshold, winStride, testPadding, scaleStep, groupThreshold, useMeanShiftGrouping);
            total_objs.AddRange(objects);

            //180 degree model
            hog_detection.SetSVMDetector(svm_model_qiaoju_chong_64_180);
            objects = hog_detection.DetectMultiScale(img_scaled, hitThreshold, winStride, testPadding, scaleStep, groupThreshold, useMeanShiftGrouping);
            total_objs.AddRange(objects);

            //225 degree model
            hog_detection.SetSVMDetector(svm_model_qiaoju_chong_64_225);
            objects = hog_detection.DetectMultiScale(img_scaled, hitThreshold, winStride, testPadding, scaleStep, groupThreshold, useMeanShiftGrouping);
            total_objs.AddRange(objects);

            //270 degree model
            hog_detection.SetSVMDetector(svm_model_qiaoju_chong_64_270);
            objects = hog_detection.DetectMultiScale(img_scaled, hitThreshold, winStride, testPadding, scaleStep, groupThreshold, useMeanShiftGrouping);
            total_objs.AddRange(objects);

            // 315 degree model
            hog_detection.SetSVMDetector(svm_model_qiaoju_chong_64_315);
            objects = hog_detection.DetectMultiScale(img_scaled, hitThreshold, winStride, testPadding, scaleStep, groupThreshold, useMeanShiftGrouping);
            total_objs.AddRange(objects);

            //Rescale back to orignal size and Remove some obvious false alarms
            List <DetectResult> results = new List <DetectResult>();

            for (int i = 0; i < total_objs.Count; i++)
            {
                Rectangle rect      = total_objs[i].Rect;
                Rectangle orig_rect = new Rectangle((int)(rect.X / scale + .5), (int)(rect.Y / scale + .5), (int)(rect.Width / scale + .5), (int)(rect.Height / scale + .5));

                //Remove some obvious false alarms
                if (OutsideImage(orig_rect, image.Width, image.Height))
                {
                    continue;
                }

                //if (orig_rect.Width < 120 || orig_rect.Height < 120) continue;
                if (orig_rect.Width > 500 || orig_rect.Height > 500)
                {
                    continue;
                }

                DetectResult result = new DetectResult();
                result.chong_type = CHONG_TYPE.QIAO_JU_CHONG;
                result.rect       = orig_rect;
                result.score      = total_objs[i].Score;
                results.Add(result);
            }

            return(results);
        }