Skip to content

Fix FastNlMeansDenosing problem #1404

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

Merged
merged 1 commit into from
Mar 27, 2022
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 37 additions & 105 deletions src/OpenCvSharp/Cv2/Cv2_photo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ static partial class Cv2
public static void Inpaint(InputArray src, InputArray inpaintMask,
OutputArray dst, double inpaintRadius, InpaintMethod flags)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (inpaintMask == null)
if (inpaintMask is null)
throw new ArgumentNullException(nameof(inpaintMask));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));
src.ThrowIfDisposed();
inpaintMask.ThrowIfDisposed();
Expand Down Expand Up @@ -53,9 +53,9 @@ public static void Inpaint(InputArray src, InputArray inpaintMask,
public static void FastNlMeansDenoising(InputArray src, OutputArray dst, float h = 3,
int templateWindowSize = 7, int searchWindowSize = 21)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));
src.ThrowIfDisposed();
dst.ThrowIfNotReady();
Expand Down Expand Up @@ -85,9 +85,9 @@ public static void FastNlMeansDenoisingColored(InputArray src, OutputArray dst,
float h = 3, float hColor = 3,
int templateWindowSize = 7, int searchWindowSize = 21)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));
src.ThrowIfDisposed();
dst.ThrowIfNotReady();
Expand Down Expand Up @@ -115,14 +115,15 @@ public static void FastNlMeansDenoisingColored(InputArray src, OutputArray dst,
/// <param name="searchWindowSize">Size in pixels of the window that is used to compute weighted average for given pixel.
/// Should be odd. Affect performance linearly: greater searchWindowsSize - greater denoising time. Recommended value 21 pixels</param>
public static void FastNlMeansDenoisingMulti(
IEnumerable<InputArray> srcImgs, OutputArray dst,
IEnumerable<Mat> srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize,
float h = 3, int templateWindowSize = 7, int searchWindowSize = 21)
{
if (srcImgs == null)
if (srcImgs is null)
throw new ArgumentNullException(nameof(srcImgs));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));

dst.ThrowIfNotReady();
var srcImgPtrs = srcImgs.Select(x => x.CvPtr).ToArray();

Expand All @@ -136,41 +137,6 @@ public static void FastNlMeansDenoisingMulti(
GC.KeepAlive(srcImgs);
}

/// <summary>
/// Modification of fastNlMeansDenoising function for images sequence where consequtive images have been captured
/// in small period of time. For example video. This version of the function is for grayscale images or for manual manipulation with colorspaces.
/// </summary>
/// <param name="srcImgs">Input 8-bit 1-channel, 2-channel or 3-channel images sequence. All images should have the same type and size.</param>
/// <param name="dst"> Output image with the same size and type as srcImgs images.</param>
/// <param name="imgToDenoiseIndex">Target image to denoise index in srcImgs sequence</param>
/// <param name="temporalWindowSize">Number of surrounding images to use for target image denoising.
/// Should be odd. Images from imgToDenoiseIndex - temporalWindowSize / 2 to imgToDenoiseIndex - temporalWindowSize / 2
/// from srcImgs will be used to denoise srcImgs[imgToDenoiseIndex] image.</param>
/// <param name="h">Parameter regulating filter strength for luminance component. Bigger h value perfectly removes noise but also removes image details,
/// smaller h value preserves details but also preserves some noise</param>
/// <param name="templateWindowSize">Size in pixels of the template patch that is used to compute weights. Should be odd. Recommended value 7 pixels</param>
/// <param name="searchWindowSize">Size in pixels of the window that is used to compute weighted average for given pixel.
/// Should be odd. Affect performance linearly: greater searchWindowsSize - greater denoising time. Recommended value 21 pixels</param>
public static void FastNlMeansDenoisingMulti(
IEnumerable<Mat> srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize,
float h = 3, int templateWindowSize = 7, int searchWindowSize = 21)
{
var srcImgsAsArrays = srcImgs.Select(m => new InputArray(m)).ToArray();
try
{
FastNlMeansDenoisingMulti(srcImgsAsArrays, dst, imgToDenoiseIndex, temporalWindowSize,
h, templateWindowSize, searchWindowSize);
}
finally
{
foreach (var img in srcImgsAsArrays)
{
img.Dispose();
}
}
}

/// <summary>
/// Modification of fastNlMeansDenoisingMulti function for colored images sequences
/// </summary>
Expand All @@ -187,13 +153,13 @@ public static void FastNlMeansDenoisingMulti(
/// <param name="searchWindowSize">Size in pixels of the window that is used to compute weighted average for given pixel.
/// Should be odd. Affect performance linearly: greater searchWindowsSize - greater denoising time. Recommended value 21 pixels</param>
public static void FastNlMeansDenoisingColoredMulti(
IEnumerable<InputArray> srcImgs, OutputArray dst,
IEnumerable<Mat> srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize, float h = 3, float hColor = 3,
int templateWindowSize = 7, int searchWindowSize = 21)
{
if (srcImgs == null)
if (srcImgs is null)
throw new ArgumentNullException(nameof(srcImgs));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));
dst.ThrowIfNotReady();
var srcImgPtrs = srcImgs.Select(x => x.CvPtr).ToArray();
Expand All @@ -207,40 +173,6 @@ public static void FastNlMeansDenoisingColoredMulti(
GC.KeepAlive(srcImgs);
}

/// <summary>
/// Modification of fastNlMeansDenoisingMulti function for colored images sequences
/// </summary>
/// <param name="srcImgs">Input 8-bit 3-channel images sequence. All images should have the same type and size.</param>
/// <param name="dst">Output image with the same size and type as srcImgs images.</param>
/// <param name="imgToDenoiseIndex">Target image to denoise index in srcImgs sequence</param>
/// <param name="temporalWindowSize">Number of surrounding images to use for target image denoising. Should be odd.
/// Images from imgToDenoiseIndex - temporalWindowSize / 2 to imgToDenoiseIndex - temporalWindowSize / 2 from srcImgs
/// will be used to denoise srcImgs[imgToDenoiseIndex] image.</param>
/// <param name="h">Parameter regulating filter strength for luminance component. Bigger h value perfectly removes noise
/// but also removes image details, smaller h value preserves details but also preserves some noise.</param>
/// <param name="hColor"> The same as h but for color components.</param>
/// <param name="templateWindowSize">Size in pixels of the template patch that is used to compute weights. Should be odd. Recommended value 7 pixels</param>
/// <param name="searchWindowSize">Size in pixels of the window that is used to compute weighted average for given pixel.
/// Should be odd. Affect performance linearly: greater searchWindowsSize - greater denoising time. Recommended value 21 pixels</param>
public static void FastNlMeansDenoisingColoredMulti(IEnumerable<Mat> srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize, float h = 3, float hColor = 3,
int templateWindowSize = 7, int searchWindowSize = 21)
{
var srcImgsAsArrays = srcImgs.Select(m => new InputArray(m)).ToArray();
try
{
FastNlMeansDenoisingColoredMulti(
srcImgsAsArrays, dst, imgToDenoiseIndex, temporalWindowSize, h, hColor, templateWindowSize, searchWindowSize);
}
finally
{
foreach (var img in srcImgsAsArrays)
{
img.Dispose();
}
}
}

/// <summary>
/// Primal-dual algorithm is an algorithm for solving special types of variational problems
/// (that is, finding a function to minimize some functional). As the image denoising,
Expand All @@ -262,9 +194,9 @@ public static void FastNlMeansDenoisingColoredMulti(IEnumerable<Mat> srcImgs, Ou
public static void DenoiseTVL1(
IEnumerable<Mat> observations, Mat result, double lambda = 1.0, int niters = 30)
{
if (observations == null)
if (observations is null)
throw new ArgumentNullException(nameof(observations));
if (result == null)
if (result is null)
throw new ArgumentNullException(nameof(result));

var observationsPtrs = observations.Select(x => x.CvPtr).ToArray();
Expand All @@ -285,11 +217,11 @@ public static void DenoiseTVL1(
public static void Decolor(
InputArray src, OutputArray grayscale, OutputArray colorBoost)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (grayscale == null)
if (grayscale is null)
throw new ArgumentNullException(nameof(grayscale));
if (colorBoost == null)
if (colorBoost is null)
throw new ArgumentNullException(nameof(colorBoost));
src.ThrowIfDisposed();
grayscale.ThrowIfNotReady();
Expand Down Expand Up @@ -321,11 +253,11 @@ public static void SeamlessClone(
InputArray src, InputArray dst, InputArray? mask, Point p,
OutputArray blend, SeamlessCloneMethods flags)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));
if (blend == null)
if (blend is null)
throw new ArgumentNullException(nameof(blend));
src.ThrowIfDisposed();
dst.ThrowIfDisposed();
Expand Down Expand Up @@ -356,9 +288,9 @@ 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)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));
src.ThrowIfDisposed();
dst.ThrowIfNotReady();
Expand Down Expand Up @@ -390,9 +322,9 @@ public static void IlluminationChange(
InputArray src, InputArray? mask, OutputArray dst,
float alpha = 0.2f, float beta = 0.4f)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));

src.ThrowIfDisposed();
Expand Down Expand Up @@ -424,9 +356,9 @@ public static void TextureFlattening(
float lowThreshold = 30, float highThreshold = 45,
int kernelSize = 3)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));

src.ThrowIfDisposed();
Expand Down Expand Up @@ -456,9 +388,9 @@ public static void EdgePreservingFilter(
EdgePreservingMethods flags = EdgePreservingMethods.RecursFilter,
float sigmaS = 60, float sigmaR = 0.4f)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));

src.ThrowIfDisposed();
Expand All @@ -483,9 +415,9 @@ public static void DetailEnhance(
InputArray src, OutputArray dst,
float sigmaS = 10, float sigmaR = 0.15f)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));

src.ThrowIfDisposed();
Expand All @@ -512,11 +444,11 @@ public static void PencilSketch(
InputArray src, OutputArray dst1, OutputArray dst2,
float sigmaS = 60, float sigmaR = 0.07f, float shadeFactor = 0.02f)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst1 == null)
if (dst1 is null)
throw new ArgumentNullException(nameof(dst1));
if (dst2 == null)
if (dst2 is null)
throw new ArgumentNullException(nameof(dst2));

src.ThrowIfDisposed();
Expand Down Expand Up @@ -546,9 +478,9 @@ public static void Stylization(
InputArray src, OutputArray dst,
float sigmaS = 60, float sigmaR = 0.45f)
{
if (src == null)
if (src is null)
throw new ArgumentNullException(nameof(src));
if (dst == null)
if (dst is null)
throw new ArgumentNullException(nameof(dst));

src.ThrowIfDisposed();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,25 @@ namespace OpenCvSharp.Internal
static partial class NativeMethods
{
[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus photo_inpaint(IntPtr src, IntPtr inpaintMask,
public static extern ExceptionStatus photo_inpaint(
IntPtr src, IntPtr inpaintMask,
IntPtr dst, double inpaintRadius, int flags);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus photo_fastNlMeansDenoising(IntPtr src, IntPtr dst, float h,
public static extern ExceptionStatus photo_fastNlMeansDenoising(
IntPtr src, IntPtr dst, float h,
int templateWindowSize, int searchWindowSize);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus photo_fastNlMeansDenoisingColored(IntPtr src, IntPtr dst,
public static extern ExceptionStatus photo_fastNlMeansDenoisingColored(
IntPtr src, IntPtr dst,
float h, float hColor, int templateWindowSize, int searchWindowSize);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus photo_fastNlMeansDenoisingMulti(IntPtr[] srcImgs, int srcImgsLength,
IntPtr dst, int imgToDenoiseIndex, int temporalWindowSize,
float h, int templateWindowSize, int searchWindowSize);
public static extern ExceptionStatus photo_fastNlMeansDenoisingMulti(
IntPtr[] srcImgs, int srcImgsLength,
IntPtr dst, int imgToDenoiseIndex, int temporalWindowSize,
float h, int templateWindowSize, int searchWindowSize);

[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ExceptionStatus photo_fastNlMeansDenoisingColoredMulti(IntPtr[] srcImgs, int srcImgsLength,
Expand Down
24 changes: 16 additions & 8 deletions src/OpenCvSharpExtern/photo.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,35 @@ CVAPI(ExceptionStatus) photo_fastNlMeansDenoisingColored(cv::_InputArray *src, c
END_WRAP
}

CVAPI(ExceptionStatus) photo_fastNlMeansDenoisingMulti(cv::_InputArray ** srcImgs, int srcImgsLength,
cv::_OutputArray *dst, int imgToDenoiseIndex, int temporalWindowSize,
CVAPI(ExceptionStatus) photo_fastNlMeansDenoisingMulti(cv::Mat **srcImgs, int srcImgsLength,
cv::_OutputArray* dst, int imgToDenoiseIndex, int temporalWindowSize,
float h, int templateWindowSize, int searchWindowSize)
{
BEGIN_WRAP
std::vector<cv::_InputArray> srcImgsVec(srcImgsLength);
for (int i = 0; i < srcImgsLength; i++)

std::vector<cv::Mat> srcImgsVec;
for (int i = 0; i < srcImgsLength; i++)
srcImgsVec[i] = *srcImgs[i];
cv::fastNlMeansDenoisingMulti(srcImgsVec, *dst, imgToDenoiseIndex, temporalWindowSize, h, templateWindowSize, searchWindowSize);

cv::fastNlMeansDenoisingMulti(
srcImgsVec, *dst, imgToDenoiseIndex, temporalWindowSize, h, templateWindowSize, searchWindowSize);

END_WRAP
}

CVAPI(ExceptionStatus) photo_fastNlMeansDenoisingColoredMulti(cv::_InputArray **srcImgs, int srcImgsLength,
CVAPI(ExceptionStatus) photo_fastNlMeansDenoisingColoredMulti(cv::Mat**srcImgs, int srcImgsLength,
cv::_OutputArray *dst, int imgToDenoiseIndex, int temporalWindowSize,
float h, float hColor, int templateWindowSize, int searchWindowSize)
{
BEGIN_WRAP
std::vector<cv::_InputArray> srcImgsVec(srcImgsLength);

std::vector<cv::Mat> srcImgsVec(srcImgsLength);
for (int i = 0; i < srcImgsLength; i++)
srcImgsVec[i] = *srcImgs[i];
cv::fastNlMeansDenoisingColoredMulti(srcImgsVec, *dst, imgToDenoiseIndex, temporalWindowSize, h, hColor, templateWindowSize, searchWindowSize);

cv::fastNlMeansDenoisingColoredMulti(
srcImgsVec, *dst, imgToDenoiseIndex, temporalWindowSize, h, hColor, templateWindowSize, searchWindowSize);

END_WRAP
}

Expand Down
Loading