public void TestCudaFilters() { if (CudaInvoke.HasCuda) { Image <Gray, Byte> image = new Image <Gray, byte>(300, 400); image.SetRandUniform(new MCvScalar(0.0), new MCvScalar(255.0)); using (GpuMat cudaImg1 = new GpuMat(image)) using (GpuMat cudaImg2 = new GpuMat()) using (CudaGaussianFilter gaussian = new CudaGaussianFilter(DepthType.Cv8U, 1, DepthType.Cv8U, 1, new Size(5, 5), 0, 0, CvEnum.BorderType.Default, CvEnum.BorderType.Default)) using (CudaSobelFilter sobel = new CudaSobelFilter(DepthType.Cv8U, 1, DepthType.Cv8U, 1, 1, 1, 3, 1.0, CvEnum.BorderType.Default, CvEnum.BorderType.Default)) { gaussian.Apply(cudaImg1, cudaImg2, null); sobel.Apply(cudaImg1, cudaImg2, null); } } }
public static Bitmap PerformShapeDetection(Bitmap frame, ShapeDetectionVariables detectionVars) { StringBuilder msgBuilder = new StringBuilder("Performance: "); Image <Bgr, Byte> img = new Image <Bgr, byte>(frame); Mat MatImg = img.Mat; Mat outputImg = new Mat(); if (CudaInvoke.HasCuda) { using (GpuMat gMatSrc = new GpuMat()) using (GpuMat gMatDst = new GpuMat()) { gMatSrc.Upload(MatImg); CudaGaussianFilter noiseReducetion = new CudaGaussianFilter(MatImg.Depth, img.NumberOfChannels, MatImg.Depth, img.NumberOfChannels, new Size(1, 1), 0); noiseReducetion.Apply(gMatSrc, gMatDst); gMatDst.Download(outputImg); } } else { Mat pyrDown = new Mat(); CvInvoke.PyrDown(img, pyrDown); CvInvoke.PyrUp(pyrDown, img); outputImg = img.Mat; } UMat uimage = new UMat(); CvInvoke.CvtColor(outputImg, uimage, ColorConversion.Bgr2Gray); CircleF[] circles = new CircleF[0]; if (detectionVars.calcCircles) { circles = CvInvoke.HoughCircles( uimage, HoughType.Gradient, 1.0, 20.0, detectionVars.circleCannyThreshold, detectionVars.circleAccumulatorThreshold == 0 ? 1 : detectionVars.circleAccumulatorThreshold, detectionVars.minradius, detectionVars.maxRadius); } #region Canny and edge detection UMat cannyEdges = new UMat(); CvInvoke.Canny(uimage, cannyEdges, detectionVars.lineCannyThreshold, detectionVars.cannyThresholdLinking); LineSegment2D[] lines = new LineSegment2D[0]; if (detectionVars.calcLines) { lines = CvInvoke.HoughLinesP( cannyEdges, 1, //Distance resolution in pixel-related units Math.PI / 45.0, //Angle resolution measured in radians. detectionVars.lineThreshold, //threshold detectionVars.minLineWidth, //min Line width 10); //gap between lines } #endregion #region Find triangles and rectangles List <RotatedRect> boxList = new List <RotatedRect>(); //a box is a rotated rectangle if (detectionVars.calcRectTri) { using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); int count = contours.Size; for (int i = 0; i < count; i++) { using (VectorOfPoint contour = contours[i]) using (VectorOfPoint approxContour = new VectorOfPoint()) { CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true); if (CvInvoke.ContourArea(approxContour, false) > 250) //only consider contours with area greater than 250 { if (approxContour.Size == 4) //The contour has 4 vertices. { #region determine if all the angles in the contour are within [80, 100] degree bool isRectangle = true; Point[] pts = approxContour.ToArray(); LineSegment2D[] edges = PointCollection.PolyLine(pts, true); for (int j = 0; j < edges.Length; j++) { double angle = Math.Abs( edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j])); if (angle < 80 || angle > 100) { isRectangle = false; break; } } #endregion if (isRectangle) { boxList.Add(CvInvoke.MinAreaRect(approxContour)); } } } } } } } #endregion Image <Bgra, Byte> alphaImgShape = new Image <Bgra, byte>(img.Size.Width, img.Size.Height, new Bgra(0, 0, 0, .5)); Mat alphaimg = new Mat(); CvInvoke.CvtColor(img, alphaimg, ColorConversion.Bgr2Bgra); #region draw rectangles and triangles if (detectionVars.calcRectTri) { Image <Bgr, Byte> triangleRectangleImage = new Image <Bgr, Byte>(img.Size); foreach (RotatedRect box in boxList) { CvInvoke.Polylines(triangleRectangleImage, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(0, 255, 0).MCvScalar, 2); } CvInvoke.AddWeighted(alphaImgShape, .5, BlackTransparent(triangleRectangleImage), .5, 0, alphaImgShape); if (CudaInvoke.HasCuda) { using (GpuMat gMatSrc = new GpuMat()) using (GpuMat gMatSrc2 = new GpuMat()) using (GpuMat gMatDst = new GpuMat()) { gMatSrc.Upload(alphaimg); gMatSrc2.Upload(alphaImgShape); CudaInvoke.AlphaComp(gMatSrc, gMatSrc2, gMatDst, AlphaCompTypes.Plus); gMatDst.Download(alphaimg); } } else { img = Overlay(img, alphaImgShape); } } #endregion #region draw circles if (detectionVars.calcCircles) { Image <Bgr, Byte> circleImage = new Image <Bgr, Byte>(img.Size); foreach (CircleF circle in circles.Take(10)) { CvInvoke.Circle(circleImage, Point.Round(circle.Center), (int)circle.Radius, new Bgr(0, 255, 0).MCvScalar, 2); } alphaImgShape = new Image <Bgra, byte>(img.Size.Width, img.Size.Height, new Bgra(0, 0, 0, .5)); CvInvoke.AddWeighted(alphaImgShape, .7, BlackTransparent(circleImage), .5, 0, alphaImgShape); if (CudaInvoke.HasCuda) { using (GpuMat gMatSrc = new GpuMat()) using (GpuMat gMatSrc2 = new GpuMat()) using (GpuMat gMatDst = new GpuMat()) { gMatSrc.Upload(alphaimg); gMatSrc2.Upload(alphaImgShape); CudaInvoke.AlphaComp(gMatSrc, gMatSrc2, gMatDst, AlphaCompTypes.Plus); gMatDst.Download(alphaimg); } } else { img = Overlay(img, alphaImgShape); } } #endregion #region draw lines if (detectionVars.calcLines) { Image <Bgr, Byte> lineImage = new Image <Bgr, Byte>(img.Size); foreach (LineSegment2D line in lines) { CvInvoke.Line(lineImage, line.P1, line.P2, new Bgr(0, 255, 0).MCvScalar, 2); } alphaImgShape = new Image <Bgra, byte>(img.Size.Width, img.Size.Height, new Bgra(0, 0, 0, .5)); CvInvoke.AddWeighted(alphaImgShape, .5, BlackTransparent(lineImage), .5, 0, alphaImgShape); if (CudaInvoke.HasCuda) { using (GpuMat gMatSrc = new GpuMat()) using (GpuMat gMatSrc2 = new GpuMat()) using (GpuMat gMatDst = new GpuMat()) { gMatSrc.Upload(alphaimg); gMatSrc2.Upload(alphaImgShape); CudaInvoke.AlphaComp(gMatSrc, gMatSrc2, gMatDst, AlphaCompTypes.Plus); gMatDst.Download(alphaimg); } } else { img = Overlay(img, alphaImgShape); } } #endregion GC.Collect(); // first time I've had to use this but this program will use as much memory as possible, resulting in corrptions return(alphaimg.Bitmap ?? frame); }