Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add IntelligentScissorsMB #1310

Merged
merged 1 commit into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/OpenCvSharp/Cv2/Cv2_imgcodecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public static bool ImWrite(string fileName, IEnumerable<Mat> img, int[]? prms =
/// <returns></returns>
public static bool ImWrite(string fileName, IEnumerable<Mat> img, params ImageEncodingParam[] prms)
{
if (prms == null || prms.Length <= 0)
if (prms.Length <= 0)
return ImWrite(fileName, img);

var p = new List<int>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;

#pragma warning disable 1591
#pragma warning disable CA1401 // P/Invokes should not be visible
#pragma warning disable CA1720 // Identifiers should not contain type names
#pragma warning disable IDE1006 // Naming style

namespace OpenCvSharp.Internal
{
static partial class NativeMethods
{
[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_new(
out IntPtr returnValue);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_delete(
IntPtr obj);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_setWeights(
IntPtr obj,
float weight_non_edge, float weight_gradient_direction, float weight_gradient_magnitude);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_setGradientMagnitudeMaxLimit(
IntPtr obj,
float gradient_magnitude_threshold_max);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_setEdgeFeatureZeroCrossingParameters(
IntPtr obj,
float gradient_magnitude_min_value);


[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_setEdgeFeatureCannyParameters(
IntPtr obj,
double threshold1, double threshold2,
int apertureSize, int L2gradient);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_applyImage(
IntPtr obj,
IntPtr image);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_applyImageFeatures(
IntPtr obj,
IntPtr non_edge,
IntPtr gradient_direction,
IntPtr gradient_magnitude,
IntPtr image);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_buildMap(
IntPtr obj,
Point sourcePt);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus imgproc_segmentation_IntelligentScissorsMB_getContour(
IntPtr obj,
Point targetPt, IntPtr contour, int backward);
}
}
7 changes: 0 additions & 7 deletions src/OpenCvSharp/Modules/core/Mat/UMat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,6 @@ public UMat(UMat m, params Range[] ranges)
{
if (m == null)
throw new ArgumentNullException(nameof(m));
if (ranges == null)
throw new ArgumentNullException(nameof(ranges));
if (ranges.Length == 0)
throw new ArgumentException("empty ranges", nameof(ranges));
m.ThrowIfDisposed();
Expand Down Expand Up @@ -389,9 +387,6 @@ public static UMat Ones(Size size, MatType type)
/// <returns></returns>
public static UMat Ones(MatType type, params int[] sizes)
{
if (sizes == null)
throw new ArgumentNullException(nameof(sizes));

NativeMethods.HandleException(
NativeMethods.core_UMat_ones2(sizes.Length, sizes, type, out var ret));
var retVal = new UMat(ret);
Expand Down Expand Up @@ -1131,8 +1126,6 @@ public UMat SubMat(Rect roi)
/// <returns></returns>
public UMat SubMat(params Range[] ranges)
{
if (ranges == null)
throw new ArgumentNullException(nameof(ranges));
ThrowIfDisposed();

NativeMethods.HandleException(
Expand Down
2 changes: 0 additions & 2 deletions src/OpenCvSharp/Modules/highgui/Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,6 @@ public static int WaitKeyEx(int delay = 0)
/// <param name="images"></param>
public static void ShowImages(params Mat[] images)
{
if (images == null)
throw new ArgumentNullException(nameof(images));
if (images.Length == 0)
return;

Expand Down
211 changes: 211 additions & 0 deletions src/OpenCvSharp/Modules/imgproc/IntelligentScissorsMB.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
using System;
using OpenCvSharp.Internal;

namespace OpenCvSharp.Segmentation
{
/// <summary>
/// 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: Intelligent Scissors for Image Composition http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.138.3811&amp;rep=rep1&amp;type=pdf
/// algorithm designed by Eric N. Mortensen and William A. Barrett, Brigham Young University
/// @cite Mortensen95intelligentscissors
/// </summary>
public class IntelligentScissorsMB : DisposableCvObject
{
/// <summary>
/// Constructor
/// </summary>
public IntelligentScissorsMB()
{
NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_new(out ptr));
}

/// <summary>
/// Releases unmanaged resources
/// </summary>
protected override void DisposeUnmanaged()
{
NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_delete(ptr));
base.DisposeUnmanaged();
}

/// <summary>
/// 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.
/// </summary>
/// <param name="weightNonEdge">Specify cost of non-edge pixels (default: 0.43f)</param>
/// <param name="weightGradientDirection">Specify cost of gradient direction function (default: 0.43f)</param>
/// <param name="weightGradientMagnitude">Specify cost of gradient magnitude function (default: 0.14f)</param>
/// <returns></returns>
public IntelligentScissorsMB SetWeights(
float weightNonEdge, float weightGradientDirection, float weightGradientMagnitude)
{
ThrowIfDisposed();

NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_setWeights(
ptr, weightNonEdge, weightGradientDirection, weightGradientMagnitude));

return this;
}

/// <summary>
/// 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 `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).
/// </summary>
/// <param name="gradientMagnitudeThresholdMax">Specify gradient magnitude max value threshold (default: 0, disabled)</param>
/// <returns></returns>
public IntelligentScissorsMB SetGradientMagnitudeMaxLimit(
float gradientMagnitudeThresholdMax = 0.0f)
{
ThrowIfDisposed();

NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_setGradientMagnitudeMaxLimit(
ptr, gradientMagnitudeThresholdMax));

return this;
}

/// <summary>
/// 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().
/// </summary>
/// <param name="gradientMagnitudeMinValue">Minimal gradient magnitude value for edge pixels (default: 0, check is disabled)</param>
/// <returns></returns>
public IntelligentScissorsMB SetEdgeFeatureZeroCrossingParameters(
float gradientMagnitudeMinValue = 0.0f)
{
ThrowIfDisposed();

NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_setEdgeFeatureZeroCrossingParameters(
ptr, gradientMagnitudeMinValue));

return this;
}

/// <summary>
/// Switch edge feature extractor to use Canny edge detector
/// Note: "Laplacian Zero-Crossing" feature extractor is used by default (following to original article)
/// </summary>
/// <param name="threshold1"></param>
/// <param name="threshold2"></param>
/// <param name="apertureSize"></param>
/// <param name="l2gradient"></param>
/// <returns></returns>
public IntelligentScissorsMB SetEdgeFeatureCannyParameters(
double threshold1, double threshold2,
int apertureSize = 3, bool l2gradient = false)
{
ThrowIfDisposed();

NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_setEdgeFeatureCannyParameters(
ptr, threshold1, threshold2, apertureSize, l2gradient ? 1 : 0));

return this;
}

/// <summary>
/// Specify input image and extract image features
/// </summary>
/// <param name="image">input image. Type is #CV_8UC1 / #CV_8UC3</param>
/// <returns></returns>
public IntelligentScissorsMB ApplyImage(InputArray image)
{
ThrowIfDisposed();
if (image is null)
throw new ArgumentNullException(nameof(image));

NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_applyImage(
ptr, image.CvPtr));

return this;
}

/// <summary>
/// Specify custom features of imput image
/// Customized advanced variant of applyImage() call.
/// </summary>
/// <param name="nonEdge">Specify cost of non-edge pixels. Type is CV_8UC1. Expected values are `{0, 1}`.</param>
/// <param name="gradientDirection">Specify gradient direction feature. Type is CV_32FC2. Values are expected to be normalized: `x^2 + y^2 == 1`</param>
/// <param name="gradientMagnitude">Specify cost of gradient magnitude function: Type is CV_32FC1. Values should be in range `[0, 1]`.</param>
/// <param name="image">Optional parameter. Must be specified if subset of features is specified (non-specified features are calculated internally)</param>
/// <returns></returns>
public IntelligentScissorsMB ApplyImageFeatures(
InputArray nonEdge, InputArray gradientDirection, InputArray gradientMagnitude,
InputArray? image = null)
{
ThrowIfDisposed();
if (nonEdge is null)
throw new ArgumentNullException(nameof(nonEdge));
if (gradientDirection is null)
throw new ArgumentNullException(nameof(gradientDirection));
if (gradientMagnitude is null)
throw new ArgumentNullException(nameof(gradientMagnitude));

NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_applyImageFeatures(
ptr, nonEdge.CvPtr, gradientDirection.CvPtr, gradientMagnitude.CvPtr, image?.CvPtr ?? IntPtr.Zero));

return this;
}

/// <summary>
/// Prepares a map of optimal paths for the given source point on the image
/// Note: applyImage() / applyImageFeatures() must be called before this call
/// </summary>
/// <param name="sourcePt">The source point used to find the paths</param>
public void BuildMap(Point sourcePt)
{
ThrowIfDisposed();

NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_buildMap(
ptr, sourcePt));
}

/// <summary>
/// Extracts optimal contour for the given target point on the image
/// Note: buildMap() must be called before this call
/// </summary>
/// <param name="targetPt">The target point</param>
/// <param name="contour">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 `std::vector&lt;Point&gt;`)</param>
/// <param name="backward">Flag to indicate reverse order of retrived pixels (use "true" value to fetch points from the target to the source point)</param>
public void GetContour(Point targetPt, OutputArray contour, bool backward = false)
{
ThrowIfDisposed();
if (contour is null)
throw new ArgumentNullException(nameof(contour));

NativeMethods.HandleException(
NativeMethods.imgproc_segmentation_IntelligentScissorsMB_getContour(
ptr, targetPt, contour.CvPtr, backward ? 1 : 0));
}
}
}
1 change: 1 addition & 0 deletions src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ copy "$(SolutionDir)opencv_files\opencv453_win_x64\x64\vc16\bin\opencv_videoio_f
<ClInclude Include="imgproc.h" />
<ClInclude Include="imgproc_GeneralizedHough.h" />
<ClInclude Include="imgproc_LineIterator.h" />
<ClInclude Include="imgproc_Segmentation.h" />
<ClInclude Include="imgproc_Subdiv2D.h" />
<ClInclude Include="img_hash.h" />
<ClInclude Include="include_opencv.h" />
Expand Down
3 changes: 3 additions & 0 deletions src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,9 @@
<ClInclude Include="ximgproc_RidgeDetectionFilter.h">
<Filter>Header Files\ximgproc</Filter>
</ClInclude>
<ClInclude Include="imgproc_Segmentation.h">
<Filter>Header Files\imgproc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
Expand Down
3 changes: 2 additions & 1 deletion src/OpenCvSharpExtern/imgproc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
#include "imgproc_Subdiv2D.h"
#include "imgproc_CLAHE.h"
#include "imgproc_LineIterator.h"
#include "imgproc_GeneralizedHough.h"
#include "imgproc_GeneralizedHough.h"
#include "imgproc_Segmentation.h"