public static List <IBoundingBox> GenerateSimilarBoundingBoxes(Size frameSize, IBoundingBox refBb, SimilarBoundingBoxGenerationInfo info) { List <IBoundingBox> boundingBoxes = new List <IBoundingBox>(); for (int i = 0; i < info.Count; i++) { // calculate new center PointF newCenter; if (info.MaxShift != 0) { float relShift = (float)(_rand.NextDouble() * 2 - 1) * info.MaxShift; PointF absShift = new PointF(relShift * refBb.Size.Width, relShift * refBb.Size.Height); newCenter = refBb.Center.Add(absShift); } else { newCenter = refBb.Center; } // calculate new size SizeF newSize; if (info.MaxScale != 0) { float scale = 1.0f + (float)(_rand.NextDouble() * 2 - 1) * info.MaxScale; newSize = refBb.Size.Multiply(scale, scale); } else { newSize = refBb.Size; } // create new bounding box IBoundingBox newBb = refBb.CreateInstance(newCenter, newSize); // if bounding box is inside the frame, add it to collection if (newBb.InsideFrame(frameSize)) { boundingBoxes.Add(newBb); } } return(boundingBoxes); }
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; }