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(); }
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); }
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); }