/// <summary> /// Apply cascade to an input frame and return the array of decection objects. /// </summary> /// <param name="image">A frame on which detector will be applied.</param> /// <param name="rois">A regions of interests mask generated by genRoi. Only the objects that fall into one of the regions will be returned.</param> /// <param name="stream">Use a Stream to call the function asynchronously (non-blocking) or null to call the function synchronously (blocking).</param> /// <returns>An array of decection objects</returns> public GpuMat Detect(CudaImage <Bgr, Byte> image, GpuMat <int> rois, Emgu.CV.Cuda.Stream stream = null) { GpuMat result = new GpuMat(); SoftCascadeInvoke.cudaSoftCascadeDetectorDetect(_ptr, image, rois, result, stream); return(result); }
/// <summary> /// Finds matching points in the faces using SURF /// </summary> /// <param name="modelImage"> /// The model image. /// </param> /// <param name="observedImage"> /// The observed image. /// </param> /// <param name="matchTime"> /// The match time. /// </param> /// <param name="modelKeyPoints"> /// The model key points. /// </param> /// <param name="observedKeyPoints"> /// The observed key points. /// </param> /// <param name="matches"> /// The matches. /// </param> /// <param name="mask"> /// The mask. /// </param> /// <param name="homography"> /// The homography. /// </param> /// <param name="score"> /// The score. /// </param> private void FindMatch( Mat modelImage, Mat observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, VectorOfVectorOfDMatch matches, out Mat mask, out Mat homography, out long score) { int k = 2; double uniquenessThreshold = 5; Stopwatch watch; homography = null; mask = null; score = 0; modelKeyPoints = new VectorOfKeyPoint(); observedKeyPoints = new VectorOfKeyPoint(); if (Controller.Instance.Cuda) { CudaSURF surfGPU = new CudaSURF(700f, 4, 2, false); using (CudaImage <Gray, byte> gpuModelImage = new CudaImage <Gray, byte>(modelImage)) //extract features from the object image using (GpuMat gpuModelKeyPoints = surfGPU.DetectKeyPointsRaw(gpuModelImage, null)) using (GpuMat gpuModelDescriptors = surfGPU.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints)) using (CudaBFMatcher matcher = new CudaBFMatcher(DistanceType.L2)) { surfGPU.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints); watch = Stopwatch.StartNew(); // extract features from the observed image using (CudaImage <Gray, Byte> gpuObservedImage = new CudaImage <Gray, byte>(observedImage)) using (GpuMat gpuObservedKeyPoints = surfGPU.DetectKeyPointsRaw(gpuObservedImage, null)) using (GpuMat gpuObservedDescriptors = surfGPU.ComputeDescriptorsRaw( gpuObservedImage, null, gpuObservedKeyPoints)) using (GpuMat <int> gpuMatchIndices = new GpuMat <int>( gpuObservedDescriptors.Size.Height, k, 1, true)) using (GpuMat <float> gpuMatchDist = new GpuMat <float>( gpuObservedDescriptors.Size.Height, k, 1, true)) //using (GpuMat<Byte> gpuMask = new GpuMat<byte>(gpuMatchIndices.Size.Height, 1, 1)) using (Emgu.CV.Cuda.Stream stream = new Emgu.CV.Cuda.Stream()) { matcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k, null); //indices = new Matrix<int>(gpuMatchIndices.Size); //mask = new Matrix<byte>(gpuMask.Size); mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1); mask.SetTo(new MCvScalar(255)); surfGPU.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints); /*//gpu implementation of voteForUniquess * using (GpuMat col0 = gpuMatchDist.Col(0)) * using (GpuMat col1 = gpuMatchDist.Col(1)) * { * CudaInvoke.Multiply(col1, new GpuMat(), col1, 1, DepthType.Default, stream); * CudaInvoke.Compare(col0, col1, mask, CmpType.LessEqual, stream); * }*/ Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask); //wait for the stream to complete its tasks //We can perform some other CPU intesive stuffs here while we are waiting for the stream to complete. stream.WaitForCompletion(); //gpuMatchIndices.Download(indices); if (CudaInvoke.CountNonZero(mask) >= 4) { int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation( modelKeyPoints, observedKeyPoints, matches, mask, 1.5, 20); if (nonZeroCount >= 4) { homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures( modelKeyPoints, observedKeyPoints, matches, mask, 2); } } watch.Stop(); } for (int i = 0; i < matches.Size; i++) { score++; } } } //else //{ // SURF surfCPU = new SURF(500, 4, 2, false); // //extract features from the object image // modelKeyPoints = new VectorOfKeyPoint(); // Matrix<float> modelDescriptors = surfCPU.DetectAndCompute(modelImage, null, modelKeyPoints); // watch = Stopwatch.StartNew(); // // extract features from the observed image // observedKeyPoints = new VectorOfKeyPoint(); // Matrix<float> observedDescriptors = surfCPU.DetectAndCompute(observedImage, null, observedKeyPoints); // BFMatcher matcher = new BFMatcher<float>(DistanceType.L2); // matcher.Add(modelDescriptors); // indices = new Matrix<int>(observedDescriptors.Rows, k); // using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k)) // { // matcher.KnnMatch(observedDescriptors, indices, dist, k, null); // mask = new Matrix<byte>(dist.Rows, 1); // mask.SetValue(255); // Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask); // } // int nonZeroCount = CvInvoke.cvCountNonZero(mask); // if (nonZeroCount >= 4) // { // nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); // if (nonZeroCount >= 4) // homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); // } // watch.Stop(); //} matchTime = 0; }