using OpenCVForUnity.CoreModule; using OpenCVForUnity.UtilsModule; using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace OpenCVForUnity.ImgprocModule { // C++: class IntelligentScissorsMB /** * Intelligent Scissors image segmentation * * This class is used to find the path (contour) between two points * which can be used for image segmentation. * * Usage example: * SNIPPET: snippets/imgproc_segmentation.cpp usage_example_intelligent_scissors * * Reference: <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.138.3811&rep=rep1&type=pdf">"Intelligent Scissors for Image Composition"</a> * algorithm designed by Eric N. Mortensen and William A. Barrett, Brigham Young University * CITE: Mortensen95intelligentscissors */ public class IntelligentScissorsMB : DisposableOpenCVObject { protected override void Dispose(bool disposing) { try { if (disposing) { } if (IsEnabledDispose) { if (nativeObj != IntPtr.Zero) imgproc_IntelligentScissorsMB_delete(nativeObj); nativeObj = IntPtr.Zero; } } finally { base.Dispose(disposing); } } protected internal IntelligentScissorsMB(IntPtr addr) : base(addr) { } public IntPtr getNativeObjAddr() { return nativeObj; } // internal usage only public static IntelligentScissorsMB __fromPtr__(IntPtr addr) { return new IntelligentScissorsMB(addr); } // // C++: cv::segmentation::IntelligentScissorsMB::IntelligentScissorsMB() // public IntelligentScissorsMB() { nativeObj = DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_IntelligentScissorsMB_10()); } // // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::setWeights(float weight_non_edge, float weight_gradient_direction, float weight_gradient_magnitude) // /** * Specify weights of feature functions * * Consider keeping weights normalized (sum of weights equals to 1.0) * Discrete dynamic programming (DP) goal is minimization of costs between pixels. * * param weight_non_edge Specify cost of non-edge pixels (default: 0.43f) * param weight_gradient_direction Specify cost of gradient direction function (default: 0.43f) * param weight_gradient_magnitude Specify cost of gradient magnitude function (default: 0.14f) * return automatically generated */ public IntelligentScissorsMB setWeights(float weight_non_edge, float weight_gradient_direction, float weight_gradient_magnitude) { ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_setWeights_10(nativeObj, weight_non_edge, weight_gradient_direction, weight_gradient_magnitude))); } // // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::setGradientMagnitudeMaxLimit(float gradient_magnitude_threshold_max = 0.0f) // /** * Specify gradient magnitude max value threshold * * Zero limit value is used to disable gradient magnitude thresholding (default behavior, as described in original article). * Otherwize pixels with {code gradient magnitude >= threshold} have zero cost. * * Note: Thresholding should be used for images with irregular regions (to avoid stuck on parameters from high-contract areas, like embedded logos). * * param gradient_magnitude_threshold_max Specify gradient magnitude max value threshold (default: 0, disabled) * return automatically generated */ public IntelligentScissorsMB setGradientMagnitudeMaxLimit(float gradient_magnitude_threshold_max) { ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_setGradientMagnitudeMaxLimit_10(nativeObj, gradient_magnitude_threshold_max))); } /** * Specify gradient magnitude max value threshold * * Zero limit value is used to disable gradient magnitude thresholding (default behavior, as described in original article). * Otherwize pixels with {code gradient magnitude >= threshold} have zero cost. * * Note: Thresholding should be used for images with irregular regions (to avoid stuck on parameters from high-contract areas, like embedded logos). * * return automatically generated */ public IntelligentScissorsMB setGradientMagnitudeMaxLimit() { ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_setGradientMagnitudeMaxLimit_11(nativeObj))); } // // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::setEdgeFeatureZeroCrossingParameters(float gradient_magnitude_min_value = 0.0f) // /** * Switch to "Laplacian Zero-Crossing" edge feature extractor and specify its parameters * * This feature extractor is used by default according to article. * * Implementation has additional filtering for regions with low-amplitude noise. * This filtering is enabled through parameter of minimal gradient amplitude (use some small value 4, 8, 16). * * Note: Current implementation of this feature extractor is based on processing of grayscale images (color image is converted to grayscale image first). * * Note: Canny edge detector is a bit slower, but provides better results (especially on color images): use setEdgeFeatureCannyParameters(). * * param gradient_magnitude_min_value Minimal gradient magnitude value for edge pixels (default: 0, check is disabled) * return automatically generated */ public IntelligentScissorsMB setEdgeFeatureZeroCrossingParameters(float gradient_magnitude_min_value) { ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_setEdgeFeatureZeroCrossingParameters_10(nativeObj, gradient_magnitude_min_value))); } /** * Switch to "Laplacian Zero-Crossing" edge feature extractor and specify its parameters * * This feature extractor is used by default according to article. * * Implementation has additional filtering for regions with low-amplitude noise. * This filtering is enabled through parameter of minimal gradient amplitude (use some small value 4, 8, 16). * * Note: Current implementation of this feature extractor is based on processing of grayscale images (color image is converted to grayscale image first). * * Note: Canny edge detector is a bit slower, but provides better results (especially on color images): use setEdgeFeatureCannyParameters(). * * return automatically generated */ public IntelligentScissorsMB setEdgeFeatureZeroCrossingParameters() { ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_setEdgeFeatureZeroCrossingParameters_11(nativeObj))); } // // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::setEdgeFeatureCannyParameters(double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false) // /** * Switch edge feature extractor to use Canny edge detector * * Note: "Laplacian Zero-Crossing" feature extractor is used by default (following to original article) * * SEE: Canny * param threshold1 automatically generated * param threshold2 automatically generated * param apertureSize automatically generated * param L2gradient automatically generated * return automatically generated */ public IntelligentScissorsMB setEdgeFeatureCannyParameters(double threshold1, double threshold2, int apertureSize, bool L2gradient) { ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_setEdgeFeatureCannyParameters_10(nativeObj, threshold1, threshold2, apertureSize, L2gradient))); } /** * Switch edge feature extractor to use Canny edge detector * * Note: "Laplacian Zero-Crossing" feature extractor is used by default (following to original article) * * SEE: Canny * param threshold1 automatically generated * param threshold2 automatically generated * param apertureSize automatically generated * return automatically generated */ public IntelligentScissorsMB setEdgeFeatureCannyParameters(double threshold1, double threshold2, int apertureSize) { ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_setEdgeFeatureCannyParameters_11(nativeObj, threshold1, threshold2, apertureSize))); } /** * Switch edge feature extractor to use Canny edge detector * * Note: "Laplacian Zero-Crossing" feature extractor is used by default (following to original article) * * SEE: Canny * param threshold1 automatically generated * param threshold2 automatically generated * return automatically generated */ public IntelligentScissorsMB setEdgeFeatureCannyParameters(double threshold1, double threshold2) { ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_setEdgeFeatureCannyParameters_12(nativeObj, threshold1, threshold2))); } // // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::applyImage(Mat image) // /** * Specify input image and extract image features * * param image input image. Type is #CV_8UC1 / #CV_8UC3 * return automatically generated */ public IntelligentScissorsMB applyImage(Mat image) { ThrowIfDisposed(); if (image != null) image.ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_applyImage_10(nativeObj, image.nativeObj))); } // // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::applyImageFeatures(Mat non_edge, Mat gradient_direction, Mat gradient_magnitude, Mat image = Mat()) // /** * Specify custom features of input image * * Customized advanced variant of applyImage() call. * * param non_edge Specify cost of non-edge pixels. Type is CV_8UC1. Expected values are {code {0, 1}}. * param gradient_direction Specify gradient direction feature. Type is CV_32FC2. Values are expected to be normalized: {code x^2 + y^2 == 1} * param gradient_magnitude Specify cost of gradient magnitude function: Type is CV_32FC1. Values should be in range {code [0, 1]}. * param image Optional parameter. Must be specified if subset of features is specified (non-specified features are calculated internally) * return automatically generated */ public IntelligentScissorsMB applyImageFeatures(Mat non_edge, Mat gradient_direction, Mat gradient_magnitude, Mat image) { ThrowIfDisposed(); if (non_edge != null) non_edge.ThrowIfDisposed(); if (gradient_direction != null) gradient_direction.ThrowIfDisposed(); if (gradient_magnitude != null) gradient_magnitude.ThrowIfDisposed(); if (image != null) image.ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_applyImageFeatures_10(nativeObj, non_edge.nativeObj, gradient_direction.nativeObj, gradient_magnitude.nativeObj, image.nativeObj))); } /** * Specify custom features of input image * * Customized advanced variant of applyImage() call. * * param non_edge Specify cost of non-edge pixels. Type is CV_8UC1. Expected values are {code {0, 1}}. * param gradient_direction Specify gradient direction feature. Type is CV_32FC2. Values are expected to be normalized: {code x^2 + y^2 == 1} * param gradient_magnitude Specify cost of gradient magnitude function: Type is CV_32FC1. Values should be in range {code [0, 1]}. * return automatically generated */ public IntelligentScissorsMB applyImageFeatures(Mat non_edge, Mat gradient_direction, Mat gradient_magnitude) { ThrowIfDisposed(); if (non_edge != null) non_edge.ThrowIfDisposed(); if (gradient_direction != null) gradient_direction.ThrowIfDisposed(); if (gradient_magnitude != null) gradient_magnitude.ThrowIfDisposed(); return new IntelligentScissorsMB(DisposableObject.ThrowIfNullIntPtr(imgproc_IntelligentScissorsMB_applyImageFeatures_11(nativeObj, non_edge.nativeObj, gradient_direction.nativeObj, gradient_magnitude.nativeObj))); } // // C++: void cv::segmentation::IntelligentScissorsMB::buildMap(Point sourcePt) // /** * Prepares a map of optimal paths for the given source point on the image * * Note: applyImage() / applyImageFeatures() must be called before this call * * param sourcePt The source point used to find the paths */ public void buildMap(Point sourcePt) { ThrowIfDisposed(); imgproc_IntelligentScissorsMB_buildMap_10(nativeObj, sourcePt.x, sourcePt.y); } // // C++: void cv::segmentation::IntelligentScissorsMB::getContour(Point targetPt, Mat& contour, bool backward = false) // /** * Extracts optimal contour for the given target point on the image * * Note: buildMap() must be called before this call * * param targetPt The target point * param contour The list of pixels which contains optimal path between the source and the target points of the image. Type is CV_32SC2 (compatible with {code std::vector<Point>}) * param backward Flag to indicate reverse order of retrived pixels (use "true" value to fetch points from the target to the source point) */ public void getContour(Point targetPt, Mat contour, bool backward) { ThrowIfDisposed(); if (contour != null) contour.ThrowIfDisposed(); imgproc_IntelligentScissorsMB_getContour_10(nativeObj, targetPt.x, targetPt.y, contour.nativeObj, backward); } /** * Extracts optimal contour for the given target point on the image * * Note: buildMap() must be called before this call * * param targetPt The target point * param contour The list of pixels which contains optimal path between the source and the target points of the image. Type is CV_32SC2 (compatible with {code std::vector<Point>}) */ public void getContour(Point targetPt, Mat contour) { ThrowIfDisposed(); if (contour != null) contour.ThrowIfDisposed(); imgproc_IntelligentScissorsMB_getContour_11(nativeObj, targetPt.x, targetPt.y, contour.nativeObj); } #if (UNITY_IOS || UNITY_WEBGL) && !UNITY_EDITOR const string LIBNAME = "__Internal"; #else const string LIBNAME = "opencvforunity"; #endif // C++: cv::segmentation::IntelligentScissorsMB::IntelligentScissorsMB() [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_IntelligentScissorsMB_10(); // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::setWeights(float weight_non_edge, float weight_gradient_direction, float weight_gradient_magnitude) [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_setWeights_10(IntPtr nativeObj, float weight_non_edge, float weight_gradient_direction, float weight_gradient_magnitude); // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::setGradientMagnitudeMaxLimit(float gradient_magnitude_threshold_max = 0.0f) [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_setGradientMagnitudeMaxLimit_10(IntPtr nativeObj, float gradient_magnitude_threshold_max); [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_setGradientMagnitudeMaxLimit_11(IntPtr nativeObj); // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::setEdgeFeatureZeroCrossingParameters(float gradient_magnitude_min_value = 0.0f) [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_setEdgeFeatureZeroCrossingParameters_10(IntPtr nativeObj, float gradient_magnitude_min_value); [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_setEdgeFeatureZeroCrossingParameters_11(IntPtr nativeObj); // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::setEdgeFeatureCannyParameters(double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false) [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_setEdgeFeatureCannyParameters_10(IntPtr nativeObj, double threshold1, double threshold2, int apertureSize, [MarshalAs(UnmanagedType.U1)] bool L2gradient); [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_setEdgeFeatureCannyParameters_11(IntPtr nativeObj, double threshold1, double threshold2, int apertureSize); [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_setEdgeFeatureCannyParameters_12(IntPtr nativeObj, double threshold1, double threshold2); // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::applyImage(Mat image) [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_applyImage_10(IntPtr nativeObj, IntPtr image_nativeObj); // C++: IntelligentScissorsMB cv::segmentation::IntelligentScissorsMB::applyImageFeatures(Mat non_edge, Mat gradient_direction, Mat gradient_magnitude, Mat image = Mat()) [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_applyImageFeatures_10(IntPtr nativeObj, IntPtr non_edge_nativeObj, IntPtr gradient_direction_nativeObj, IntPtr gradient_magnitude_nativeObj, IntPtr image_nativeObj); [DllImport(LIBNAME)] private static extern IntPtr imgproc_IntelligentScissorsMB_applyImageFeatures_11(IntPtr nativeObj, IntPtr non_edge_nativeObj, IntPtr gradient_direction_nativeObj, IntPtr gradient_magnitude_nativeObj); // C++: void cv::segmentation::IntelligentScissorsMB::buildMap(Point sourcePt) [DllImport(LIBNAME)] private static extern void imgproc_IntelligentScissorsMB_buildMap_10(IntPtr nativeObj, double sourcePt_x, double sourcePt_y); // C++: void cv::segmentation::IntelligentScissorsMB::getContour(Point targetPt, Mat& contour, bool backward = false) [DllImport(LIBNAME)] private static extern void imgproc_IntelligentScissorsMB_getContour_10(IntPtr nativeObj, double targetPt_x, double targetPt_y, IntPtr contour_nativeObj, [MarshalAs(UnmanagedType.U1)] bool backward); [DllImport(LIBNAME)] private static extern void imgproc_IntelligentScissorsMB_getContour_11(IntPtr nativeObj, double targetPt_x, double targetPt_y, IntPtr contour_nativeObj); // native support for java finalize() [DllImport(LIBNAME)] private static extern void imgproc_IntelligentScissorsMB_delete(IntPtr nativeObj); } }