/// <summary> /// Applying an appropriate non-linear transformation to the gradient field inside /// the selection and then integrating back with a Poisson solver, modifies locally /// the apparent illumination of an image. /// </summary> /// <param name="src">Input 8-bit 3-channel image.</param> /// <param name="mask">Input 8-bit 1 or 3-channel image.</param> /// <param name="dst">Output image with the same size and type as src.</param> /// <param name="alpha">Value ranges between 0-2.</param> /// <param name="beta">Value ranges between 0-2.</param> /// <remarks> /// This is useful to highlight under-exposed foreground objects or to reduce specular reflections. /// </remarks> public static void IlluminationChange( InputArray src, InputArray mask, OutputArray dst, float alpha = 0.2f, float beta = 0.4f) { if (src == null) { throw new ArgumentNullException(nameof(src)); } if (dst == null) { throw new ArgumentNullException(nameof(dst)); } src.ThrowIfDisposed(); dst.ThrowIfNotReady(); mask?.ThrowIfDisposed(); NativeMethods.HandleException( NativeMethods.photo_illuminationChange( src.CvPtr, ToPtr(mask), dst.CvPtr, alpha, beta)); GC.KeepAlive(src); GC.KeepAlive(mask); dst.Fix(); }
/// <summary> /// By retaining only the gradients at edge locations, before integrating with the /// Poisson solver, one washes out the texture of the selected region, giving its /// contents a flat aspect. Here Canny Edge Detector is used. /// </summary> /// <param name="src">Input 8-bit 3-channel image.</param> /// <param name="mask">Input 8-bit 1 or 3-channel image.</param> /// <param name="dst">Output image with the same size and type as src.</param> /// <param name="lowThreshold">Range from 0 to 100.</param> /// <param name="highThreshold">Value > 100.</param> /// <param name="kernelSize">The size of the Sobel kernel to be used.</param> public static void TextureFlattening( InputArray src, InputArray mask, OutputArray dst, float lowThreshold = 30, float highThreshold = 45, int kernelSize = 3) { if (src == null) { throw new ArgumentNullException(nameof(src)); } if (dst == null) { throw new ArgumentNullException(nameof(dst)); } src.ThrowIfDisposed(); dst.ThrowIfNotReady(); mask?.ThrowIfDisposed(); NativeMethods.HandleException( NativeMethods.photo_textureFlattening( src.CvPtr, ToPtr(mask), dst.CvPtr, lowThreshold, highThreshold, kernelSize)); GC.KeepAlive(src); GC.KeepAlive(mask); dst.Fix(); }
/// <summary> /// Detects keypoints and computes the descriptors /// </summary> /// <param name="image"></param> /// <param name="mask"></param> /// <param name="keypoints"></param> /// <param name="descriptors"></param> /// <param name="useProvidedKeypoints"></param> public virtual void DetectAndCompute( InputArray image, InputArray?mask, out KeyPoint[] keypoints, OutputArray descriptors, bool useProvidedKeypoints = false) { ThrowIfDisposed(); if (image == null) { throw new ArgumentNullException(nameof(image)); } if (descriptors == null) { throw new ArgumentNullException(nameof(descriptors)); } image.ThrowIfDisposed(); mask?.ThrowIfDisposed(); using (var keypointsVec = new VectorOfKeyPoint()) { NativeMethods.features2d_Feature2D_detectAndCompute( ptr, image.CvPtr, Cv2.ToPtr(mask), keypointsVec.CvPtr, descriptors.CvPtr, useProvidedKeypoints ? 1 : 0); keypoints = keypointsVec.ToArray(); } GC.KeepAlive(this); GC.KeepAlive(image); GC.KeepAlive(mask); descriptors.Fix(); GC.KeepAlive(descriptors); }
/// <summary> /// Image editing tasks concern either global changes (color/intensity corrections, /// filters, deformations) or local changes concerned to a selection. Here we are /// interested in achieving local changes, ones that are restricted to a region /// manually selected (ROI), in a seamless and effortless manner. The extent of /// the changes ranges from slight distortions to complete replacement by novel /// content @cite PM03 . /// </summary> /// <param name="src">Input 8-bit 3-channel image.</param> /// <param name="dst">Input 8-bit 3-channel image.</param> /// <param name="mask">Input 8-bit 1 or 3-channel image.</param> /// <param name="p">Point in dst image where object is placed.</param> /// <param name="blend">Output image with the same size and type as dst.</param> /// <param name="flags">Cloning method</param> public static void SeamlessClone( InputArray src, InputArray dst, InputArray mask, Point p, OutputArray blend, SeamlessCloneMethods flags) { if (src == null) { throw new ArgumentNullException(nameof(src)); } if (dst == null) { throw new ArgumentNullException(nameof(dst)); } if (blend == null) { throw new ArgumentNullException(nameof(blend)); } src.ThrowIfDisposed(); dst.ThrowIfDisposed(); mask?.ThrowIfDisposed(); blend.ThrowIfNotReady(); NativeMethods.HandleException( NativeMethods.photo_seamlessClone( src.CvPtr, dst.CvPtr, ToPtr(mask), p, blend.CvPtr, (int)flags)); GC.KeepAlive(src); GC.KeepAlive(dst); GC.KeepAlive(mask); blend.Fix(); }
/// <summary> /// Estimate the Gaussian mixture parameters from a samples set. /// </summary> /// <param name="samples">Samples from which the Gaussian mixture model will be estimated. It should be a /// one-channel matrix, each row of which is a sample. If the matrix does not have CV_64F type /// it will be converted to the inner matrix of such type for the further computing.</param> /// <param name="means0">Initial means \f$a_k\f$ of mixture components. It is a one-channel matrix of /// \f$nclusters \times dims\f$ size. If the matrix does not have CV_64F type it will be /// converted to the inner matrix of such type for the further computing.</param> /// <param name="covs0">The vector of initial covariance matrices \f$S_k\f$ of mixture components. Each of /// covariance matrices is a one-channel matrix of \f$dims \times dims\f$ size. If the matrices /// do not have CV_64F type they will be converted to the inner matrices of such type for the further computing.</param> /// <param name="weights0">Initial weights \f$\pi_k\f$ of mixture components. It should be a one-channel /// floating-point matrix with \f$1 \times nclusters\f$ or \f$nclusters \times 1\f$ size.</param> /// <param name="logLikelihoods">The optional output matrix that contains a likelihood logarithm value for /// each sample. It has \f$nsamples \times 1\f$ size and CV_64FC1 type.</param> /// <param name="labels">The optional output "class label" for each sample: /// \f$\texttt{labels}_i=\texttt{arg max}_k(p_{i,k}), i=1..N\f$ (indices of the most probable /// mixture component for each sample). It has \f$nsamples \times 1\f$ size and CV_32SC1 type.</param> /// <param name="probs">The optional output matrix that contains posterior probabilities of each Gaussian /// mixture component given the each sample. It has \f$nsamples \times nclusters\f$ size and CV_64FC1 type.</param> public virtual bool TrainE( InputArray samples, InputArray means0, InputArray?covs0 = null, InputArray?weights0 = null, OutputArray?logLikelihoods = null, OutputArray?labels = null, OutputArray?probs = null) { ThrowIfDisposed(); if (samples == null) { throw new ArgumentNullException(nameof(samples)); } if (means0 == null) { throw new ArgumentNullException(nameof(means0)); } samples.ThrowIfDisposed(); means0.ThrowIfDisposed(); logLikelihoods?.ThrowIfNotReady(); covs0?.ThrowIfDisposed(); weights0?.ThrowIfDisposed(); labels?.ThrowIfNotReady(); probs?.ThrowIfNotReady(); NativeMethods.HandleException( NativeMethods.ml_EM_trainE( ptr, samples.CvPtr, means0.CvPtr, Cv2.ToPtr(covs0), Cv2.ToPtr(weights0), Cv2.ToPtr(logLikelihoods), Cv2.ToPtr(labels), Cv2.ToPtr(probs), out var ret)); logLikelihoods?.Fix(); labels?.Fix(); probs?.Fix(); GC.KeepAlive(this); GC.KeepAlive(samples); GC.KeepAlive(means0); GC.KeepAlive(covs0); GC.KeepAlive(weights0); GC.KeepAlive(logLikelihoods); GC.KeepAlive(labels); GC.KeepAlive(probs); return(ret != 0); }
/// <summary> /// Finds the geometric transform (warp) between two images in terms of the ECC criterion @cite EP08 . /// </summary> /// <param name="templateImage">single-channel template image; CV_8U or CV_32F array.</param> /// <param name="inputImage">single-channel input image which should be warped with the final warpMatrix in /// order to provide an image similar to templateImage, same type as templateImage.</param> /// <param name="warpMatrix">floating-point \f$2\times 3\f$ or \f$3\times 3\f$ mapping matrix (warp).</param> /// <param name="motionType">parameter, specifying the type of motion</param> /// <param name="criteria">parameter, specifying the termination criteria of the ECC algorithm; /// criteria.epsilon defines the threshold of the increment in the correlation coefficient between two /// iterations(a negative criteria.epsilon makes criteria.maxcount the only termination criterion). /// Default values are shown in the declaration above.</param> /// <param name="inputMask">An optional mask to indicate valid values of inputImage.</param> /// <returns></returns> public static double FindTransformECC( InputArray templateImage, InputArray inputImage, InputOutputArray warpMatrix, MotionTypes motionType = MotionTypes.Affine, TermCriteria?criteria = null, InputArray?inputMask = null) { if (templateImage == null) { throw new ArgumentNullException(nameof(templateImage)); } if (inputImage == null) { throw new ArgumentNullException(nameof(inputImage)); } if (warpMatrix == null) { throw new ArgumentNullException(nameof(warpMatrix)); } templateImage.ThrowIfDisposed(); inputImage.ThrowIfDisposed(); warpMatrix.ThrowIfDisposed(); inputMask?.ThrowIfDisposed(); var criteriaValue = criteria.GetValueOrDefault(new TermCriteria(CriteriaType.Count | CriteriaType.Eps, 50, 0.001)); NativeMethods.HandleException( NativeMethods.video_findTransformECC2( templateImage.CvPtr, inputImage.CvPtr, warpMatrix.CvPtr, (int)motionType, criteriaValue, inputMask?.CvPtr ?? IntPtr.Zero, out var ret)); GC.KeepAlive(templateImage); GC.KeepAlive(inputImage); GC.KeepAlive(warpMatrix); GC.KeepAlive(inputMask); return(ret); }
/// <summary> /// Finds the geometric transform (warp) between two images in terms of the ECC criterion @cite EP08 . /// </summary> /// <param name="templateImage">single-channel template image; CV_8U or CV_32F array.</param> /// <param name="inputImage">single-channel input image which should be warped with the final warpMatrix in /// order to provide an image similar to templateImage, same type as templateImage.</param> /// <param name="warpMatrix">floating-point \f$2\times 3\f$ or \f$3\times 3\f$ mapping matrix (warp).</param> /// <param name="motionType">parameter, specifying the type of motion</param> /// <param name="criteria">parameter, specifying the termination criteria of the ECC algorithm; /// criteria.epsilon defines the threshold of the increment in the correlation coefficient between two /// iterations(a negative criteria.epsilon makes criteria.maxcount the only termination criterion). /// Default values are shown in the declaration above.</param> /// <param name="inputMask">An optional mask to indicate valid values of inputImage.</param> /// <param name="gaussFiltSize">An optional value indicating size of gaussian blur filter; (DEFAULT: 5)</param> /// <returns></returns> public static double FindTransformECC( InputArray templateImage, InputArray inputImage, InputOutputArray warpMatrix, MotionTypes motionType, TermCriteria criteria, InputArray?inputMask = null, int gaussFiltSize = 5) { if (templateImage == null) { throw new ArgumentNullException(nameof(templateImage)); } if (inputImage == null) { throw new ArgumentNullException(nameof(inputImage)); } if (warpMatrix == null) { throw new ArgumentNullException(nameof(warpMatrix)); } templateImage.ThrowIfDisposed(); inputImage.ThrowIfDisposed(); warpMatrix.ThrowIfDisposed(); inputMask?.ThrowIfDisposed(); NativeMethods.HandleException( NativeMethods.video_findTransformECC1( templateImage.CvPtr, inputImage.CvPtr, warpMatrix.CvPtr, (int)motionType, criteria, inputMask?.CvPtr ?? IntPtr.Zero, gaussFiltSize, out var ret)); GC.KeepAlive(templateImage); GC.KeepAlive(inputImage); GC.KeepAlive(warpMatrix); GC.KeepAlive(inputMask); return(ret); }
/// <summary> /// Computes the Enhanced Correlation Coefficient value between two images @cite EP08 . /// </summary> /// <param name="templateImage">single-channel template image; CV_8U or CV_32F array.</param> /// <param name="inputImage">single-channel input image to be warped to provide an image similar to templateImage, same type as templateImage.</param> /// <param name="inputMask">An optional mask to indicate valid values of inputImage.</param> /// <returns></returns> public static double ComputeECC(InputArray templateImage, InputArray inputImage, InputArray?inputMask = null) { if (templateImage == null) { throw new ArgumentNullException(nameof(templateImage)); } if (inputImage == null) { throw new ArgumentNullException(nameof(inputImage)); } templateImage.ThrowIfDisposed(); inputImage.ThrowIfDisposed(); inputMask?.ThrowIfDisposed(); NativeMethods.HandleException( NativeMethods.video_computeECC( templateImage.CvPtr, inputImage.CvPtr, inputMask?.CvPtr ?? IntPtr.Zero, out var ret)); GC.KeepAlive(templateImage); GC.KeepAlive(inputImage); GC.KeepAlive(inputMask); return(ret); }
/// <summary> /// Given an original color image, two differently colored versions of this /// image can be mixed seamlessly. Multiplication factor is between 0.5 to 2.5. /// </summary> /// <param name="src">Input 8-bit 3-channel image.</param> /// <param name="mask">Input 8-bit 1 or 3-channel image.</param> /// <param name="dst">Output image with the same size and type as src.</param> /// <param name="redMul">R-channel multiply factor.</param> /// <param name="greenMul">G-channel multiply factor.</param> /// <param name="blueMul">B-channel multiply factor.</param> public static void ColorChange( InputArray src, InputArray mask, OutputArray dst, float redMul = 1.0f, float greenMul = 1.0f, float blueMul = 1.0f) { if (src == null) { throw new ArgumentNullException(nameof(src)); } if (dst == null) { throw new ArgumentNullException(nameof(dst)); } src.ThrowIfDisposed(); dst.ThrowIfNotReady(); mask?.ThrowIfDisposed(); NativeMethods.photo_colorChange( src.CvPtr, ToPtr(mask), dst.CvPtr, redMul, greenMul, blueMul); GC.KeepAlive(src); GC.KeepAlive(mask); dst.Fix(); }
/// <summary> /// Filtering is the fundamental operation in image and video processing. /// Edge-preserving smoothing filters are used in many different applications @cite EM11 . /// </summary> /// <param name="src">Input 8-bit 3-channel image.</param> /// <param name="dst">Output 8-bit 3-channel image.</param> /// <param name="flags">Edge preserving filters</param> /// <param name="sigmaS">Range between 0 to 200.</param> /// <param name="sigmaR">Range between 0 to 1.</param> public static void EdgePreservingFilter( InputArray src, OutputArray dst, EdgePreservingMethods flags = EdgePreservingMethods.RecursFilter, float sigmaS = 60, float sigmaR = 0.4f) { if (src == null) { throw new ArgumentNullException(nameof(src)); } if (dst == null) { throw new ArgumentNullException(nameof(dst)); } src.ThrowIfDisposed(); dst.ThrowIfNotReady(); NativeMethods.HandleException( NativeMethods.photo_edgePreservingFilter( src.CvPtr, dst.CvPtr, (int)flags, sigmaS, sigmaR)); GC.KeepAlive(src); dst.Fix(); }
/// <summary> /// find template on image /// </summary> /// <param name="edges"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="positions"></param> /// <param name="votes"></param> public virtual void Detect( InputArray edges, InputArray dx, InputArray dy, OutputArray positions, OutputArray?votes = null) { if (edges == null) { throw new ArgumentNullException(nameof(edges)); } if (dx == null) { throw new ArgumentNullException(nameof(dx)); } if (dy == null) { throw new ArgumentNullException(nameof(dy)); } if (positions == null) { throw new ArgumentNullException(nameof(positions)); } edges.ThrowIfDisposed(); dx.ThrowIfDisposed(); dy.ThrowIfDisposed(); positions.ThrowIfNotReady(); votes?.ThrowIfNotReady(); NativeMethods.imgproc_GeneralizedHough_detect2( ptr, edges.CvPtr, dx.CvPtr, dy.CvPtr, positions.CvPtr, Cv2.ToPtr(votes)); GC.KeepAlive(this); GC.KeepAlive(edges); GC.KeepAlive(dx); GC.KeepAlive(dy); GC.KeepAlive(positions); GC.KeepAlive(votes); positions.Fix(); votes?.Fix(); }
/// <summary> /// find template on image /// </summary> /// <param name="image"></param> /// <param name="positions"></param> /// <param name="votes"></param> public virtual void Detect( InputArray image, OutputArray positions, OutputArray?votes = null) { if (image == null) { throw new ArgumentNullException(nameof(image)); } if (positions == null) { throw new ArgumentNullException(nameof(positions)); } image.ThrowIfDisposed(); positions.ThrowIfNotReady(); votes?.ThrowIfNotReady(); NativeMethods.imgproc_GeneralizedHough_detect1( ptr, image.CvPtr, positions.CvPtr, Cv2.ToPtr(votes)); GC.KeepAlive(this); GC.KeepAlive(image); GC.KeepAlive(positions); GC.KeepAlive(votes); positions.Fix(); votes?.Fix(); }
/// <summary> /// Constructs a pyramid which can be used as input for calcOpticalFlowPyrLK /// </summary> /// <param name="img">8-bit input image.</param> /// <param name="pyramid">output pyramid.</param> /// <param name="winSize">window size of optical flow algorithm. /// Must be not less than winSize argument of calcOpticalFlowPyrLK(). /// It is needed to calculate required padding for pyramid levels.</param> /// <param name="maxLevel">0-based maximal pyramid level number.</param> /// <param name="withDerivatives">set to precompute gradients for the every pyramid level. /// If pyramid is constructed without the gradients then calcOpticalFlowPyrLK() will /// calculate them internally.</param> /// <param name="pyrBorder">the border mode for pyramid layers.</param> /// <param name="derivBorder">the border mode for gradients.</param> /// <param name="tryReuseInputImage">put ROI of input image into the pyramid if possible. /// You can pass false to force data copying.</param> /// <returns>number of levels in constructed pyramid. Can be less than maxLevel.</returns> public static int BuildOpticalFlowPyramid( InputArray img, out Mat[] pyramid, Size winSize, int maxLevel, bool withDerivatives = true, BorderTypes pyrBorder = BorderTypes.Reflect101, BorderTypes derivBorder = BorderTypes.Constant, bool tryReuseInputImage = true) { if (img == null) { throw new ArgumentNullException(nameof(img)); } img.ThrowIfDisposed(); using (var pyramidVec = new VectorOfMat()) { int result = NativeMethods.video_buildOpticalFlowPyramid2( img.CvPtr, pyramidVec.CvPtr, winSize, maxLevel, withDerivatives ? 1 : 0, (int)pyrBorder, (int)derivBorder, tryReuseInputImage ? 1 : 0); GC.KeepAlive(img); pyramid = pyramidVec.ToArray(); return(result); } }
/// <summary> /// サンプル集合からガウス混合パラメータを推定する /// </summary> /// <param name="samples"></param> /// <param name="means0"></param> /// <param name="covs0"></param> /// <param name="weights0"></param> /// <param name="logLikelihoods"></param> /// <param name="labels"></param> /// <param name="probs"></param> #else /// <summary> /// Estimates Gaussian mixture parameters from the sample set /// </summary> /// <param name="samples"></param> /// <param name="means0"></param> /// <param name="covs0"></param> /// <param name="weights0"></param> /// <param name="logLikelihoods"></param> /// <param name="labels"></param> /// <param name="probs"></param> #endif public virtual bool TrainE( InputArray samples, InputArray means0, InputArray covs0 = null, InputArray weights0 = null, OutputArray logLikelihoods = null, OutputArray labels = null, OutputArray probs = null) { if (disposed) { throw new ObjectDisposedException(GetType().Name); } if (samples == null) { throw new ArgumentNullException(nameof(samples)); } if (means0 == null) { throw new ArgumentNullException(nameof(means0)); } samples.ThrowIfDisposed(); means0.ThrowIfDisposed(); if (logLikelihoods != null) { logLikelihoods.ThrowIfNotReady(); } if (covs0 != null) { covs0.ThrowIfDisposed(); } if (weights0 != null) { weights0.ThrowIfDisposed(); } if (labels != null) { labels.ThrowIfNotReady(); } if (probs != null) { probs.ThrowIfNotReady(); } int ret = NativeMethods.ml_EM_trainE( ptr, samples.CvPtr, means0.CvPtr, Cv2.ToPtr(covs0), Cv2.ToPtr(weights0), Cv2.ToPtr(logLikelihoods), Cv2.ToPtr(labels), Cv2.ToPtr(probs)); if (logLikelihoods != null) { logLikelihoods.Fix(); } if (labels != null) { labels.Fix(); } if (probs != null) { probs.Fix(); } GC.KeepAlive(samples); GC.KeepAlive(means0); GC.KeepAlive(covs0); GC.KeepAlive(weights0); return(ret != 0); }