//通过将sample与模板templates比对,寻找相应的contour,寻找到以后存放在FoundTemplateDesc类中 public FoundTemplateDesc FindTemplate(Templates templates, Template sample) { //int maxInterCorrelationShift = (int)(templateSize * maxRotateAngle / Math.PI); //maxInterCorrelationShift = Math.Min(templateSize, maxInterCorrelationShift+13); double rate = 0; double angle = 0; Complex interCorr = default(Complex); Template foundTemplate = null; foreach (var template in templates) { // if (Math.Abs(sample.autoCorrDescriptor1 - template.autoCorrDescriptor1) > maxACFDescriptorDeviation) { continue; } if (Math.Abs(sample.autoCorrDescriptor2 - template.autoCorrDescriptor2) > maxACFDescriptorDeviation) { continue; } if (Math.Abs(sample.autoCorrDescriptor3 - template.autoCorrDescriptor3) > maxACFDescriptorDeviation) { continue; } if (Math.Abs(sample.autoCorrDescriptor4 - template.autoCorrDescriptor4) > maxACFDescriptorDeviation) { continue; } // double r = 0; //可以看作相似度 if (checkACF) { r = template.autoCorr.NormDot(sample.autoCorr).Norma; //ACF的话不需要FindMaxNorma() if (r < minACF) { continue; } } if (checkICF) { interCorr = template.contour.InterCorrelation(sample.contour).FindMaxNorma(); r = interCorr.Norma / (template.contourNorma * sample.contourNorma); if (r < minICF) { continue; } if (Math.Abs(interCorr.Angle) > maxRotateAngle) { continue; } } if (template.preferredAngleNoMore90 && Math.Abs(interCorr.Angle) >= Math.PI / 2) { continue;//unsuitable angle } //find max rate if (r >= rate) { rate = r; foundTemplate = template; angle = interCorr.Angle; } } //ignore antipatterns if (foundTemplate != null && foundTemplate.name == antiPatternName) { foundTemplate = null; } // if (foundTemplate != null) { return new FoundTemplateDesc() { template = foundTemplate, rate = rate, sample = sample, angle = angle } } ; else { return(null); } }
public void ProcessImage(Image <Gray, byte> grayFrame) { if (equalizeHist) { grayFrame._EqualizeHist();//autocontrast } //smoothed Image <Gray, byte> smoothedGrayFrame = grayFrame.PyrDown(); smoothedGrayFrame = smoothedGrayFrame.PyrUp(); //canny Image <Gray, byte> cannyFrame = null; if (noiseFilter) { cannyFrame = smoothedGrayFrame.Canny(new Gray(cannyThreshold), new Gray(cannyThreshold)); } //smoothing if (blur) { grayFrame = smoothedGrayFrame; } //binarize CvInvoke.cvAdaptiveThreshold(grayFrame, grayFrame, 255, Emgu.CV.CvEnum.ADAPTIVE_THRESHOLD_TYPE.CV_ADAPTIVE_THRESH_MEAN_C, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY, adaptiveThresholdBlockSize + adaptiveThresholdBlockSize % 2 + 1, adaptiveThresholdParameter); // grayFrame._Not(); // if (addCanny) { if (cannyFrame != null) { grayFrame._Or(cannyFrame); } } // this.binarizedFrame = grayFrame; //dilate canny contours for filtering if (cannyFrame != null) { cannyFrame = cannyFrame.Dilate(3); } //find contours var sourceContours = grayFrame.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST); //filter contours contours = FilterContours(sourceContours, cannyFrame, grayFrame.Width, grayFrame.Height); //find templates lock (foundTemplates) foundTemplates.Clear(); samples.Clear(); lock (templates) { LoadTemplates("waterkiller.bin"); Parallel.ForEach <Contour <Point> >(contours, (contour) => { var arr = contour.ToArray(); Template sample = new Template(arr, contour.Area, samples.templateSize); lock (samples) samples.Add(sample); if (!onlyFindContours) { FoundTemplateDesc desc = finder.FindTemplate(templates, sample); if (desc != null) { lock (foundTemplates) foundTemplates.Add(desc); } } } ); } // FilterByIntersection(ref foundTemplates); }
public FoundTemplateDesc FindTemplate(Templates templates, Template sample) { FoundTemplateDesc desc2; double num = 0.0; double angle = 0.0; Complex complex = new Complex(); Template objA = null; using (List <Template> .Enumerator enumerator = templates.GetEnumerator()) { while (true) { if (!enumerator.MoveNext()) { break; } Template current = enumerator.Current; if ((Math.Abs((int)(sample.autoCorrDescriptor1 - current.autoCorrDescriptor1)) <= this.maxACFDescriptorDeviation) && ((Math.Abs((int)(sample.autoCorrDescriptor2 - current.autoCorrDescriptor2)) <= this.maxACFDescriptorDeviation) && ((Math.Abs((int)(sample.autoCorrDescriptor3 - current.autoCorrDescriptor3)) <= this.maxACFDescriptorDeviation) && (Math.Abs((int)(sample.autoCorrDescriptor4 - current.autoCorrDescriptor4)) <= this.maxACFDescriptorDeviation)))) { double num3 = 0.0; if (!this.checkACF || (current.autoCorr.NormDot(sample.autoCorr).Norma >= this.minACF)) { if (this.checkICF) { complex = current.contour.InterCorrelation(sample.contour).FindMaxNorma(); num3 = complex.Norma / (current.contourNorma * sample.contourNorma); if (num3 < this.minICF) { continue; } if (Math.Abs(complex.Angle) > this.maxRotateAngle) { continue; } } if ((!current.preferredAngleNoMore90 || (Math.Abs(complex.Angle) < 1.5707963267948966)) && (num3 >= num)) { num = num3; objA = current; angle = complex.Angle; } } } } } if ((objA != null) && (objA.name == this.antiPatternName)) { objA = null; } if (ReferenceEquals(objA, null)) { desc2 = null; } else { desc2 = new FoundTemplateDesc { template = objA, rate = num, sample = sample, angle = angle }; } return(desc2); }