Commit 3468ae57 authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #733 from bpawlik:bm3d

parents 73459049 727631f0
......@@ -49,4 +49,5 @@
#include "xphoto/inpainting.hpp"
#include "xphoto/white_balance.hpp"
#include "xphoto/dct_image_denoising.hpp"
#include "xphoto/bm3d_image_denoising.hpp"
#endif
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_BM3D_IMAGE_DENOISING_HPP__
#define __OPENCV_BM3D_IMAGE_DENOISING_HPP__
/** @file
@date Jul 19, 2016
@author Bartek Pawlik
*/
#include <opencv2/core.hpp>
namespace cv
{
namespace xphoto
{
//! @addtogroup xphoto
//! @{
//! BM3D transform types
enum TransformTypes
{
/** Un-normalized Haar transform */
HAAR = 0
};
//! BM3D algorithm steps
enum Bm3dSteps
{
/** Execute all steps of the algorithm */
BM3D_STEPALL = 0,
/** Execute only first step of the algorithm */
BM3D_STEP1 = 1,
/** Execute only second step of the algorithm */
BM3D_STEP2 = 2
};
/** @brief Performs image denoising using the Block-Matching and 3D-filtering algorithm
<http://www.cs.tut.fi/~foi/GCF-BM3D/BM3D_TIP_2007.pdf> with several computational
optimizations. Noise expected to be a gaussian white noise.
@param src Input 8-bit or 16-bit 1-channel image.
@param dstStep1 Output image of the first step of BM3D with the same size and type as src.
@param dstStep2 Output image of the second step of BM3D with the same size and type as src.
@param h Parameter regulating filter strength. Big h value perfectly removes noise but also
removes image details, smaller h value preserves details but also preserves some noise.
@param templateWindowSize Size in pixels of the template patch that is used for block-matching.
Should be power of 2.
@param searchWindowSize Size in pixels of the window that is used to perform block-matching.
Affect performance linearly: greater searchWindowsSize - greater denoising time.
Must be larger than templateWindowSize.
@param blockMatchingStep1 Block matching threshold for the first step of BM3D (hard thresholding),
i.e. maximum distance for which two blocks are considered similar.
Value expressed in euclidean distance.
@param blockMatchingStep2 Block matching threshold for the second step of BM3D (Wiener filtering),
i.e. maximum distance for which two blocks are considered similar.
Value expressed in euclidean distance.
@param groupSize Maximum size of the 3D group for collaborative filtering.
@param slidingStep Sliding step to process every next reference block.
@param beta Kaiser window parameter that affects the sidelobe attenuation of the transform of the
window. Kaiser window is used in order to reduce border effects. To prevent usage of the window,
set beta to zero.
@param normType Norm used to calculate distance between blocks. L2 is slower than L1
but yields more accurate results.
@param step Step of BM3D to be executed. Possible variants are: step 1, step 2, both steps.
@param transformType Type of the orthogonal transform used in collaborative filtering step.
Currently only Haar transform is supported.
This function expected to be applied to grayscale images. Advanced usage of this function
can be manual denoising of colored image in different colorspaces.
@sa
fastNlMeansDenoising
*/
CV_EXPORTS_W void bm3dDenoising(
InputArray src,
InputOutputArray dstStep1,
OutputArray dstStep2,
float h = 1,
int templateWindowSize = 4,
int searchWindowSize = 16,
int blockMatchingStep1 = 2500,
int blockMatchingStep2 = 400,
int groupSize = 8,
int slidingStep = 1,
float beta = 2.0f,
int normType = cv::NORM_L2,
int step = cv::xphoto::BM3D_STEPALL,
int transformType = cv::xphoto::HAAR);
/** @brief Performs image denoising using the Block-Matching and 3D-filtering algorithm
<http://www.cs.tut.fi/~foi/GCF-BM3D/BM3D_TIP_2007.pdf> with several computational
optimizations. Noise expected to be a gaussian white noise.
@param src Input 8-bit or 16-bit 1-channel image.
@param dst Output image with the same size and type as src.
@param h Parameter regulating filter strength. Big h value perfectly removes noise but also
removes image details, smaller h value preserves details but also preserves some noise.
@param templateWindowSize Size in pixels of the template patch that is used for block-matching.
Should be power of 2.
@param searchWindowSize Size in pixels of the window that is used to perform block-matching.
Affect performance linearly: greater searchWindowsSize - greater denoising time.
Must be larger than templateWindowSize.
@param blockMatchingStep1 Block matching threshold for the first step of BM3D (hard thresholding),
i.e. maximum distance for which two blocks are considered similar.
Value expressed in euclidean distance.
@param blockMatchingStep2 Block matching threshold for the second step of BM3D (Wiener filtering),
i.e. maximum distance for which two blocks are considered similar.
Value expressed in euclidean distance.
@param groupSize Maximum size of the 3D group for collaborative filtering.
@param slidingStep Sliding step to process every next reference block.
@param beta Kaiser window parameter that affects the sidelobe attenuation of the transform of the
window. Kaiser window is used in order to reduce border effects. To prevent usage of the window,
set beta to zero.
@param normType Norm used to calculate distance between blocks. L2 is slower than L1
but yields more accurate results.
@param step Step of BM3D to be executed. Allowed are only BM3D_STEP1 and BM3D_STEPALL.
BM3D_STEP2 is not allowed as it requires basic estimate to be present.
@param transformType Type of the orthogonal transform used in collaborative filtering step.
Currently only Haar transform is supported.
This function expected to be applied to grayscale images. Advanced usage of this function
can be manual denoising of colored image in different colorspaces.
@sa
fastNlMeansDenoising
*/
CV_EXPORTS_W void bm3dDenoising(
InputArray src,
OutputArray dst,
float h = 1,
int templateWindowSize = 4,
int searchWindowSize = 16,
int blockMatchingStep1 = 2500,
int blockMatchingStep2 = 400,
int groupSize = 8,
int slidingStep = 1,
float beta = 2.0f,
int normType = cv::NORM_L2,
int step = cv::xphoto::BM3D_STEPALL,
int transformType = cv::xphoto::HAAR);
//! @}
}
}
#endif // __OPENCV_BM3D_IMAGE_DENOISING_HPP__
#include "opencv2/xphoto.hpp"
#include "opencv2/highgui.hpp"
const char* keys =
{
"{i || input image name}"
"{o || output image name}"
"{sigma || expected noise standard deviation}"
"{tw |4| template window size}"
"{sw |16| search window size}"
};
int main(int argc, const char** argv)
{
bool printHelp = (argc == 1);
printHelp = printHelp || (argc == 2 && std::string(argv[1]) == "--help");
printHelp = printHelp || (argc == 2 && std::string(argv[1]) == "-h");
if (printHelp)
{
printf("\nThis sample demonstrates BM3D image denoising\n"
"Call:\n"
" bm3d_image_denoising -i=<string> -sigma=<double> -tw=<int> -sw=<int> [-o=<string>]\n\n");
return 0;
}
cv::CommandLineParser parser(argc, argv, keys);
if (!parser.check())
{
parser.printErrors();
return -1;
}
std::string inFilename = parser.get<std::string>("i");
std::string outFilename = parser.get<std::string>("o");
cv::Mat src = cv::imread(inFilename, cv::IMREAD_GRAYSCALE);
if (src.empty())
{
printf("Cannot read image file: %s\n", inFilename.c_str());
return -1;
}
float sigma = parser.get<float>("sigma");
if (sigma == 0.0)
sigma = 15.0;
int templateWindowSize = parser.get<int>("tw");
if (templateWindowSize == 0)
templateWindowSize = 4;
int searchWindowSize = parser.get<int>("sw");
if (searchWindowSize == 0)
searchWindowSize = 16;
cv::Mat res(src.size(), src.type());
cv::xphoto::bm3dDenoising(src, res, sigma, templateWindowSize, searchWindowSize);
if (outFilename.empty())
{
cv::namedWindow("input image", cv::WINDOW_NORMAL);
cv::imshow("input image", src);
cv::namedWindow("denoising result", cv::WINDOW_NORMAL);
cv::imshow("denoising result", res);
cv::waitKey(0);
}
else
{
cv::imwrite(outFilename, res);
}
return 0;
}
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_BM3D_DENOISING_INVOKER_COMMONS_HPP__
#define __OPENCV_BM3D_DENOISING_INVOKER_COMMONS_HPP__
#include "bm3d_denoising_invoker_structs.hpp"
// std::isnan is a part of C++11 and it is not supported in MSVS2010/2012
#if defined _MSC_VER && _MSC_VER < 1800 /* MSVC 2013 */
#include <float.h>
namespace std {
template <typename T> bool isnan(T value) { return _isnan(value) != 0; }
}
#endif
namespace cv
{
namespace xphoto
{
// Returns largest power of 2 smaller than the input value
inline int getLargestPowerOf2SmallerThan(unsigned x)
{
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
return x - (x >> 1);
}
// Returns true if x is a power of 2. Otherwise false.
inline bool isPowerOf2(int x)
{
return (x > 0) && !(x & (x - 1));
}
template <typename T>
inline static void shrink(T &val, T &nonZeroCount, const T &threshold)
{
if (std::abs(val) < threshold)
val = 0;
else
++nonZeroCount;
}
template <typename T>
inline static void hardThreshold2D(T *dst, T *thrMap, const int &templateWindowSizeSq)
{
for (int i = 1; i < templateWindowSizeSq; ++i)
{
if (std::abs(dst[i] < thrMap[i]))
dst[i] = 0;
}
}
template <int N, typename T, typename DT, typename CT>
inline static T HardThreshold(BlockMatch<T, DT, CT> *z, const int &n, T *&thrMap)
{
T nonZeroCount = 0;
for (int i = 0; i < N; ++i)
shrink(z[i][n], nonZeroCount, *thrMap++);
return nonZeroCount;
}
template <typename T, typename DT, typename CT>
inline static T HardThreshold(BlockMatch<T, DT, CT> *z, const int &n, T *&thrMap, const int &N)
{
T nonZeroCount = 0;
for (int i = 0; i < N; ++i)
shrink(z[i][n], nonZeroCount, *thrMap++);
return nonZeroCount;
}
template <int N, typename T, typename DT, typename CT>
inline static int WienerFiltering(BlockMatch<T, DT, CT> *zSrc, BlockMatch<T, DT, CT> *zBasic, const int &n, T *&thrMap)
{
int wienerCoeffs = 0;
for (int i = 0; i < N; ++i)
{
// Possible optimization point here to get rid of floats and casts
int basicSq = zBasic[i][n] * zBasic[i][n];
int sigmaSq = *thrMap * *thrMap;
int denom = basicSq + sigmaSq;
float wie = (denom == 0) ? 1.0f : ((float)basicSq / (float)denom);
zBasic[i][n] = (T)(zSrc[i][n] * wie);
wienerCoeffs += (int)wie;
++thrMap;
}
return wienerCoeffs;
}
template <typename T, typename DT, typename CT>
inline static int WienerFiltering(BlockMatch<T, DT, CT> *zSrc, BlockMatch<T, DT, CT> *zBasic, const int &n, T *&thrMap, const unsigned &N)
{
int wienerCoeffs = 0;
for (unsigned i = 0; i < N; ++i)
{
// Possible optimization point here to get rid of floats and casts
int basicSq = zBasic[i][n] * zBasic[i][n];
int sigmaSq = *thrMap * *thrMap;
int denom = basicSq + sigmaSq;
float wie = (denom == 0) ? 1.0f : ((float)basicSq / (float)denom);
zBasic[i][n] = (T)(zSrc[i][n] * wie);
wienerCoeffs += (int)wie;
++thrMap;
}
return wienerCoeffs;
}
} // namespace xphoto
} // namespace cv
#endif
This diff is collapsed.
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_BM3D_DENOISING_INVOKER_STRUCTS_HPP__
#define __OPENCV_BM3D_DENOISING_INVOKER_STRUCTS_HPP__
namespace cv
{
namespace xphoto
{
template <typename T, typename DT, typename CT>
class BlockMatch
{
public:
// Data accessor
T* data()
{
return data_;
}
// Const version of data accessor
const T* data() const
{
return data_;
}
// Allocate memory for data
void init(const int &blockSizeSq)
{
data_ = new T[blockSizeSq];
}
// Release data memory
void release()
{
delete[] data_;
}
// Overloaded operator for convenient assignment
void operator()(const DT &_dist, const CT &_coord_x, const CT &_coord_y)
{
dist = _dist;
coord_x = _coord_x;
coord_y = _coord_y;
}
// Overloaded array subscript operator
T& operator[](const std::size_t &idx)
{
return data_[idx];
};
// Overloaded const array subscript operator
const T& operator[](const std::size_t &idx) const
{
return data_[idx];
};
// Overloaded comparison operator for sorting
bool operator<(const BlockMatch& right) const
{
return dist < right.dist;
}
// Block matching distance
DT dist;
// Relative coordinates to the current search window
CT coord_x;
CT coord_y;
private:
// Pointer to the pixel values of the block
T *data_;
};
class DistAbs
{
template <typename T>
struct calcDist_
{
static inline int f(const T &a, const T &b)
{
return std::abs(a - b);
}
};
template <typename ET>
struct calcDist_<Vec<ET, 2> >
{
static inline int f(const Vec<ET, 2> a, const Vec<ET, 2> b)
{
return std::abs((int)(a[0] - b[0])) + std::abs((int)(a[1] - b[1]));
}
};
template <typename ET>
struct calcDist_<Vec<ET, 3> >
{
static inline int f(const Vec<ET, 3> a, const Vec<ET, 3> b)
{
return
std::abs((int)(a[0] - b[0])) +
std::abs((int)(a[1] - b[1])) +
std::abs((int)(a[2] - b[2]));
}
};
template <typename ET>
struct calcDist_<Vec<ET, 4> >
{
static inline int f(const Vec<ET, 4> a, const Vec<ET, 4> b)
{
return
std::abs((int)(a[0] - b[0])) +
std::abs((int)(a[1] - b[1])) +
std::abs((int)(a[2] - b[2])) +
std::abs((int)(a[3] - b[3]));
}
};
public:
template <typename T>
static inline int calcDist(const T &a, const T &b)
{
return calcDist_<T>::f(a, b);
}
template <typename T>
static inline int calcDist(const Mat& m, int i1, int j1, int i2, int j2)
{
const T a = m.at<T>(i1, j1);
const T b = m.at<T>(i2, j2);
return calcDist<T>(a, b);
}
template <typename T>
static inline int calcUpDownDist(T a_up, T a_down, T b_up, T b_down)
{
return calcDist<T>(a_down, b_down) - calcDist<T>(a_up, b_up);
};
template <typename T>
static inline T calcBlockMatchingThreshold(const T &blockMatchThrL2, const T &blockSizeSq)
{
return (T)(std::sqrt((double)blockMatchThrL2) * blockSizeSq);
}
};
class DistSquared
{
template <typename T>
struct calcDist_
{
static inline int f(const T &a, const T &b)
{
return (a - b) * (a - b);
}
};
template <typename ET>
struct calcDist_<Vec<ET, 2> >
{
static inline int f(const Vec<ET, 2> a, const Vec<ET, 2> b)
{
return (int)(a[0] - b[0])*(int)(a[0] - b[0]) + (int)(a[1] - b[1])*(int)(a[1] - b[1]);
}
};
template <typename ET>
struct calcDist_<Vec<ET, 3> >
{
static inline int f(const Vec<ET, 3> a, const Vec<ET, 3> b)
{
return
(int)(a[0] - b[0])*(int)(a[0] - b[0]) +
(int)(a[1] - b[1])*(int)(a[1] - b[1]) +
(int)(a[2] - b[2])*(int)(a[2] - b[2]);
}
};
template <typename ET>
struct calcDist_<Vec<ET, 4> >
{
static inline int f(const Vec<ET, 4> a, const Vec<ET, 4> b)
{
return
(int)(a[0] - b[0])*(int)(a[0] - b[0]) +
(int)(a[1] - b[1])*(int)(a[1] - b[1]) +
(int)(a[2] - b[2])*(int)(a[2] - b[2]) +
(int)(a[3] - b[3])*(int)(a[3] - b[3]);
}
};
template <typename T> struct calcUpDownDist_
{
static inline int f(T a_up, T a_down, T b_up, T b_down)
{
int A = a_down - b_down;
int B = a_up - b_up;
return (A - B)*(A + B);
}
};
template <typename ET, int n> struct calcUpDownDist_<Vec<ET, n> >
{
private:
typedef Vec<ET, n> T;
public:
static inline int f(T a_up, T a_down, T b_up, T b_down)
{
return calcDist<T>(a_down, b_down) - calcDist<T>(a_up, b_up);
}
};
public:
template <typename T>
static inline int calcDist(const T &a, const T &b)
{
return calcDist_<T>::f(a, b);
}
template <typename T>
static inline int calcDist(const Mat& m, int i1, int j1, int i2, int j2)
{
const T a = m.at<T>(i1, j1);
const T b = m.at<T>(i2, j2);
return calcDist<T>(a, b);
}
template <typename T>
static inline int calcUpDownDist(T a_up, T a_down, T b_up, T b_down)
{
return calcUpDownDist_<T>::f(a_up, a_down, b_up, b_down);
};
template <typename T>
static inline T calcBlockMatchingThreshold(const T &blockMatchThrL2, const T &blockSizeSq)
{
return blockMatchThrL2 * blockSizeSq;
}
};
template <class T>
struct Array2d
{
T* a;
int n1, n2;
bool needToDeallocArray;
Array2d(const Array2d& array2d) :
a(array2d.a), n1(array2d.n1), n2(array2d.n2), needToDeallocArray(false)
{
if (array2d.needToDeallocArray)
{
CV_Error(Error::BadDataPtr, "Copy constructor for self allocating arrays not supported");
}
}
Array2d(T* _a, int _n1, int _n2) :
a(_a), n1(_n1), n2(_n2), needToDeallocArray(false)
{
}
Array2d(int _n1, int _n2) :
n1(_n1), n2(_n2), needToDeallocArray(true)
{
a = new T[n1*n2];
}
~Array2d()
{
if (needToDeallocArray)
delete[] a;
}
T* operator [] (int i)
{
return a + i*n2;
}
inline T* row_ptr(int i)
{
return (*this)[i];
}
};
template <class T>
struct Array3d
{
T* a;
int n1, n2, n3;
bool needToDeallocArray;
Array3d(T* _a, int _n1, int _n2, int _n3) :
a(_a), n1(_n1), n2(_n2), n3(_n3), needToDeallocArray(false)
{
}
Array3d(int _n1, int _n2, int _n3) :
n1(_n1), n2(_n2), n3(_n3), needToDeallocArray(true)
{
a = new T[n1*n2*n3];
}
~Array3d()
{
if (needToDeallocArray)
delete[] a;
}
Array2d<T> operator [] (int i)
{
Array2d<T> array2d(a + i*n2*n3, n2, n3);
return array2d;
}
inline T* row_ptr(int i1, int i2)
{
return a + i1*n2*n3 + i2*n3;
}
};
} // namespace xphoto
} // namespace cv
#endif
\ No newline at end of file
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_BM3D_DENOISING_TRANSFORMS_HPP__
#define __OPENCV_BM3D_DENOISING_TRANSFORMS_HPP__
#include "bm3d_denoising_transforms_haar.hpp"
namespace cv
{
namespace xphoto
{
// Following class contains interface of the tranform domain functions.
template <typename T, typename TT>
class Transform
{
public:
// 2D transforms
typedef void(*Forward2D)(const T *ptr, TT *dst, const int &step, const int blockSize);
typedef void(*Inverse2D)(TT *src, const int blockSize);
// 1D transforms
typedef void(*Forward1D)(BlockMatch<TT, int, TT> *z, const int &n, const unsigned &N);
typedef void(*Inverse1D)(BlockMatch<TT, int, TT> *z, const int &n, const unsigned &N);
// Specialized 1D transforms
typedef void(*Forward1Ds)(BlockMatch<TT, int, TT> *z, const int &n);
typedef void(*Inverse1Ds)(BlockMatch<TT, int, TT> *z, const int &n);
};
} // namespace xphoto
} // namespace cv
#endif
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/xphoto.hpp"
#include "opencv2/core.hpp"
#ifdef OPENCV_ENABLE_NONFREE
#include "bm3d_denoising_invoker_step1.hpp"
#include "bm3d_denoising_invoker_step2.hpp"
#include "bm3d_denoising_transforms.hpp"
#endif
namespace cv
{
namespace xphoto
{
#ifdef OPENCV_ENABLE_NONFREE
template<typename ST, typename D, typename TT>
static void bm3dDenoising_(
const Mat& src,
Mat& basic,
Mat& dst,
const float& h,
const int &templateWindowSize,
const int &searchWindowSize,
const int &hBMStep1,
const int &hBMStep2,
const int &groupSize,
const int &slidingStep,
const float &beta,
const int &step)
{
double granularity = (double)std::max(1., (double)src.total() / (1 << 16));
switch (CV_MAT_CN(src.type())) {
case 1:
if (step == BM3D_STEP1 || step == BM3D_STEPALL)
{
parallel_for_(cv::Range(0, src.rows),
Bm3dDenoisingInvokerStep1<ST, D, float, TT, HaarTransform<ST, TT> >(
src,
basic,
templateWindowSize,
searchWindowSize,
h,
hBMStep1,
groupSize,
slidingStep,
beta),
granularity);
}
if (step == BM3D_STEP2 || step == BM3D_STEPALL)
{
parallel_for_(cv::Range(0, src.rows),
Bm3dDenoisingInvokerStep2<ST, D, float, TT, HaarTransform<ST, TT> >(
src,
basic,
dst,
templateWindowSize,
searchWindowSize,
h,
hBMStep2,
groupSize,
slidingStep,
beta),
granularity);
}
break;
default:
CV_Error(Error::StsBadArg,
"Unsupported number of channels! Only 1 channel is supported at the moment.");
}
}
void bm3dDenoising(
InputArray _src,
InputOutputArray _basic,
OutputArray _dst,
float h,
int templateWindowSize,
int searchWindowSize,
int blockMatchingStep1,
int blockMatchingStep2,
int groupSize,
int slidingStep,
float beta,
int normType,
int step,
int transformType)
{
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
CV_Assert(1 == cn);
CV_Assert(HAAR == transformType);
CV_Assert(searchWindowSize > templateWindowSize);
CV_Assert(slidingStep > 0 && slidingStep < templateWindowSize);
Size srcSize = _src.size();
switch (step)
{
case BM3D_STEP1:
_basic.create(srcSize, type);
break;
case BM3D_STEP2:
CV_Assert(type == _basic.type());
_dst.create(srcSize, type);
break;
case BM3D_STEPALL:
_dst.create(srcSize, type);
break;
default:
CV_Error(Error::StsBadArg, "Unsupported BM3D step!");
}
Mat src = _src.getMat();
Mat basic = _basic.getMat().empty() ? Mat(srcSize, type) : _basic.getMat();
Mat dst = _dst.getMat();
switch (normType) {
case cv::NORM_L2:
switch (depth) {
case CV_8U:
bm3dDenoising_<uchar, DistSquared, short>(
src,
basic,
dst,
h,
templateWindowSize,
searchWindowSize,
blockMatchingStep1,
blockMatchingStep2,
groupSize,
slidingStep,
beta,
step);
break;
default:
CV_Error(Error::StsBadArg,
"Unsupported depth! Only CV_8U is supported for NORM_L2");
}
break;
case cv::NORM_L1:
switch (depth) {
case CV_8U:
bm3dDenoising_<uchar, DistAbs, short>(
src,
basic,
dst,
h,
templateWindowSize,
searchWindowSize,
blockMatchingStep1,
blockMatchingStep2,
groupSize,
slidingStep,
beta,
step);
break;
case CV_16U:
bm3dDenoising_<ushort, DistAbs, int>(
src,
basic,
dst,
h,
templateWindowSize,
searchWindowSize,
blockMatchingStep1,
blockMatchingStep2,
groupSize,
slidingStep,
beta,
step);
break;
default:
CV_Error(Error::StsBadArg,
"Unsupported depth! Only CV_8U and CV_16U are supported for NORM_L1");
}
break;
default:
CV_Error(Error::StsBadArg,
"Unsupported norm type! Only NORM_L2 and NORM_L1 are supported");
}
}
void bm3dDenoising(
InputArray _src,
OutputArray _dst,
float h,
int templateWindowSize,
int searchWindowSize,
int blockMatchingStep1,
int blockMatchingStep2,
int groupSize,
int slidingStep,
float beta,
int normType,
int step,
int transformType)
{
if (step == BM3D_STEP2)
CV_Error(Error::StsBadArg,
"Unsupported step type! To use BM3D_STEP2 one need to provide basic image.");
Mat basic;
bm3dDenoising(
_src,
basic,
_dst,
h,
templateWindowSize,
searchWindowSize,
blockMatchingStep1,
blockMatchingStep2,
groupSize,
slidingStep,
beta,
normType,
step,
transformType);
if (step == BM3D_STEP1)
_dst.assign(basic);
}
#else
void bm3dDenoising(
InputArray _src,
InputOutputArray _basic,
OutputArray _dst,
float h,
int templateWindowSize,
int searchWindowSize,
int blockMatchingStep1,
int blockMatchingStep2,
int groupSize,
int slidingStep,
float beta,
int normType,
int step,
int transformType)
{
// Empty implementation
CV_UNUSED(_src);
CV_UNUSED(_basic);
CV_UNUSED(_dst);
CV_UNUSED(h);
CV_UNUSED(templateWindowSize);
CV_UNUSED(searchWindowSize);
CV_UNUSED(blockMatchingStep1);
CV_UNUSED(blockMatchingStep2);
CV_UNUSED(groupSize);
CV_UNUSED(slidingStep);
CV_UNUSED(beta);
CV_UNUSED(normType);
CV_UNUSED(step);
CV_UNUSED(transformType);
CV_Error(Error::StsNotImplemented,
"This algorithm is patented and is excluded in this configuration;"
"Set OPENCV_ENABLE_NONFREE CMake option and rebuild the library");
}
void bm3dDenoising(
InputArray _src,
OutputArray _dst,
float h,
int templateWindowSize,
int searchWindowSize,
int blockMatchingStep1,
int blockMatchingStep2,
int groupSize,
int slidingStep,
float beta,
int normType,
int step,
int transformType)
{
// Empty implementation
CV_UNUSED(_src);
CV_UNUSED(_dst);
CV_UNUSED(h);
CV_UNUSED(templateWindowSize);
CV_UNUSED(searchWindowSize);
CV_UNUSED(blockMatchingStep1);
CV_UNUSED(blockMatchingStep2);
CV_UNUSED(groupSize);
CV_UNUSED(slidingStep);
CV_UNUSED(beta);
CV_UNUSED(normType);
CV_UNUSED(step);
CV_UNUSED(transformType);
CV_Error(Error::StsNotImplemented,
"This algorithm is patented and is excluded in this configuration;"
"Set OPENCV_ENABLE_NONFREE CMake option and rebuild the library");
}
#endif
} // namespace xphoto
} // namespace cv
\ No newline at end of file
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective icvers.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_BM3D_DENOISING_KAISER_WINDOW_HPP__
#define __OPENCV_BM3D_DENOISING_KAISER_WINDOW_HPP__
#include "opencv2/core.hpp"
#include <cmath>
namespace cv
{
namespace xphoto
{
static int factorial(int n)
{
if (n == 0)
return 1;
int val = 1;
for (int idx = 1; idx <= n; ++idx)
val *= idx;
return val;
}
template <int MAX_ITER>
static float bessel0(const float &x)
{
float sum = 0.0f;
for (int m = 0; m < MAX_ITER; ++m)
{
float factM = (float)factorial(m);
float inc = std::pow(1.0f / factM * std::pow(x * 0.5f, (float)m), 2.0f);
sum += inc;
if ((inc / sum) < 0.001F)
break;
}
return sum;
}
#define MAX_ITER_BESSEL 100
static void calcKaiserWindow1D(cv::Mat &dst, const int N, const float beta)
{
if (dst.empty())
dst.create(cv::Size(1, N), CV_32FC1);
CV_Assert(dst.total() == (size_t)N);
CV_Assert(dst.type() == CV_32FC1);
CV_Assert(N > 0);
float *p = dst.ptr<float>(0);
for (int i = 0; i < N; ++i)
{
float b = beta * std::sqrt(1.0f - std::pow(2.0f * i / (N - 1.0f) - 1.0f, 2.0f));
p[i] = bessel0<MAX_ITER_BESSEL>(b) / bessel0<MAX_ITER_BESSEL>(beta);
}
}
static void calcKaiserWindow2D(float *&kaiser, const int N, const float beta)
{
if (kaiser == NULL)
kaiser = new float[N * N];
if (beta == 0.0f)
{
for (int i = 0; i < N * N; ++i)
kaiser[i] = 1.0f;
return;
}
cv::Mat kaiser1D;
calcKaiserWindow1D(kaiser1D, N, beta);
cv::Mat kaiser1Dt;
cv::transpose(kaiser1D, kaiser1Dt);
cv::Mat kaiser2D = kaiser1D * kaiser1Dt;
float *p = kaiser2D.ptr<float>(0);
for (unsigned i = 0; i < kaiser2D.total(); ++i)
kaiser[i] = p[i];
}
} // namespace xphoto
} // namespace cv
#endif
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment