public void FastHoughTransform() { using (var image = Image("building.jpg", ImreadModes.Grayscale)) using (var fht = new Mat()) { CvXImgProc.FastHoughTransform(image, fht, MatType.CV_32SC1); Cv2.MinMaxLoc(fht, out var minv, out double maxv); Mat ucharFht = new Mat(); fht.ConvertTo(ucharFht, MatType.CV_8UC1, 255.0 / (maxv + minv), minv / (maxv + minv)); Rescale(ucharFht, ucharFht); //Cv2.ImShow("fast hough transform", ucharFht); //Cv2.WaitKey(); }
public void FHTSample() { const string imPath = @"_data\image\building.jpg"; using (var image = new Mat(imPath, ImreadModes.GrayScale)) using (var hough = new Mat()) using (var canny = new Mat()) { Cv2.Canny(image, canny, 50, 200, 3); CvXImgProc.FastHoughTransform(canny, hough, MatType.CV_32S /*C1*/, AngleRangeOption.ARO_315_135, HoughOP.FHT_ADD, HoughDeskewOption.DESKEW); var lines = new List <Vec4i>(); GetLocalExtr(lines, canny, hough, 255f * 0.3f * Math.Min(canny.Rows, canny.Cols), 50); var cannyColor = new Mat(); Cv2.CvtColor(canny, cannyColor, ColorConversionCodes.GRAY2BGR); for (var i = 0; i < lines.Count; i++) { var line = lines[i]; Cv2.Line(cannyColor, new Point(line.Item0, line.Item1), new Point(line.Item2, line.Item3), Scalar.Red); } //cannyColor.SaveImage("cannycolor.png"); ShowImagesWhenDebugMode(image, canny, cannyColor); } bool GetLocalExtr(List <Vec4i> lines, Mat src, Mat fht, float minWeight, int maxCount) { const int MAX_LEN = 10_000; var weightedPoints = new List <KeyValuePair <int, Point> >(); for (var y = 0; y < fht.Rows; ++y) { if (weightedPoints.Count > MAX_LEN) { break; } var fhtMat = new MatOfInt(fht); var fhtIndexer = fhtMat.GetIndexer(); var pLineY = Math.Max(y - 1, 0); var cLineY = y; var nLineY = Math.Min(y + 1, fht.Rows - 1); for (var x = 0; x < fht.Cols; ++x) { if (weightedPoints.Count > MAX_LEN) { break; } var value = fhtIndexer[cLineY, x]; if (value >= minWeight) { var isLocalMax = 0; var start = Math.Max(x - 1, 0); var end = Math.Min(x + 1, fht.Cols - 1); for (var xx = start; xx < end; ++xx) { var pLine = fhtIndexer[pLineY, xx]; var cLine = fhtIndexer[cLineY, xx]; var nLine = fhtIndexer[nLineY, xx]; if (!incIfGreater(value, pLine, ref isLocalMax) || !incIfGreater(value, cLine, ref isLocalMax) || !incIfGreater(value, nLine, ref isLocalMax)) { isLocalMax = 0; break; } } if (isLocalMax > 0) { weightedPoints.Add(new KeyValuePair <int, Point>(value, new Point(x, y))); } } } } if (weightedPoints.Count == 0) { return(true); } // Sort WeightedPoints weightedPoints = weightedPoints.OrderByDescending(x => x.Key).ToList(); weightedPoints = weightedPoints.Take(maxCount).ToList(); for (var i = 0; i < weightedPoints.Count; i++) { lines.Add(CvXImgProc.HoughPoint2Line(weightedPoints[i].Value, src)); } return(true); } bool incIfGreater(int a, int b, ref int value) { if (/*value == 0 || */ a < b) { return(false); } if (a > b) { ++(value); } return(true); } }