/// <summary> /// Detect ChArUco Diamond markers. /// </summary> /// <param name="image">input image necessary for corner subpixel.</param> /// <param name="markerCorners">list of detected marker corners from detectMarkers function.</param> /// <param name="markerIds">list of marker ids in markerCorners.</param> /// <param name="squareMarkerLengthRate">rate between square and marker length: squareMarkerLengthRate = squareLength/markerLength. The real units are not necessary.</param> /// <param name="diamondCorners">output list of detected diamond corners (4 corners per diamond). The order is the same than in marker corners: top left, top right, bottom right and bottom left. Similar format than the corners returned by detectMarkers (e.g std::vector<std::vector<cv::Point2f>>).</param> /// <param name="diamondIds">ids of the diamonds in diamondCorners. The id of each diamond is in fact of type Vec4i, so each diamond has 4 ids, which are the ids of the aruco markers composing the diamond.</param> /// <param name="cameraMatrix">Optional camera calibration matrix.</param> /// <param name="distCoeffs">Optional camera distortion coefficients.</param> public static void DetectCharucoDiamond(InputArray image, Point2f[][] markerCorners, IEnumerable <int> markerIds, float squareMarkerLengthRate, out Point2f[][] diamondCorners, out Vec4i[] diamondIds, InputArray?cameraMatrix = null, InputArray?distCoeffs = null) { if (image == null) { throw new ArgumentNullException(nameof(image)); } if (markerCorners == null) { throw new ArgumentNullException(nameof(markerCorners)); } if (markerIds == null) { throw new ArgumentNullException(nameof(markerIds)); } if (cameraMatrix == null && distCoeffs != null) { throw new ArgumentNullException(nameof(cameraMatrix)); } if (cameraMatrix != null && distCoeffs == null) { throw new ArgumentNullException(nameof(distCoeffs)); } image.ThrowIfDisposed(); cameraMatrix?.ThrowIfDisposed(); distCoeffs?.ThrowIfDisposed(); using var markerCornersAddress = new ArrayAddress2 <Point2f>(markerCorners); using var markerIdsVec = new VectorOfInt32(markerIds); using var diamondCornersVec = new VectorOfVectorPoint2f(); using var diamondIdsVec = new VectorOfVec4i(); NativeMethods.HandleException( NativeMethods.aruco_detectCharucoDiamond( image.CvPtr, markerCornersAddress.GetPointer(), markerCornersAddress.GetDim1Length(), markerCornersAddress.GetDim2Lengths(), markerIdsVec.CvPtr, squareMarkerLengthRate, diamondCornersVec.CvPtr, diamondIdsVec.CvPtr, cameraMatrix?.CvPtr ?? IntPtr.Zero, distCoeffs?.CvPtr ?? IntPtr.Zero)); diamondCorners = diamondCornersVec.ToArray(); diamondIds = diamondIdsVec.ToArray(); GC.KeepAlive(image); if (cameraMatrix != null) { GC.KeepAlive(cameraMatrix); } if (distCoeffs != null) { GC.KeepAlive(distCoeffs); } }
/// <summary> /// Downloads results from cuda::HoughLinesDetector::detect to host memory. /// </summary> /// <param name="d_lines">Result of cuda::HoughLinesDetector::detect .</param> /// <param name="h_lines">Output host array.</param> /// <param name="stream">Stream for the asynchronous version.</param> public virtual void downloadResults(InputArray d_lines, out LineSegmentPoint[] h_lines, Stream stream = null) { if (d_lines == null) { throw new ArgumentNullException(nameof(d_lines)); } d_lines.ThrowIfDisposed(); using (var vec = new VectorOfVec4i()) { NativeMethods.cuda_imgproc_HoughSegmentDetector_downloadResults(ptr, d_lines.CvPtr, vec.CvPtr , stream?.CvPtr ?? Stream.Null.CvPtr); h_lines = vec.ToArray <LineSegmentPoint>(); } GC.KeepAlive(this); GC.KeepAlive(d_lines); GC.KeepAlive(h_lines); }
/// <summary> /// 確率的ハフ変換を利用して,2値画像から線分を検出します. /// </summary> /// <param name="image">8ビット,シングルチャンネルの2値入力画像.この画像は関数により書き換えられる可能性があります</param> /// <param name="rho">ピクセル単位で表される投票空間の距離分解能</param> /// <param name="theta">ラジアン単位で表される投票空間の角度分解能</param> /// <param name="threshold">投票の閾値パラメータ.十分な票( > threshold )を得た直線のみが出力されます</param> /// <param name="minLineLength">最小の線分長.これより短い線分は棄却されます. [既定値は0]</param> /// <param name="maxLineGap">2点が同一線分上にあると見なす場合に許容される最大距離. [既定値は0]</param> /// <returns>検出された線分.各線分は,4要素のベクトル (x1, y1, x2, y2) で表現されます.</returns> #else /// <summary> /// Finds lines segments in a binary image using probabilistic Hough transform. /// </summary> /// <param name="image"></param> /// <param name="rho">Distance resolution of the accumulator in pixels</param> /// <param name="theta">Angle resolution of the accumulator in radians</param> /// <param name="threshold">The accumulator threshold parameter. Only those lines are returned that get enough votes ( > threshold )</param> /// <param name="minLineLength">The minimum line length. Line segments shorter than that will be rejected. [By default this is 0]</param> /// <param name="maxLineGap">The maximum allowed gap between points on the same line to link them. [By default this is 0]</param> /// <returns>The output lines. Each line is represented by a 4-element vector (x1, y1, x2, y2)</returns> #endif public static CvLineSegmentPoint[] HoughLinesP(InputArray image, double rho, double theta, int threshold, double minLineLength = 0, double maxLineGap = 0) { if (image == null) throw new ArgumentNullException("image"); image.ThrowIfDisposed(); using (var vec = new VectorOfVec4i()) { NativeMethods.imgproc_HoughLinesP(image.CvPtr, vec.CvPtr, rho, theta, threshold, minLineLength, maxLineGap); return vec.ToArray<CvLineSegmentPoint>(); } }
/// <summary> /// Computes the contour convexity defects /// </summary> /// <param name="contour">Input contour.</param> /// <param name="convexHull">Convex hull obtained using convexHull() that /// should contain indices of the contour points that make the hull.</param> /// <returns>The output vector of convexity defects. /// Each convexity defect is represented as 4-element integer vector /// (a.k.a. cv::Vec4i): (start_index, end_index, farthest_pt_index, fixpt_depth), /// where indices are 0-based indices in the original contour of the convexity defect beginning, /// end and the farthest point, and fixpt_depth is fixed-point approximation /// (with 8 fractional bits) of the distance between the farthest contour point and the hull. /// That is, to get the floating-point value of the depth will be fixpt_depth/256.0. </returns> public static Vec4i[] ConvexityDefects(IEnumerable<Point2f> contour, IEnumerable<int> convexHull) { if (contour == null) throw new ArgumentNullException("contour"); if (convexHull == null) throw new ArgumentNullException("convexHull"); Point2f[] contourArray = EnumerableEx.ToArray(contour); int[] convexHullArray = EnumerableEx.ToArray(convexHull); IntPtr convexityDefectsPtr; NativeMethods.imgproc_convexityDefects_Point2f(contourArray, contourArray.Length, convexHullArray, convexHullArray.Length, out convexityDefectsPtr); using (var convexityDefects = new VectorOfVec4i(convexityDefectsPtr)) { return convexityDefects.ToArray(); } }
/// <summary> /// 2値画像中の輪郭を検出します. /// </summary> /// <param name="image">入力画像,8ビット,シングルチャンネル.0以外のピクセルは 1として,0のピクセルは0のまま扱われます. /// また,この関数は,輪郭抽出処理中に入力画像 image の中身を書き換えます.</param> /// <param name="contours">検出された輪郭.各輪郭は,点のベクトルとして格納されます.</param> /// <param name="hierarchy">画像のトポロジーに関する情報を含む出力ベクトル.これは,輪郭数と同じ数の要素を持ちます.各輪郭 contours[i] に対して, /// 要素 hierarchy[i]のメンバにはそれぞれ,同じ階層レベルに存在する前後の輪郭,最初の子輪郭,および親輪郭の /// contours インデックス(0 基準)がセットされます.また,輪郭 i において,前後,親,子の輪郭が存在しない場合, /// それに対応する hierarchy[i] の要素は,負の値になります.</param> /// <param name="mode">輪郭抽出モード</param> /// <param name="method">輪郭の近似手法</param> /// <param name="offset">オプションのオフセット.各輪郭点はこの値の分だけシフトします.これは,ROIの中で抽出された輪郭を,画像全体に対して位置づけて解析する場合に役立ちます.</param> #else /// <summary> /// Finds contours in a binary image. /// </summary> /// <param name="image">Source, an 8-bit single-channel image. Non-zero pixels are treated as 1’s. /// Zero pixels remain 0’s, so the image is treated as binary. /// The function modifies the image while extracting the contours.</param> /// <param name="contours">Detected contours. Each contour is stored as a vector of points.</param> /// <param name="hierarchy">Optional output vector, containing information about the image topology. /// It has as many elements as the number of contours. For each i-th contour contours[i], /// the members of the elements hierarchy[i] are set to 0-based indices in contours of the next /// and previous contours at the same hierarchical level, the first child contour and the parent contour, respectively. /// If for the contour i there are no next, previous, parent, or nested contours, the corresponding elements of hierarchy[i] will be negative.</param> /// <param name="mode">Contour retrieval mode</param> /// <param name="method">Contour approximation method</param> /// <param name="offset"> Optional offset by which every contour point is shifted. /// This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context.</param> #endif public static void FindContours(InputOutputArray image, out Point[][] contours, out HierarchyIndex[] hierarchy, ContourRetrieval mode, ContourChain method, Point? offset = null) { if (image == null) throw new ArgumentNullException("image"); image.ThrowIfNotReady(); CvPoint offset0 = offset.GetValueOrDefault(new Point()); IntPtr contoursPtr, hierarchyPtr; NativeMethods.imgproc_findContours1_vector(image.CvPtr, out contoursPtr, out hierarchyPtr, (int)mode, (int)method, offset0); using (var contoursVec = new VectorOfVectorPoint(contoursPtr)) using (var hierarchyVec = new VectorOfVec4i(hierarchyPtr)) { contours = contoursVec.ToArray(); Vec4i[] hierarchyOrg = hierarchyVec.ToArray(); hierarchy = EnumerableEx.SelectToArray(hierarchyOrg, HierarchyIndex.FromVec4i); } image.Fix(); }