private int GetPatchCode(Image <Gray, byte> currentFrame, IBoundingBox patchBb) { // define region where the patch is currentFrame.ROI = Rectangle.Round(patchBb.GetRectangle()); return(GetPatchCode(currentFrame)); }
public float GetOverlap(IBoundingBox bb) { RectangleF r1 = GetRectangle(); RectangleF r2 = bb.GetRectangle(); // calculate intersection RectangleF rectInter = RectangleF.Intersect(r1, r2); float intersection = rectInter.Width * rectInter.Height; // calculate union float union = r1.Width * r1.Height + r2.Width * r2.Height - intersection; return(intersection / union); }
private Image <Gray, byte> CreateModelPatch(IBoundingBox boundingBox, Image <Gray, byte> frame, INTER interpolation, double gaussianSigma) { frame.ROI = Rectangle.Round(boundingBox.GetRectangle()); Image <Gray, byte> patch = frame.Resize( _objectModel.PatchSize.Width, _objectModel.PatchSize.Height, interpolation ); frame.ROI = Rectangle.Empty; if (gaussianSigma != 0) { CvInvoke.cvSmooth( patch, patch, SMOOTH_TYPE.CV_GAUSSIAN, 0, 0, gaussianSigma, gaussianSigma ); } return(patch); }
public void TrainDetector(Image <Gray, byte> currentFrame, IBoundingBox currentBb, out bool valid) { // if patch is outside the image if (!currentBb.InsideFrame(currentFrame.Size)) { valid = false; return; } // get normalized image patch currentFrame.ROI = Rectangle.Round(currentBb.GetRectangle()); Image <Gray, byte> currentPatch = currentFrame.Resize(_objectModel.PatchSize.Width, _objectModel.PatchSize.Height, INTER.CV_INTER_LINEAR); currentFrame.ROI = Rectangle.Empty; // if appearance changed too fast float pnnSimilarity, nnnSimilarity; if (_objectModel.RelativeSimilarity(currentPatch, out pnnSimilarity, out nnnSimilarity) < 0.5f) { valid = false; return; } if (nnnSimilarity > _sameSimilarityThreshold) { valid = false; return; } #region ensemble classifier // generate positive patches List <Image <Gray, byte> > positivePatchesForEnsemble = GeneratePatches( _ensembleClassifier.SmoothFrame, currentBb, _runtimePosPatchSynthesisInfo.EnsembleCount, _runtimePosPatchSynthesisInfo.WarpInfo, 0, Size.Empty ); // pick negative patches List <IBoundingBox> allEnsembleNegativeBbs = new List <IBoundingBox>(); foreach (KeyValuePair <IBoundingBox, double> pair in _ensembleClassifier.PositivePosteriors) { IBoundingBox bb = pair.Key; if (bb.GetOverlap(currentBb) < _runtimeNegativePatchPickingInfo.Overlap) { allEnsembleNegativeBbs.Add(bb); } } List <Image <Gray, byte> > negativePatchesForEnsemble = PickBoundingBoxesAndGeneratePatches( _ensembleClassifier.SmoothFrame, allEnsembleNegativeBbs, _runtimeNegativePatchPickingInfo.EnsembleCount, Size.Empty ); // train ensemble classifier int bootstrap = 1; for (int i = 0; i < bootstrap; i++) { _ensembleClassifier.TrainWithUnseenPatches(positivePatchesForEnsemble, negativePatchesForEnsemble); } #endregion #region nn classifier // generate positive patches List <Image <Gray, byte> > positivePatchesForNn = GeneratePatches( currentFrame, currentBb, _runtimePosPatchSynthesisInfo.NnCount, _runtimePosPatchSynthesisInfo.WarpInfo, _runtimePosPatchSynthesisInfo.GaussianSigma, _objectModel.PatchSize ); int width = _objectModel.PatchSize.Width; int height = _objectModel.PatchSize.Height; for (int i = 0; i < positivePatchesForNn.Count; i++) { positivePatchesForNn[i] = positivePatchesForNn[i].Resize(width, height, INTER.CV_INTER_LINEAR); } /* * // pick negative patches * List<IBoundingBox> allNegativeNnBbs = new List<IBoundingBox>(); * IBoundingBox[] allBoundingBoxes = _nnClassifier.ScanningWindowGenerator.ScanningWindows; * List<int> nnAcceptedPatches = _nnClassifier.AcceptedPatches; * int nnAcceptedPatchesCount = nnAcceptedPatches.Count; * * for (int i = 0; i < nnAcceptedPatchesCount; i++) * { * int windowIndex = nnAcceptedPatches[i]; * IBoundingBox bb = allBoundingBoxes[windowIndex]; * if (bb.GetOverlap(currentBb) < _runtimeNegativePatchPickingInfo.Overlap) * { * allNegativeNnBbs.Add(bb); * } * } * * List<Image<Gray, byte>> negativePatchesForNn = PickBoundingBoxesAndGeneratePatches( * currentFrame, * allNegativeNnBbs, * _runtimeNegativePatchPickingInfo.NnCount, * _objectModel.PatchSize * ); */ List <Image <Gray, byte> > negativePatchesForNn = PickFromList <Image <Gray, byte> >(negativePatchesForEnsemble, _runtimeNegativePatchPickingInfo.NnCount); for (int i = 0; i < negativePatchesForNn.Count; i++) { negativePatchesForNn[i] = negativePatchesForNn[i].Resize(_objectModel.PatchSize.Width, ObjectModel.PatchSize.Height, INTER.CV_INTER_LINEAR); } // train nn classifier (update object model) TrainNnClassifier(positivePatchesForNn, negativePatchesForNn); #endregion valid = true; currentFrame.ROI = Rectangle.Empty; }
public static void DrawBoundingBox(PaintEventArgs e, IBoundingBox bb, Pen pen) { Rectangle rect = Rectangle.Round(bb.GetRectangle()); e.Graphics.DrawRectangle(pen, rect); }
public IBoundingBox DetermineBoundingBox(IBoundingBox trackerBoundingBox, List <IBoundingBox> detectorBoundingBoxes, Image <Gray, byte> frame, out bool reinitializeTracker, bool prevValid, out bool currValid) { IBoundingBox output = null; reinitializeTracker = false; currValid = false; /* [Zdenek] If neither the tracker nor the detector output a bounding box, * the object is declared as not visible */ if (trackerBoundingBox == null && detectorBoundingBoxes == null) { return(null); } // calculate relative similarities for all bounding boxes Dictionary <IBoundingBox, float> relativeSimilarities = new Dictionary <IBoundingBox, float>(); // -> tracker if (trackerBoundingBox != null) { frame.ROI = Rectangle.Round(trackerBoundingBox.GetRectangle()); Size patchSize = _objectModel.PatchSize; Image <Gray, byte> trackerPatch = frame.Resize(patchSize.Width, patchSize.Height, INTER.CV_INTER_LINEAR); relativeSimilarities.Add(trackerBoundingBox, _objectModel.RelativeSimilarity(trackerPatch)); frame.ROI = Rectangle.Empty; } // -> detector if (detectorBoundingBoxes != null) { for (int i = 0; i < detectorBoundingBoxes.Count; i++) { IBoundingBox bb = detectorBoundingBoxes[i]; relativeSimilarities.Add(bb, CurrentState.RelativeSimilarities[bb]); } } // if tracker is defined if (trackerBoundingBox != null) { output = trackerBoundingBox; if (detectorBoundingBoxes != null) { float bigOverlap = 0.8f; // get detector bounding boxes // that are far from tracker // and are more confident then the tracker List <IBoundingBox> bbs = new List <IBoundingBox>(); foreach (IBoundingBox bb in detectorBoundingBoxes) { if (bb.GetOverlap(trackerBoundingBox) < bigOverlap && relativeSimilarities[bb] > relativeSimilarities[trackerBoundingBox]) { bbs.Add(bb); } } // if there is only only one such bounding box, // reinitialize the tracker if (bbs.Count == 1) { output = bbs[0]; reinitializeTracker = true; currValid = false; } // otherwise calculate weighted average with close detections else { int trackerRepeat = 1; PointF center = trackerBoundingBox.Center.Multiply(trackerRepeat, trackerRepeat); SizeF size = trackerBoundingBox.Size.Multiply(trackerRepeat, trackerRepeat); // consider detector bounding boxes that are close to the tracker int bbCount = trackerRepeat; foreach (IBoundingBox bb in detectorBoundingBoxes) { if (bb.GetOverlap(trackerBoundingBox) >= bigOverlap) { center = center.Add(bb.Center); size = size.Add(bb.Size); bbCount++; } } output = trackerBoundingBox.CreateInstance( center.Divide(bbCount, bbCount), size.Divide(bbCount, bbCount) ); } } } // if tracker is not defined else { if (detectorBoundingBoxes != null) { List <IBoundingBox> suppressedBbs = Service.NonMaximalBoundingBoxSuppress(detectorBoundingBoxes); // if there is a single detection, reinitialize the tracker if (suppressedBbs.Count == 1) { output = suppressedBbs[0]; reinitializeTracker = true; currValid = false; } } } if (output != null) { if (prevValid == true) { currValid = true; } else { Image <Gray, byte> outputPatch = frame.GetPatch(output.Center, Size.Round(output.Size)) .Resize(_objectModel.PatchSize.Width, _objectModel.PatchSize.Height, INTER.CV_INTER_LINEAR); float pnn, nnn; float conservativeSimilarity = _objectModel.ConservativeSimilarity(outputPatch, out pnn, out nnn); if (pnn > 0.8f && conservativeSimilarity >= ConsSimValidThreshold) { currValid = true; } } } return(output); }