mirror of https://github.com/opencv/opencv.git
parent
47ce461d97
commit
f2afe64521
10 changed files with 47 additions and 2151 deletions
@ -1,2 +1,2 @@ |
||||
set(the_description "Computational Photography") |
||||
ocv_define_module(photo opencv_imgproc) |
||||
set(the_description "Generic optimization") |
||||
ocv_define_module(optim) |
||||
|
@ -1,161 +0,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_DENOISING_ARRAYS_HPP__ |
||||
#define __OPENCV_DENOISING_ARRAYS_HPP__ |
||||
|
||||
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) { |
||||
// copy constructor for self allocating arrays not supported
|
||||
throw new std::exception(); |
||||
} |
||||
} |
||||
|
||||
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; |
||||
} |
||||
}; |
||||
|
||||
template <class T> struct Array4d { |
||||
T* a; |
||||
int n1,n2,n3,n4; |
||||
bool needToDeallocArray; |
||||
int steps[4]; |
||||
|
||||
void init_steps() { |
||||
steps[0] = n2*n3*n4; |
||||
steps[1] = n3*n4; |
||||
steps[2] = n4; |
||||
steps[3] = 1; |
||||
} |
||||
|
||||
Array4d(T* _a, int _n1, int _n2, int _n3, int _n4): |
||||
a(_a), n1(_n1), n2(_n2), n3(_n3), n4(_n4), needToDeallocArray(false) |
||||
{ |
||||
init_steps(); |
||||
} |
||||
|
||||
Array4d(int _n1, int _n2, int _n3, int _n4): |
||||
n1(_n1), n2(_n2), n3(_n3), n4(_n4), needToDeallocArray(true) |
||||
{ |
||||
a = new T[n1*n2*n3*n4]; |
||||
init_steps(); |
||||
} |
||||
|
||||
~Array4d() { |
||||
if (needToDeallocArray) { |
||||
delete[] a; |
||||
} |
||||
} |
||||
|
||||
Array3d<T> operator [] (int i) { |
||||
Array3d<T> array3d(a + i*n2*n3*n4, n2, n3, n4); |
||||
return array3d; |
||||
} |
||||
|
||||
inline T* row_ptr(int i1, int i2, int i3) { |
||||
return a + i1*n2*n3*n4 + i2*n3*n4 + i3*n4; |
||||
} |
||||
|
||||
inline int step_size(int dimension) { |
||||
return steps[dimension]; |
||||
} |
||||
}; |
||||
|
||||
#endif |
||||
|
||||
|
@ -1,242 +0,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*/
|
||||
|
||||
#include "precomp.hpp" |
||||
#include "opencv2/photo.hpp" |
||||
#include "opencv2/imgproc.hpp" |
||||
#include "fast_nlmeans_denoising_invoker.hpp" |
||||
#include "fast_nlmeans_multi_denoising_invoker.hpp" |
||||
|
||||
void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h, |
||||
int templateWindowSize, int searchWindowSize) |
||||
{ |
||||
Mat src = _src.getMat(); |
||||
_dst.create(src.size(), src.type()); |
||||
Mat dst = _dst.getMat(); |
||||
|
||||
#ifdef HAVE_TEGRA_OPTIMIZATION |
||||
if(tegra::fastNlMeansDenoising(src, dst, h, templateWindowSize, searchWindowSize)) |
||||
return; |
||||
#endif |
||||
|
||||
switch (src.type()) { |
||||
case CV_8U: |
||||
parallel_for(cv::BlockedRange(0, src.rows), |
||||
FastNlMeansDenoisingInvoker<uchar>( |
||||
src, dst, templateWindowSize, searchWindowSize, h)); |
||||
break; |
||||
case CV_8UC2: |
||||
parallel_for(cv::BlockedRange(0, src.rows), |
||||
FastNlMeansDenoisingInvoker<cv::Vec2b>( |
||||
src, dst, templateWindowSize, searchWindowSize, h)); |
||||
break; |
||||
case CV_8UC3: |
||||
parallel_for(cv::BlockedRange(0, src.rows), |
||||
FastNlMeansDenoisingInvoker<cv::Vec3b>( |
||||
src, dst, templateWindowSize, searchWindowSize, h)); |
||||
break; |
||||
default: |
||||
CV_Error(Error::StsBadArg, |
||||
"Unsupported image format! Only CV_8UC1, CV_8UC2 and CV_8UC3 are supported"); |
||||
} |
||||
} |
||||
|
||||
void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst, |
||||
float h, float hForColorComponents, |
||||
int templateWindowSize, int searchWindowSize) |
||||
{ |
||||
Mat src = _src.getMat(); |
||||
_dst.create(src.size(), src.type()); |
||||
Mat dst = _dst.getMat(); |
||||
|
||||
if (src.type() != CV_8UC3) { |
||||
CV_Error(Error::StsBadArg, "Type of input image should be CV_8UC3!"); |
||||
return; |
||||
} |
||||
|
||||
Mat src_lab; |
||||
cvtColor(src, src_lab, COLOR_LBGR2Lab); |
||||
|
||||
Mat l(src.size(), CV_8U); |
||||
Mat ab(src.size(), CV_8UC2); |
||||
Mat l_ab[] = { l, ab }; |
||||
int from_to[] = { 0,0, 1,1, 2,2 }; |
||||
mixChannels(&src_lab, 1, l_ab, 2, from_to, 3); |
||||
|
||||
fastNlMeansDenoising(l, l, h, templateWindowSize, searchWindowSize); |
||||
fastNlMeansDenoising(ab, ab, hForColorComponents, templateWindowSize, searchWindowSize); |
||||
|
||||
Mat l_ab_denoised[] = { l, ab }; |
||||
Mat dst_lab(src.size(), src.type()); |
||||
mixChannels(l_ab_denoised, 2, &dst_lab, 1, from_to, 3); |
||||
|
||||
cvtColor(dst_lab, dst, COLOR_Lab2LBGR); |
||||
} |
||||
|
||||
static void fastNlMeansDenoisingMultiCheckPreconditions( |
||||
const std::vector<Mat>& srcImgs, |
||||
int imgToDenoiseIndex, int temporalWindowSize, |
||||
int templateWindowSize, int searchWindowSize) |
||||
{ |
||||
int src_imgs_size = (int)srcImgs.size(); |
||||
if (src_imgs_size == 0) { |
||||
CV_Error(Error::StsBadArg, "Input images vector should not be empty!"); |
||||
} |
||||
|
||||
if (temporalWindowSize % 2 == 0 || |
||||
searchWindowSize % 2 == 0 || |
||||
templateWindowSize % 2 == 0) { |
||||
CV_Error(Error::StsBadArg, "All windows sizes should be odd!"); |
||||
} |
||||
|
||||
int temporalWindowHalfSize = temporalWindowSize / 2; |
||||
if (imgToDenoiseIndex - temporalWindowHalfSize < 0 || |
||||
imgToDenoiseIndex + temporalWindowHalfSize >= src_imgs_size) |
||||
{ |
||||
CV_Error(Error::StsBadArg, |
||||
"imgToDenoiseIndex and temporalWindowSize " |
||||
"should be choosen corresponding srcImgs size!"); |
||||
} |
||||
|
||||
for (int i = 1; i < src_imgs_size; i++) { |
||||
if (srcImgs[0].size() != srcImgs[i].size() || srcImgs[0].type() != srcImgs[i].type()) { |
||||
CV_Error(Error::StsBadArg, "Input images should have the same size and type!"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst, |
||||
int imgToDenoiseIndex, int temporalWindowSize, |
||||
float h, int templateWindowSize, int searchWindowSize) |
||||
{ |
||||
std::vector<Mat> srcImgs; |
||||
_srcImgs.getMatVector(srcImgs); |
||||
|
||||
fastNlMeansDenoisingMultiCheckPreconditions( |
||||
srcImgs, imgToDenoiseIndex, |
||||
temporalWindowSize, templateWindowSize, searchWindowSize |
||||
); |
||||
_dst.create(srcImgs[0].size(), srcImgs[0].type()); |
||||
Mat dst = _dst.getMat(); |
||||
|
||||
switch (srcImgs[0].type()) { |
||||
case CV_8U: |
||||
parallel_for(cv::BlockedRange(0, srcImgs[0].rows), |
||||
FastNlMeansMultiDenoisingInvoker<uchar>( |
||||
srcImgs, imgToDenoiseIndex, temporalWindowSize, |
||||
dst, templateWindowSize, searchWindowSize, h)); |
||||
break; |
||||
case CV_8UC2: |
||||
parallel_for(cv::BlockedRange(0, srcImgs[0].rows), |
||||
FastNlMeansMultiDenoisingInvoker<cv::Vec2b>( |
||||
srcImgs, imgToDenoiseIndex, temporalWindowSize, |
||||
dst, templateWindowSize, searchWindowSize, h)); |
||||
break; |
||||
case CV_8UC3: |
||||
parallel_for(cv::BlockedRange(0, srcImgs[0].rows), |
||||
FastNlMeansMultiDenoisingInvoker<cv::Vec3b>( |
||||
srcImgs, imgToDenoiseIndex, temporalWindowSize, |
||||
dst, templateWindowSize, searchWindowSize, h)); |
||||
break; |
||||
default: |
||||
CV_Error(Error::StsBadArg, |
||||
"Unsupported matrix format! Only uchar, Vec2b, Vec3b are supported"); |
||||
} |
||||
} |
||||
|
||||
void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs, OutputArray _dst, |
||||
int imgToDenoiseIndex, int temporalWindowSize, |
||||
float h, float hForColorComponents, |
||||
int templateWindowSize, int searchWindowSize) |
||||
{ |
||||
std::vector<Mat> srcImgs; |
||||
_srcImgs.getMatVector(srcImgs); |
||||
|
||||
fastNlMeansDenoisingMultiCheckPreconditions( |
||||
srcImgs, imgToDenoiseIndex, |
||||
temporalWindowSize, templateWindowSize, searchWindowSize |
||||
); |
||||
|
||||
_dst.create(srcImgs[0].size(), srcImgs[0].type()); |
||||
Mat dst = _dst.getMat(); |
||||
|
||||
int src_imgs_size = (int)srcImgs.size(); |
||||
|
||||
if (srcImgs[0].type() != CV_8UC3) { |
||||
CV_Error(Error::StsBadArg, "Type of input images should be CV_8UC3!"); |
||||
return; |
||||
} |
||||
|
||||
int from_to[] = { 0,0, 1,1, 2,2 }; |
||||
|
||||
// TODO convert only required images
|
||||
std::vector<Mat> src_lab(src_imgs_size); |
||||
std::vector<Mat> l(src_imgs_size); |
||||
std::vector<Mat> ab(src_imgs_size); |
||||
for (int i = 0; i < src_imgs_size; i++) { |
||||
src_lab[i] = Mat::zeros(srcImgs[0].size(), CV_8UC3); |
||||
l[i] = Mat::zeros(srcImgs[0].size(), CV_8UC1); |
||||
ab[i] = Mat::zeros(srcImgs[0].size(), CV_8UC2); |
||||
cvtColor(srcImgs[i], src_lab[i], COLOR_LBGR2Lab); |
||||
|
||||
Mat l_ab[] = { l[i], ab[i] }; |
||||
mixChannels(&src_lab[i], 1, l_ab, 2, from_to, 3); |
||||
} |
||||
|
||||
Mat dst_l; |
||||
Mat dst_ab; |
||||
|
||||
fastNlMeansDenoisingMulti( |
||||
l, dst_l, imgToDenoiseIndex, temporalWindowSize, |
||||
h, templateWindowSize, searchWindowSize); |
||||
|
||||
fastNlMeansDenoisingMulti( |
||||
ab, dst_ab, imgToDenoiseIndex, temporalWindowSize, |
||||
hForColorComponents, templateWindowSize, searchWindowSize); |
||||
|
||||
Mat l_ab_denoised[] = { dst_l, dst_ab }; |
||||
Mat dst_lab(srcImgs[0].size(), srcImgs[0].type()); |
||||
mixChannels(l_ab_denoised, 2, &dst_lab, 1, from_to, 3); |
||||
|
||||
cvtColor(dst_lab, dst, COLOR_Lab2LBGR); |
||||
} |
||||
|
||||
|
@ -1,334 +0,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_FAST_NLMEANS_DENOISING_INVOKER_HPP__ |
||||
#define __OPENCV_FAST_NLMEANS_DENOISING_INVOKER_HPP__ |
||||
|
||||
#include "precomp.hpp" |
||||
#include <limits> |
||||
|
||||
#include "fast_nlmeans_denoising_invoker_commons.hpp" |
||||
#include "arrays.hpp" |
||||
|
||||
using namespace cv; |
||||
|
||||
template <typename T> |
||||
struct FastNlMeansDenoisingInvoker { |
||||
public: |
||||
FastNlMeansDenoisingInvoker(const Mat& src, Mat& dst, |
||||
int template_window_size, int search_window_size, const float h); |
||||
|
||||
void operator() (const BlockedRange& range) const; |
||||
|
||||
private: |
||||
void operator= (const FastNlMeansDenoisingInvoker&); |
||||
|
||||
const Mat& src_; |
||||
Mat& dst_; |
||||
|
||||
Mat extended_src_; |
||||
int border_size_; |
||||
|
||||
int template_window_size_; |
||||
int search_window_size_; |
||||
|
||||
int template_window_half_size_; |
||||
int search_window_half_size_; |
||||
|
||||
int fixed_point_mult_; |
||||
int almost_template_window_size_sq_bin_shift_; |
||||
std::vector<int> almost_dist2weight_; |
||||
|
||||
void calcDistSumsForFirstElementInRow( |
||||
int i, |
||||
Array2d<int>& dist_sums, |
||||
Array3d<int>& col_dist_sums, |
||||
Array3d<int>& up_col_dist_sums) const; |
||||
|
||||
void calcDistSumsForElementInFirstRow( |
||||
int i, |
||||
int j, |
||||
int first_col_num, |
||||
Array2d<int>& dist_sums, |
||||
Array3d<int>& col_dist_sums, |
||||
Array3d<int>& up_col_dist_sums) const; |
||||
}; |
||||
|
||||
inline int getNearestPowerOf2(int value) |
||||
{ |
||||
int p = 0; |
||||
while( 1 << p < value) ++p; |
||||
return p; |
||||
} |
||||
|
||||
template <class T> |
||||
FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker( |
||||
const cv::Mat& src, |
||||
cv::Mat& dst, |
||||
int template_window_size, |
||||
int search_window_size, |
||||
const float h) : src_(src), dst_(dst) |
||||
{ |
||||
CV_Assert(src.channels() == sizeof(T)); //T is Vec1b or Vec2b or Vec3b
|
||||
|
||||
template_window_half_size_ = template_window_size / 2; |
||||
search_window_half_size_ = search_window_size / 2; |
||||
template_window_size_ = template_window_half_size_ * 2 + 1; |
||||
search_window_size_ = search_window_half_size_ * 2 + 1; |
||||
|
||||
border_size_ = search_window_half_size_ + template_window_half_size_; |
||||
copyMakeBorder(src_, extended_src_, |
||||
border_size_, border_size_, border_size_, border_size_, cv::BORDER_DEFAULT); |
||||
|
||||
const int max_estimate_sum_value = search_window_size_ * search_window_size_ * 255; |
||||
fixed_point_mult_ = std::numeric_limits<int>::max() / max_estimate_sum_value; |
||||
|
||||
// precalc weight for every possible l2 dist between blocks
|
||||
// additional optimization of precalced weights to replace division(averaging) by binary shift
|
||||
|
||||
CV_Assert(template_window_size_ <= 46340 ); // sqrt(INT_MAX)
|
||||
int template_window_size_sq = template_window_size_ * template_window_size_; |
||||
almost_template_window_size_sq_bin_shift_ = getNearestPowerOf2(template_window_size_sq); |
||||
double almost_dist2actual_dist_multiplier = ((double)(1 << almost_template_window_size_sq_bin_shift_)) / template_window_size_sq; |
||||
|
||||
int max_dist = 255 * 255 * sizeof(T); |
||||
int almost_max_dist = (int) (max_dist / almost_dist2actual_dist_multiplier + 1); |
||||
almost_dist2weight_.resize(almost_max_dist); |
||||
|
||||
const double WEIGHT_THRESHOLD = 0.001; |
||||
for (int almost_dist = 0; almost_dist < almost_max_dist; almost_dist++) { |
||||
double dist = almost_dist * almost_dist2actual_dist_multiplier; |
||||
int weight = cvRound(fixed_point_mult_ * std::exp(-dist / (h * h * sizeof(T)))); |
||||
|
||||
if (weight < WEIGHT_THRESHOLD * fixed_point_mult_) |
||||
weight = 0; |
||||
|
||||
almost_dist2weight_[almost_dist] = weight; |
||||
} |
||||
CV_Assert(almost_dist2weight_[0] == fixed_point_mult_); |
||||
// additional optimization init end
|
||||
|
||||
if (dst_.empty()) { |
||||
dst_ = Mat::zeros(src_.size(), src_.type()); |
||||
} |
||||
} |
||||
|
||||
template <class T> |
||||
void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) const { |
||||
int row_from = range.begin(); |
||||
int row_to = range.end() - 1; |
||||
|
||||
Array2d<int> dist_sums(search_window_size_, search_window_size_); |
||||
|
||||
// for lazy calc optimization
|
||||
Array3d<int> col_dist_sums(template_window_size_, search_window_size_, search_window_size_); |
||||
|
||||
int first_col_num = -1; |
||||
Array3d<int> up_col_dist_sums(src_.cols, search_window_size_, search_window_size_); |
||||
|
||||
for (int i = row_from; i <= row_to; i++) { |
||||
for (int j = 0; j < src_.cols; j++) { |
||||
int search_window_y = i - search_window_half_size_; |
||||
int search_window_x = j - search_window_half_size_; |
||||
|
||||
// calc dist_sums
|
||||
if (j == 0) { |
||||
calcDistSumsForFirstElementInRow(i, dist_sums, col_dist_sums, up_col_dist_sums); |
||||
first_col_num = 0; |
||||
|
||||
} else { // calc cur dist_sums using previous dist_sums
|
||||
if (i == row_from) { |
||||
calcDistSumsForElementInFirstRow(i, j, first_col_num, |
||||
dist_sums, col_dist_sums, up_col_dist_sums); |
||||
|
||||
} else { |
||||
int ay = border_size_ + i; |
||||
int ax = border_size_ + j + template_window_half_size_; |
||||
|
||||
int start_by = |
||||
border_size_ + i - search_window_half_size_; |
||||
|
||||
int start_bx = |
||||
border_size_ + j - search_window_half_size_ + template_window_half_size_; |
||||
|
||||
T a_up = extended_src_.at<T>(ay - template_window_half_size_ - 1, ax); |
||||
T a_down = extended_src_.at<T>(ay + template_window_half_size_, ax); |
||||
|
||||
// copy class member to local variable for optimization
|
||||
int search_window_size = search_window_size_; |
||||
|
||||
for (int y = 0; y < search_window_size; y++) { |
||||
int* dist_sums_row = dist_sums.row_ptr(y); |
||||
|
||||
int* col_dist_sums_row = col_dist_sums.row_ptr(first_col_num,y); |
||||
|
||||
int* up_col_dist_sums_row = up_col_dist_sums.row_ptr(j, y); |
||||
|
||||
const T* b_up_ptr = |
||||
extended_src_.ptr<T>(start_by - template_window_half_size_ - 1 + y); |
||||
|
||||
const T* b_down_ptr = |
||||
extended_src_.ptr<T>(start_by + template_window_half_size_ + y); |
||||
|
||||
for (int x = 0; x < search_window_size; x++) { |
||||
dist_sums_row[x] -= col_dist_sums_row[x]; |
||||
|
||||
col_dist_sums_row[x] = |
||||
up_col_dist_sums_row[x] + |
||||
calcUpDownDist( |
||||
a_up, a_down, |
||||
b_up_ptr[start_bx + x], b_down_ptr[start_bx + x] |
||||
); |
||||
|
||||
dist_sums_row[x] += col_dist_sums_row[x]; |
||||
|
||||
up_col_dist_sums_row[x] = col_dist_sums_row[x]; |
||||
|
||||
} |
||||
} |
||||
} |
||||
|
||||
first_col_num = (first_col_num + 1) % template_window_size_; |
||||
} |
||||
|
||||
// calc weights
|
||||
int weights_sum = 0; |
||||
|
||||
int estimation[3]; |
||||
for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++) { |
||||
estimation[channel_num] = 0; |
||||
} |
||||
|
||||
for (int y = 0; y < search_window_size_; y++) { |
||||
const T* cur_row_ptr = extended_src_.ptr<T>(border_size_ + search_window_y + y); |
||||
int* dist_sums_row = dist_sums.row_ptr(y); |
||||
for (int x = 0; x < search_window_size_; x++) { |
||||
int almostAvgDist = |
||||
dist_sums_row[x] >> almost_template_window_size_sq_bin_shift_; |
||||
|
||||
int weight = almost_dist2weight_[almostAvgDist]; |
||||
weights_sum += weight; |
||||
|
||||
T p = cur_row_ptr[border_size_ + search_window_x + x]; |
||||
incWithWeight(estimation, weight, p); |
||||
} |
||||
} |
||||
|
||||
for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++) |
||||
estimation[channel_num] = ((unsigned)estimation[channel_num] + weights_sum/2) / weights_sum; |
||||
|
||||
dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation); |
||||
} |
||||
} |
||||
} |
||||
|
||||
template <class T> |
||||
inline void FastNlMeansDenoisingInvoker<T>::calcDistSumsForFirstElementInRow( |
||||
int i, |
||||
Array2d<int>& dist_sums, |
||||
Array3d<int>& col_dist_sums, |
||||
Array3d<int>& up_col_dist_sums) const |
||||
{ |
||||
int j = 0; |
||||
|
||||
for (int y = 0; y < search_window_size_; y++) { |
||||
for (int x = 0; x < search_window_size_; x++) { |
||||
dist_sums[y][x] = 0; |
||||
for (int tx = 0; tx < template_window_size_; tx++) { |
||||
col_dist_sums[tx][y][x] = 0; |
||||
} |
||||
|
||||
int start_y = i + y - search_window_half_size_; |
||||
int start_x = j + x - search_window_half_size_; |
||||
|
||||
for (int ty = -template_window_half_size_; ty <= template_window_half_size_; ty++) { |
||||
for (int tx = -template_window_half_size_; tx <= template_window_half_size_; tx++) { |
||||
int dist = calcDist<T>(extended_src_, |
||||
border_size_ + i + ty, border_size_ + j + tx, |
||||
border_size_ + start_y + ty, border_size_ + start_x + tx); |
||||
|
||||
dist_sums[y][x] += dist; |
||||
col_dist_sums[tx + template_window_half_size_][y][x] += dist; |
||||
} |
||||
} |
||||
|
||||
up_col_dist_sums[j][y][x] = col_dist_sums[template_window_size_ - 1][y][x]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
template <class T> |
||||
inline void FastNlMeansDenoisingInvoker<T>::calcDistSumsForElementInFirstRow( |
||||
int i, |
||||
int j, |
||||
int first_col_num, |
||||
Array2d<int>& dist_sums, |
||||
Array3d<int>& col_dist_sums, |
||||
Array3d<int>& up_col_dist_sums) const |
||||
{ |
||||
int ay = border_size_ + i; |
||||
int ax = border_size_ + j + template_window_half_size_; |
||||
|
||||
int start_by = border_size_ + i - search_window_half_size_; |
||||
int start_bx = border_size_ + j - search_window_half_size_ + template_window_half_size_; |
||||
|
||||
int new_last_col_num = first_col_num; |
||||
|
||||
for (int y = 0; y < search_window_size_; y++) { |
||||
for (int x = 0; x < search_window_size_; x++) { |
||||
dist_sums[y][x] -= col_dist_sums[first_col_num][y][x]; |
||||
|
||||
col_dist_sums[new_last_col_num][y][x] = 0; |
||||
int by = start_by + y; |
||||
int bx = start_bx + x; |
||||
for (int ty = -template_window_half_size_; ty <= template_window_half_size_; ty++) { |
||||
col_dist_sums[new_last_col_num][y][x] += |
||||
calcDist<T>(extended_src_, ay + ty, ax, by + ty, bx); |
||||
} |
||||
|
||||
dist_sums[y][x] += col_dist_sums[new_last_col_num][y][x]; |
||||
|
||||
up_col_dist_sums[j][y][x] = col_dist_sums[new_last_col_num][y][x]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -1,115 +0,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_FAST_NLMEANS_DENOISING_INVOKER_COMMONS_HPP__ |
||||
#define __OPENCV_FAST_NLMEANS_DENOISING_INVOKER_COMMONS_HPP__ |
||||
|
||||
using namespace cv; |
||||
|
||||
template <typename T> static inline int calcDist(const T a, const T b); |
||||
|
||||
template <> inline int calcDist(const uchar a, const uchar b) { |
||||
return (a-b) * (a-b); |
||||
} |
||||
|
||||
template <> inline int calcDist(const Vec2b a, const Vec2b b) { |
||||
return (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]); |
||||
} |
||||
|
||||
template <> inline int calcDist(const Vec3b a, const Vec3b b) { |
||||
return (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2]); |
||||
} |
||||
|
||||
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(a_down,b_down) - calcDist(a_up, b_up); |
||||
} |
||||
|
||||
template <> inline int calcUpDownDist(uchar a_up, uchar a_down, uchar b_up, uchar b_down) { |
||||
int A = a_down - b_down; |
||||
int B = a_up - b_up; |
||||
return (A-B)*(A+B); |
||||
} |
||||
|
||||
template <typename T> static inline void incWithWeight(int* estimation, int weight, T p); |
||||
|
||||
template <> inline void incWithWeight(int* estimation, int weight, uchar p) { |
||||
estimation[0] += weight * p; |
||||
} |
||||
|
||||
template <> inline void incWithWeight(int* estimation, int weight, Vec2b p) { |
||||
estimation[0] += weight * p[0]; |
||||
estimation[1] += weight * p[1]; |
||||
} |
||||
|
||||
template <> inline void incWithWeight(int* estimation, int weight, Vec3b p) { |
||||
estimation[0] += weight * p[0]; |
||||
estimation[1] += weight * p[1]; |
||||
estimation[2] += weight * p[2]; |
||||
} |
||||
|
||||
template <typename T> static inline T saturateCastFromArray(int* estimation); |
||||
|
||||
template <> inline uchar saturateCastFromArray(int* estimation) { |
||||
return saturate_cast<uchar>(estimation[0]); |
||||
} |
||||
|
||||
template <> inline Vec2b saturateCastFromArray(int* estimation) { |
||||
Vec2b res; |
||||
res[0] = saturate_cast<uchar>(estimation[0]); |
||||
res[1] = saturate_cast<uchar>(estimation[1]); |
||||
return res; |
||||
} |
||||
|
||||
template <> inline Vec3b saturateCastFromArray(int* estimation) { |
||||
Vec3b res; |
||||
res[0] = saturate_cast<uchar>(estimation[0]); |
||||
res[1] = saturate_cast<uchar>(estimation[1]); |
||||
res[2] = saturate_cast<uchar>(estimation[2]); |
||||
return res; |
||||
} |
||||
|
||||
#endif |
@ -1,383 +0,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_FAST_NLMEANS_MULTI_DENOISING_INVOKER_HPP__ |
||||
#define __OPENCV_FAST_NLMEANS_MULTI_DENOISING_INVOKER_HPP__ |
||||
|
||||
#include "precomp.hpp" |
||||
#include <limits> |
||||
|
||||
#include "fast_nlmeans_denoising_invoker_commons.hpp" |
||||
#include "arrays.hpp" |
||||
|
||||
using namespace cv; |
||||
|
||||
template <typename T> |
||||
struct FastNlMeansMultiDenoisingInvoker { |
||||
public: |
||||
FastNlMeansMultiDenoisingInvoker( |
||||
const std::vector<Mat>& srcImgs, int imgToDenoiseIndex, int temporalWindowSize, |
||||
Mat& dst, int template_window_size, int search_window_size, const float h); |
||||
|
||||
void operator() (const BlockedRange& range) const; |
||||
|
||||
private: |
||||
void operator= (const FastNlMeansMultiDenoisingInvoker&); |
||||
|
||||
int rows_; |
||||
int cols_; |
||||
|
||||
Mat& dst_; |
||||
|
||||
std::vector<Mat> extended_srcs_; |
||||
Mat main_extended_src_; |
||||
int border_size_; |
||||
|
||||
int template_window_size_; |
||||
int search_window_size_; |
||||
int temporal_window_size_; |
||||
|
||||
int template_window_half_size_; |
||||
int search_window_half_size_; |
||||
int temporal_window_half_size_; |
||||
|
||||
int fixed_point_mult_; |
||||
int almost_template_window_size_sq_bin_shift; |
||||
std::vector<int> almost_dist2weight; |
||||
|
||||
void calcDistSumsForFirstElementInRow( |
||||
int i, |
||||
Array3d<int>& dist_sums, |
||||
Array4d<int>& col_dist_sums, |
||||
Array4d<int>& up_col_dist_sums) const; |
||||
|
||||
void calcDistSumsForElementInFirstRow( |
||||
int i, |
||||
int j, |
||||
int first_col_num, |
||||
Array3d<int>& dist_sums, |
||||
Array4d<int>& col_dist_sums, |
||||
Array4d<int>& up_col_dist_sums) const; |
||||
}; |
||||
|
||||
template <class T> |
||||
FastNlMeansMultiDenoisingInvoker<T>::FastNlMeansMultiDenoisingInvoker( |
||||
const std::vector<Mat>& srcImgs, |
||||
int imgToDenoiseIndex, |
||||
int temporalWindowSize, |
||||
cv::Mat& dst, |
||||
int template_window_size, |
||||
int search_window_size, |
||||
const float h) : dst_(dst), extended_srcs_(srcImgs.size()) |
||||
{ |
||||
CV_Assert(srcImgs.size() > 0); |
||||
CV_Assert(srcImgs[0].channels() == sizeof(T)); |
||||
|
||||
rows_ = srcImgs[0].rows; |
||||
cols_ = srcImgs[0].cols; |
||||
|
||||
template_window_half_size_ = template_window_size / 2; |
||||
search_window_half_size_ = search_window_size / 2; |
||||
temporal_window_half_size_ = temporalWindowSize / 2; |
||||
|
||||
template_window_size_ = template_window_half_size_ * 2 + 1; |
||||
search_window_size_ = search_window_half_size_ * 2 + 1; |
||||
temporal_window_size_ = temporal_window_half_size_ * 2 + 1; |
||||
|
||||
border_size_ = search_window_half_size_ + template_window_half_size_; |
||||
for (int i = 0; i < temporal_window_size_; i++) { |
||||
copyMakeBorder( |
||||
srcImgs[imgToDenoiseIndex - temporal_window_half_size_ + i], extended_srcs_[i], |
||||
border_size_, border_size_, border_size_, border_size_, cv::BORDER_DEFAULT); |
||||
} |
||||
main_extended_src_ = extended_srcs_[temporal_window_half_size_]; |
||||
|
||||
const int max_estimate_sum_value = |
||||
temporal_window_size_ * search_window_size_ * search_window_size_ * 255; |
||||
|
||||
fixed_point_mult_ = std::numeric_limits<int>::max() / max_estimate_sum_value; |
||||
|
||||
// precalc weight for every possible l2 dist between blocks
|
||||
// additional optimization of precalced weights to replace division(averaging) by binary shift
|
||||
int template_window_size_sq = template_window_size_ * template_window_size_; |
||||
almost_template_window_size_sq_bin_shift = 0; |
||||
while (1 << almost_template_window_size_sq_bin_shift < template_window_size_sq) { |
||||
almost_template_window_size_sq_bin_shift++; |
||||
} |
||||
|
||||
int almost_template_window_size_sq = 1 << almost_template_window_size_sq_bin_shift; |
||||
double almost_dist2actual_dist_multiplier = |
||||
((double) almost_template_window_size_sq) / template_window_size_sq; |
||||
|
||||
int max_dist = 255 * 255 * sizeof(T); |
||||
int almost_max_dist = (int) (max_dist / almost_dist2actual_dist_multiplier + 1); |
||||
almost_dist2weight.resize(almost_max_dist); |
||||
|
||||
const double WEIGHT_THRESHOLD = 0.001; |
||||
for (int almost_dist = 0; almost_dist < almost_max_dist; almost_dist++) { |
||||
double dist = almost_dist * almost_dist2actual_dist_multiplier; |
||||
int weight = cvRound(fixed_point_mult_ * std::exp(-dist / (h * h * sizeof(T)))); |
||||
|
||||
if (weight < WEIGHT_THRESHOLD * fixed_point_mult_) { |
||||
weight = 0; |
||||
} |
||||
|
||||
almost_dist2weight[almost_dist] = weight; |
||||
} |
||||
CV_Assert(almost_dist2weight[0] == fixed_point_mult_); |
||||
// additional optimization init end
|
||||
|
||||
if (dst_.empty()) { |
||||
dst_ = Mat::zeros(srcImgs[0].size(), srcImgs[0].type()); |
||||
} |
||||
} |
||||
|
||||
template <class T> |
||||
void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range) const { |
||||
int row_from = range.begin(); |
||||
int row_to = range.end() - 1; |
||||
|
||||
Array3d<int> dist_sums(temporal_window_size_, search_window_size_, search_window_size_); |
||||
|
||||
// for lazy calc optimization
|
||||
Array4d<int> col_dist_sums( |
||||
template_window_size_, temporal_window_size_, search_window_size_, search_window_size_); |
||||
|
||||
int first_col_num = -1; |
||||
|
||||
Array4d<int> up_col_dist_sums( |
||||
cols_, temporal_window_size_, search_window_size_, search_window_size_); |
||||
|
||||
for (int i = row_from; i <= row_to; i++) { |
||||
for (int j = 0; j < cols_; j++) { |
||||
int search_window_y = i - search_window_half_size_; |
||||
int search_window_x = j - search_window_half_size_; |
||||
|
||||
// calc dist_sums
|
||||
if (j == 0) { |
||||
calcDistSumsForFirstElementInRow(i, dist_sums, col_dist_sums, up_col_dist_sums); |
||||
first_col_num = 0; |
||||
|
||||
} else { // calc cur dist_sums using previous dist_sums
|
||||
if (i == row_from) { |
||||
calcDistSumsForElementInFirstRow(i, j, first_col_num, |
||||
dist_sums, col_dist_sums, up_col_dist_sums); |
||||
|
||||
} else { |
||||
int ay = border_size_ + i; |
||||
int ax = border_size_ + j + template_window_half_size_; |
||||
|
||||
int start_by = |
||||
border_size_ + i - search_window_half_size_; |
||||
|
||||
int start_bx = |
||||
border_size_ + j - search_window_half_size_ + template_window_half_size_; |
||||
|
||||
T a_up = main_extended_src_.at<T>(ay - template_window_half_size_ - 1, ax); |
||||
T a_down = main_extended_src_.at<T>(ay + template_window_half_size_, ax); |
||||
|
||||
// copy class member to local variable for optimization
|
||||
int search_window_size = search_window_size_; |
||||
|
||||
for (int d = 0; d < temporal_window_size_; d++) { |
||||
Mat cur_extended_src = extended_srcs_[d]; |
||||
Array2d<int> cur_dist_sums = dist_sums[d]; |
||||
Array2d<int> cur_col_dist_sums = col_dist_sums[first_col_num][d]; |
||||
Array2d<int> cur_up_col_dist_sums = up_col_dist_sums[j][d]; |
||||
for (int y = 0; y < search_window_size; y++) { |
||||
int* dist_sums_row = cur_dist_sums.row_ptr(y); |
||||
|
||||
int* col_dist_sums_row = cur_col_dist_sums.row_ptr(y); |
||||
|
||||
int* up_col_dist_sums_row = cur_up_col_dist_sums.row_ptr(y); |
||||
|
||||
const T* b_up_ptr = |
||||
cur_extended_src.ptr<T>(start_by - template_window_half_size_ - 1 + y); |
||||
const T* b_down_ptr = |
||||
cur_extended_src.ptr<T>(start_by + template_window_half_size_ + y); |
||||
|
||||
for (int x = 0; x < search_window_size; x++) { |
||||
dist_sums_row[x] -= col_dist_sums_row[x]; |
||||
|
||||
col_dist_sums_row[x] = up_col_dist_sums_row[x] + |
||||
calcUpDownDist( |
||||
a_up, a_down, |
||||
b_up_ptr[start_bx + x], b_down_ptr[start_bx + x] |
||||
); |
||||
|
||||
dist_sums_row[x] += col_dist_sums_row[x]; |
||||
|
||||
up_col_dist_sums_row[x] = col_dist_sums_row[x]; |
||||
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
first_col_num = (first_col_num + 1) % template_window_size_; |
||||
} |
||||
|
||||
// calc weights
|
||||
int weights_sum = 0; |
||||
|
||||
int estimation[3]; |
||||
for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++) { |
||||
estimation[channel_num] = 0; |
||||
} |
||||
for (int d = 0; d < temporal_window_size_; d++) { |
||||
const Mat& esrc_d = extended_srcs_[d]; |
||||
for (int y = 0; y < search_window_size_; y++) { |
||||
const T* cur_row_ptr = esrc_d.ptr<T>(border_size_ + search_window_y + y); |
||||
|
||||
int* dist_sums_row = dist_sums.row_ptr(d, y); |
||||
|
||||
for (int x = 0; x < search_window_size_; x++) { |
||||
int almostAvgDist = |
||||
dist_sums_row[x] >> almost_template_window_size_sq_bin_shift; |
||||
|
||||
int weight = almost_dist2weight[almostAvgDist]; |
||||
weights_sum += weight; |
||||
|
||||
T p = cur_row_ptr[border_size_ + search_window_x + x]; |
||||
incWithWeight(estimation, weight, p); |
||||
} |
||||
} |
||||
} |
||||
|
||||
for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++) |
||||
estimation[channel_num] = ((unsigned)estimation[channel_num] + weights_sum / 2) / weights_sum; |
||||
|
||||
dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation); |
||||
|
||||
} |
||||
} |
||||
} |
||||
|
||||
template <class T> |
||||
inline void FastNlMeansMultiDenoisingInvoker<T>::calcDistSumsForFirstElementInRow( |
||||
int i, |
||||
Array3d<int>& dist_sums, |
||||
Array4d<int>& col_dist_sums, |
||||
Array4d<int>& up_col_dist_sums) const |
||||
{ |
||||
int j = 0; |
||||
|
||||
for (int d = 0; d < temporal_window_size_; d++) { |
||||
Mat cur_extended_src = extended_srcs_[d]; |
||||
for (int y = 0; y < search_window_size_; y++) { |
||||
for (int x = 0; x < search_window_size_; x++) { |
||||
dist_sums[d][y][x] = 0; |
||||
for (int tx = 0; tx < template_window_size_; tx++) { |
||||
col_dist_sums[tx][d][y][x] = 0; |
||||
} |
||||
|
||||
int start_y = i + y - search_window_half_size_; |
||||
int start_x = j + x - search_window_half_size_; |
||||
|
||||
int* dist_sums_ptr = &dist_sums[d][y][x]; |
||||
int* col_dist_sums_ptr = &col_dist_sums[0][d][y][x]; |
||||
int col_dist_sums_step = col_dist_sums.step_size(0); |
||||
for (int tx = -template_window_half_size_; tx <= template_window_half_size_; tx++) { |
||||
for (int ty = -template_window_half_size_; ty <= template_window_half_size_; ty++) { |
||||
int dist = calcDist<T>( |
||||
main_extended_src_.at<T>( |
||||
border_size_ + i + ty, border_size_ + j + tx), |
||||
cur_extended_src.at<T>( |
||||
border_size_ + start_y + ty, border_size_ + start_x + tx) |
||||
); |
||||
|
||||
*dist_sums_ptr += dist; |
||||
*col_dist_sums_ptr += dist; |
||||
} |
||||
col_dist_sums_ptr += col_dist_sums_step; |
||||
} |
||||
|
||||
up_col_dist_sums[j][d][y][x] = col_dist_sums[template_window_size_ - 1][d][y][x]; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
template <class T> |
||||
inline void FastNlMeansMultiDenoisingInvoker<T>::calcDistSumsForElementInFirstRow( |
||||
int i, |
||||
int j, |
||||
int first_col_num, |
||||
Array3d<int>& dist_sums, |
||||
Array4d<int>& col_dist_sums, |
||||
Array4d<int>& up_col_dist_sums) const |
||||
{ |
||||
int ay = border_size_ + i; |
||||
int ax = border_size_ + j + template_window_half_size_; |
||||
|
||||
int start_by = border_size_ + i - search_window_half_size_; |
||||
int start_bx = border_size_ + j - search_window_half_size_ + template_window_half_size_; |
||||
|
||||
int new_last_col_num = first_col_num; |
||||
|
||||
for (int d = 0; d < temporal_window_size_; d++) { |
||||
Mat cur_extended_src = extended_srcs_[d]; |
||||
for (int y = 0; y < search_window_size_; y++) { |
||||
for (int x = 0; x < search_window_size_; x++) { |
||||
dist_sums[d][y][x] -= col_dist_sums[first_col_num][d][y][x]; |
||||
|
||||
col_dist_sums[new_last_col_num][d][y][x] = 0; |
||||
int by = start_by + y; |
||||
int bx = start_bx + x; |
||||
|
||||
int* col_dist_sums_ptr = &col_dist_sums[new_last_col_num][d][y][x]; |
||||
for (int ty = -template_window_half_size_; ty <= template_window_half_size_; ty++) { |
||||
*col_dist_sums_ptr += |
||||
calcDist<T>( |
||||
main_extended_src_.at<T>(ay + ty, ax), |
||||
cur_extended_src.at<T>(by + ty, bx) |
||||
); |
||||
} |
||||
|
||||
dist_sums[d][y][x] += col_dist_sums[new_last_col_num][d][y][x]; |
||||
|
||||
up_col_dist_sums[j][d][y][x] = col_dist_sums[new_last_col_num][d][y][x]; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -1,817 +0,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*/
|
||||
|
||||
/* ////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Geometrical transforms on images and matrices: rotation, zoom etc.
|
||||
//
|
||||
// */
|
||||
|
||||
#include "precomp.hpp" |
||||
#include "opencv2/imgproc/imgproc_c.h" |
||||
#include "opencv2/photo/photo_c.h" |
||||
|
||||
#undef CV_MAT_ELEM_PTR_FAST |
||||
#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size ) \ |
||||
((mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col)) |
||||
|
||||
inline float |
||||
min4( float a, float b, float c, float d ) |
||||
{ |
||||
a = MIN(a,b); |
||||
c = MIN(c,d); |
||||
return MIN(a,c); |
||||
} |
||||
|
||||
#define CV_MAT_3COLOR_ELEM(img,type,y,x,c) CV_MAT_ELEM(img,type,y,(x)*3+(c)) |
||||
#define KNOWN 0 //known outside narrow band
|
||||
#define BAND 1 //narrow band (known)
|
||||
#define INSIDE 2 //unknown
|
||||
#define CHANGE 3 //servise
|
||||
|
||||
typedef struct CvHeapElem |
||||
{ |
||||
float T; |
||||
int i,j; |
||||
struct CvHeapElem* prev; |
||||
struct CvHeapElem* next; |
||||
} |
||||
CvHeapElem; |
||||
|
||||
|
||||
class CvPriorityQueueFloat |
||||
{ |
||||
protected: |
||||
CvHeapElem *mem,*empty,*head,*tail; |
||||
int num,in; |
||||
|
||||
public: |
||||
bool Init( const CvMat* f ) |
||||
{ |
||||
int i,j; |
||||
for( i = num = 0; i < f->rows; i++ ) |
||||
{ |
||||
for( j = 0; j < f->cols; j++ ) |
||||
num += CV_MAT_ELEM(*f,uchar,i,j)!=0; |
||||
} |
||||
if (num<=0) return false; |
||||
mem = (CvHeapElem*)cvAlloc((num+2)*sizeof(CvHeapElem)); |
||||
if (mem==NULL) return false; |
||||
|
||||
head = mem; |
||||
head->i = head->j = -1; |
||||
head->prev = NULL; |
||||
head->next = mem+1; |
||||
head->T = -FLT_MAX; |
||||
empty = mem+1; |
||||
for (i=1; i<=num; i++) { |
||||
mem[i].prev = mem+i-1; |
||||
mem[i].next = mem+i+1; |
||||
mem[i].i = -1; |
||||
mem[i].T = FLT_MAX; |
||||
} |
||||
tail = mem+i; |
||||
tail->i = tail->j = -1; |
||||
tail->prev = mem+i-1; |
||||
tail->next = NULL; |
||||
tail->T = FLT_MAX; |
||||
return true; |
||||
} |
||||
|
||||
bool Add(const CvMat* f) { |
||||
int i,j; |
||||
for (i=0; i<f->rows; i++) { |
||||
for (j=0; j<f->cols; j++) { |
||||
if (CV_MAT_ELEM(*f,uchar,i,j)!=0) { |
||||
if (!Push(i,j,0)) return false; |
||||
} |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
bool Push(int i, int j, float T) { |
||||
CvHeapElem *tmp=empty,*add=empty; |
||||
if (empty==tail) return false; |
||||
while (tmp->prev->T>T) tmp = tmp->prev; |
||||
if (tmp!=empty) { |
||||
add->prev->next = add->next; |
||||
add->next->prev = add->prev; |
||||
empty = add->next; |
||||
add->prev = tmp->prev; |
||||
add->next = tmp; |
||||
add->prev->next = add; |
||||
add->next->prev = add; |
||||
} else { |
||||
empty = empty->next; |
||||
} |
||||
add->i = i; |
||||
add->j = j; |
||||
add->T = T; |
||||
in++; |
||||
// printf("push i %3d j %3d T %12.4e in %4d\n",i,j,T,in);
|
||||
return true; |
||||
} |
||||
|
||||
bool Pop(int *i, int *j) { |
||||
CvHeapElem *tmp=head->next; |
||||
if (empty==tmp) return false; |
||||
*i = tmp->i; |
||||
*j = tmp->j; |
||||
tmp->prev->next = tmp->next; |
||||
tmp->next->prev = tmp->prev; |
||||
tmp->prev = empty->prev; |
||||
tmp->next = empty; |
||||
tmp->prev->next = tmp; |
||||
tmp->next->prev = tmp; |
||||
empty = tmp; |
||||
in--; |
||||
// printf("pop i %3d j %3d T %12.4e in %4d\n",tmp->i,tmp->j,tmp->T,in);
|
||||
return true; |
||||
} |
||||
|
||||
bool Pop(int *i, int *j, float *T) { |
||||
CvHeapElem *tmp=head->next; |
||||
if (empty==tmp) return false; |
||||
*i = tmp->i; |
||||
*j = tmp->j; |
||||
*T = tmp->T; |
||||
tmp->prev->next = tmp->next; |
||||
tmp->next->prev = tmp->prev; |
||||
tmp->prev = empty->prev; |
||||
tmp->next = empty; |
||||
tmp->prev->next = tmp; |
||||
tmp->next->prev = tmp; |
||||
empty = tmp; |
||||
in--; |
||||
// printf("pop i %3d j %3d T %12.4e in %4d\n",tmp->i,tmp->j,tmp->T,in);
|
||||
return true; |
||||
} |
||||
|
||||
CvPriorityQueueFloat(void) { |
||||
num=in=0; |
||||
mem=empty=head=tail=NULL; |
||||
} |
||||
|
||||
~CvPriorityQueueFloat(void) |
||||
{ |
||||
cvFree( &mem ); |
||||
} |
||||
}; |
||||
|
||||
inline float VectorScalMult(CvPoint2D32f v1,CvPoint2D32f v2) { |
||||
return v1.x*v2.x+v1.y*v2.y; |
||||
} |
||||
|
||||
inline float VectorLength(CvPoint2D32f v1) { |
||||
return v1.x*v1.x+v1.y*v1.y; |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
//HEAP::iterator Heap_Iterator;
|
||||
//HEAP Heap;
|
||||
|
||||
static float FastMarching_solve(int i1,int j1,int i2,int j2, const CvMat* f, const CvMat* t) |
||||
{ |
||||
double sol, a11, a22, m12; |
||||
a11=CV_MAT_ELEM(*t,float,i1,j1); |
||||
a22=CV_MAT_ELEM(*t,float,i2,j2); |
||||
m12=MIN(a11,a22); |
||||
|
||||
if( CV_MAT_ELEM(*f,uchar,i1,j1) != INSIDE ) |
||||
if( CV_MAT_ELEM(*f,uchar,i2,j2) != INSIDE ) |
||||
if( fabs(a11-a22) >= 1.0 ) |
||||
sol = 1+m12; |
||||
else |
||||
sol = (a11+a22+sqrt((double)(2-(a11-a22)*(a11-a22))))*0.5; |
||||
else |
||||
sol = 1+a11; |
||||
else if( CV_MAT_ELEM(*f,uchar,i2,j2) != INSIDE ) |
||||
sol = 1+a22; |
||||
else |
||||
sol = 1+m12; |
||||
|
||||
return (float)sol; |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static void |
||||
icvCalcFMM(const CvMat *f, CvMat *t, CvPriorityQueueFloat *Heap, bool negate) { |
||||
int i, j, ii = 0, jj = 0, q; |
||||
float dist; |
||||
|
||||
while (Heap->Pop(&ii,&jj)) { |
||||
|
||||
unsigned known=(negate)?CHANGE:KNOWN; |
||||
CV_MAT_ELEM(*f,uchar,ii,jj) = (uchar)known; |
||||
|
||||
for (q=0; q<4; q++) { |
||||
i=0; j=0; |
||||
if (q==0) {i=ii-1; j=jj;} |
||||
else if(q==1) {i=ii; j=jj-1;} |
||||
else if(q==2) {i=ii+1; j=jj;} |
||||
else {i=ii; j=jj+1;} |
||||
if ((i<=0)||(j<=0)||(i>f->rows)||(j>f->cols)) continue; |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,i,j)==INSIDE) { |
||||
dist = min4(FastMarching_solve(i-1,j,i,j-1,f,t), |
||||
FastMarching_solve(i+1,j,i,j-1,f,t), |
||||
FastMarching_solve(i-1,j,i,j+1,f,t), |
||||
FastMarching_solve(i+1,j,i,j+1,f,t)); |
||||
CV_MAT_ELEM(*t,float,i,j) = dist; |
||||
CV_MAT_ELEM(*f,uchar,i,j) = BAND; |
||||
Heap->Push(i,j,dist); |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (negate) { |
||||
for (i=0; i<f->rows; i++) { |
||||
for(j=0; j<f->cols; j++) { |
||||
if (CV_MAT_ELEM(*f,uchar,i,j) == CHANGE) { |
||||
CV_MAT_ELEM(*f,uchar,i,j) = KNOWN; |
||||
CV_MAT_ELEM(*t,float,i,j) = -CV_MAT_ELEM(*t,float,i,j); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
static void |
||||
icvTeleaInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQueueFloat *Heap ) { |
||||
int i = 0, j = 0, ii = 0, jj = 0, k, l, q, color = 0; |
||||
float dist; |
||||
|
||||
if (CV_MAT_CN(out->type)==3) { |
||||
|
||||
while (Heap->Pop(&ii,&jj)) { |
||||
|
||||
CV_MAT_ELEM(*f,uchar,ii,jj) = KNOWN; |
||||
for(q=0; q<4; q++) { |
||||
if (q==0) {i=ii-1; j=jj;} |
||||
else if(q==1) {i=ii; j=jj-1;} |
||||
else if(q==2) {i=ii+1; j=jj;} |
||||
else if(q==3) {i=ii; j=jj+1;} |
||||
if ((i<=1)||(j<=1)||(i>t->rows-1)||(j>t->cols-1)) continue; |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,i,j)==INSIDE) { |
||||
dist = min4(FastMarching_solve(i-1,j,i,j-1,f,t), |
||||
FastMarching_solve(i+1,j,i,j-1,f,t), |
||||
FastMarching_solve(i-1,j,i,j+1,f,t), |
||||
FastMarching_solve(i+1,j,i,j+1,f,t)); |
||||
CV_MAT_ELEM(*t,float,i,j) = dist; |
||||
|
||||
for (color=0; color<=2; color++) { |
||||
CvPoint2D32f gradI,gradT,r; |
||||
float Ia=0,Jx=0,Jy=0,s=1.0e-20f,w,dst,lev,dir,sat; |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,i,j+1)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,i,j-1)!=INSIDE) { |
||||
gradT.x=(float)((CV_MAT_ELEM(*t,float,i,j+1)-CV_MAT_ELEM(*t,float,i,j-1)))*0.5f; |
||||
} else { |
||||
gradT.x=(float)((CV_MAT_ELEM(*t,float,i,j+1)-CV_MAT_ELEM(*t,float,i,j))); |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,i,j-1)!=INSIDE) { |
||||
gradT.x=(float)((CV_MAT_ELEM(*t,float,i,j)-CV_MAT_ELEM(*t,float,i,j-1))); |
||||
} else { |
||||
gradT.x=0; |
||||
} |
||||
} |
||||
if (CV_MAT_ELEM(*f,uchar,i+1,j)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,i-1,j)!=INSIDE) { |
||||
gradT.y=(float)((CV_MAT_ELEM(*t,float,i+1,j)-CV_MAT_ELEM(*t,float,i-1,j)))*0.5f; |
||||
} else { |
||||
gradT.y=(float)((CV_MAT_ELEM(*t,float,i+1,j)-CV_MAT_ELEM(*t,float,i,j))); |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,i-1,j)!=INSIDE) { |
||||
gradT.y=(float)((CV_MAT_ELEM(*t,float,i,j)-CV_MAT_ELEM(*t,float,i-1,j))); |
||||
} else { |
||||
gradT.y=0; |
||||
} |
||||
} |
||||
for (k=i-range; k<=i+range; k++) { |
||||
int km=k-1+(k==1),kp=k-1-(k==t->rows-2); |
||||
for (l=j-range; l<=j+range; l++) { |
||||
int lm=l-1+(l==1),lp=l-1-(l==t->cols-2); |
||||
if (k>0&&l>0&&k<t->rows-1&&l<t->cols-1) { |
||||
if ((CV_MAT_ELEM(*f,uchar,k,l)!=INSIDE)&& |
||||
((l-j)*(l-j)+(k-i)*(k-i)<=range*range)) { |
||||
r.y = (float)(i-k); |
||||
r.x = (float)(j-l); |
||||
|
||||
dst = (float)(1./(VectorLength(r)*sqrt((double)VectorLength(r)))); |
||||
lev = (float)(1./(1+fabs(CV_MAT_ELEM(*t,float,k,l)-CV_MAT_ELEM(*t,float,i,j)))); |
||||
|
||||
dir=VectorScalMult(r,gradT); |
||||
if (fabs(dir)<=0.01) dir=0.000001f; |
||||
w = (float)fabs(dst*lev*dir); |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,k,l+1)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,k,l-1)!=INSIDE) { |
||||
gradI.x=(float)((CV_MAT_3COLOR_ELEM(*out,uchar,km,lp+1,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km,lm-1,color)))*2.0f; |
||||
} else { |
||||
gradI.x=(float)((CV_MAT_3COLOR_ELEM(*out,uchar,km,lp+1,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km,lm,color))); |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,k,l-1)!=INSIDE) { |
||||
gradI.x=(float)((CV_MAT_3COLOR_ELEM(*out,uchar,km,lp,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km,lm-1,color))); |
||||
} else { |
||||
gradI.x=0; |
||||
} |
||||
} |
||||
if (CV_MAT_ELEM(*f,uchar,k+1,l)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,k-1,l)!=INSIDE) { |
||||
gradI.y=(float)((CV_MAT_3COLOR_ELEM(*out,uchar,kp+1,lm,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km-1,lm,color)))*2.0f; |
||||
} else { |
||||
gradI.y=(float)((CV_MAT_3COLOR_ELEM(*out,uchar,kp+1,lm,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km,lm,color))); |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,k-1,l)!=INSIDE) { |
||||
gradI.y=(float)((CV_MAT_3COLOR_ELEM(*out,uchar,kp,lm,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km-1,lm,color))); |
||||
} else { |
||||
gradI.y=0; |
||||
} |
||||
} |
||||
Ia += (float)w * (float)(CV_MAT_3COLOR_ELEM(*out,uchar,km,lm,color)); |
||||
Jx -= (float)w * (float)(gradI.x*r.x); |
||||
Jy -= (float)w * (float)(gradI.y*r.y); |
||||
s += w; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
sat = (float)((Ia/s+(Jx+Jy)/(sqrt(Jx*Jx+Jy*Jy)+1.0e-20f)+0.5f)); |
||||
{ |
||||
CV_MAT_3COLOR_ELEM(*out,uchar,i-1,j-1,color) = cv::saturate_cast<uchar>(sat); |
||||
} |
||||
} |
||||
|
||||
CV_MAT_ELEM(*f,uchar,i,j) = BAND; |
||||
Heap->Push(i,j,dist); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} else if (CV_MAT_CN(out->type)==1) { |
||||
|
||||
while (Heap->Pop(&ii,&jj)) { |
||||
|
||||
CV_MAT_ELEM(*f,uchar,ii,jj) = KNOWN; |
||||
for(q=0; q<4; q++) { |
||||
if (q==0) {i=ii-1; j=jj;} |
||||
else if(q==1) {i=ii; j=jj-1;} |
||||
else if(q==2) {i=ii+1; j=jj;} |
||||
else if(q==3) {i=ii; j=jj+1;} |
||||
if ((i<=1)||(j<=1)||(i>t->rows-1)||(j>t->cols-1)) continue; |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,i,j)==INSIDE) { |
||||
dist = min4(FastMarching_solve(i-1,j,i,j-1,f,t), |
||||
FastMarching_solve(i+1,j,i,j-1,f,t), |
||||
FastMarching_solve(i-1,j,i,j+1,f,t), |
||||
FastMarching_solve(i+1,j,i,j+1,f,t)); |
||||
CV_MAT_ELEM(*t,float,i,j) = dist; |
||||
|
||||
for (color=0; color<=0; color++) { |
||||
CvPoint2D32f gradI,gradT,r; |
||||
float Ia=0,Jx=0,Jy=0,s=1.0e-20f,w,dst,lev,dir,sat; |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,i,j+1)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,i,j-1)!=INSIDE) { |
||||
gradT.x=(float)((CV_MAT_ELEM(*t,float,i,j+1)-CV_MAT_ELEM(*t,float,i,j-1)))*0.5f; |
||||
} else { |
||||
gradT.x=(float)((CV_MAT_ELEM(*t,float,i,j+1)-CV_MAT_ELEM(*t,float,i,j))); |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,i,j-1)!=INSIDE) { |
||||
gradT.x=(float)((CV_MAT_ELEM(*t,float,i,j)-CV_MAT_ELEM(*t,float,i,j-1))); |
||||
} else { |
||||
gradT.x=0; |
||||
} |
||||
} |
||||
if (CV_MAT_ELEM(*f,uchar,i+1,j)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,i-1,j)!=INSIDE) { |
||||
gradT.y=(float)((CV_MAT_ELEM(*t,float,i+1,j)-CV_MAT_ELEM(*t,float,i-1,j)))*0.5f; |
||||
} else { |
||||
gradT.y=(float)((CV_MAT_ELEM(*t,float,i+1,j)-CV_MAT_ELEM(*t,float,i,j))); |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,i-1,j)!=INSIDE) { |
||||
gradT.y=(float)((CV_MAT_ELEM(*t,float,i,j)-CV_MAT_ELEM(*t,float,i-1,j))); |
||||
} else { |
||||
gradT.y=0; |
||||
} |
||||
} |
||||
for (k=i-range; k<=i+range; k++) { |
||||
int km=k-1+(k==1),kp=k-1-(k==t->rows-2); |
||||
for (l=j-range; l<=j+range; l++) { |
||||
int lm=l-1+(l==1),lp=l-1-(l==t->cols-2); |
||||
if (k>0&&l>0&&k<t->rows-1&&l<t->cols-1) { |
||||
if ((CV_MAT_ELEM(*f,uchar,k,l)!=INSIDE)&& |
||||
((l-j)*(l-j)+(k-i)*(k-i)<=range*range)) { |
||||
r.y = (float)(i-k); |
||||
r.x = (float)(j-l); |
||||
|
||||
dst = (float)(1./(VectorLength(r)*sqrt(VectorLength(r)))); |
||||
lev = (float)(1./(1+fabs(CV_MAT_ELEM(*t,float,k,l)-CV_MAT_ELEM(*t,float,i,j)))); |
||||
|
||||
dir=VectorScalMult(r,gradT); |
||||
if (fabs(dir)<=0.01) dir=0.000001f; |
||||
w = (float)fabs(dst*lev*dir); |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,k,l+1)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,k,l-1)!=INSIDE) { |
||||
gradI.x=(float)((CV_MAT_ELEM(*out,uchar,km,lp+1)-CV_MAT_ELEM(*out,uchar,km,lm-1)))*2.0f; |
||||
} else { |
||||
gradI.x=(float)((CV_MAT_ELEM(*out,uchar,km,lp+1)-CV_MAT_ELEM(*out,uchar,km,lm))); |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,k,l-1)!=INSIDE) { |
||||
gradI.x=(float)((CV_MAT_ELEM(*out,uchar,km,lp)-CV_MAT_ELEM(*out,uchar,km,lm-1))); |
||||
} else { |
||||
gradI.x=0; |
||||
} |
||||
} |
||||
if (CV_MAT_ELEM(*f,uchar,k+1,l)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,k-1,l)!=INSIDE) { |
||||
gradI.y=(float)((CV_MAT_ELEM(*out,uchar,kp+1,lm)-CV_MAT_ELEM(*out,uchar,km-1,lm)))*2.0f; |
||||
} else { |
||||
gradI.y=(float)((CV_MAT_ELEM(*out,uchar,kp+1,lm)-CV_MAT_ELEM(*out,uchar,km,lm))); |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,k-1,l)!=INSIDE) { |
||||
gradI.y=(float)((CV_MAT_ELEM(*out,uchar,kp,lm)-CV_MAT_ELEM(*out,uchar,km-1,lm))); |
||||
} else { |
||||
gradI.y=0; |
||||
} |
||||
} |
||||
Ia += (float)w * (float)(CV_MAT_ELEM(*out,uchar,km,lm)); |
||||
Jx -= (float)w * (float)(gradI.x*r.x); |
||||
Jy -= (float)w * (float)(gradI.y*r.y); |
||||
s += w; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
sat = (float)((Ia/s+(Jx+Jy)/(sqrt(Jx*Jx+Jy*Jy)+1.0e-20f)+0.5f)); |
||||
{ |
||||
CV_MAT_ELEM(*out,uchar,i-1,j-1) = cv::saturate_cast<uchar>(sat); |
||||
} |
||||
} |
||||
|
||||
CV_MAT_ELEM(*f,uchar,i,j) = BAND; |
||||
Heap->Push(i,j,dist); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
static void |
||||
icvNSInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQueueFloat *Heap) { |
||||
int i = 0, j = 0, ii = 0, jj = 0, k, l, q, color = 0; |
||||
float dist; |
||||
|
||||
if (CV_MAT_CN(out->type)==3) { |
||||
|
||||
while (Heap->Pop(&ii,&jj)) { |
||||
|
||||
CV_MAT_ELEM(*f,uchar,ii,jj) = KNOWN; |
||||
for(q=0; q<4; q++) { |
||||
if (q==0) {i=ii-1; j=jj;} |
||||
else if(q==1) {i=ii; j=jj-1;} |
||||
else if(q==2) {i=ii+1; j=jj;} |
||||
else if(q==3) {i=ii; j=jj+1;} |
||||
if ((i<=1)||(j<=1)||(i>t->rows-1)||(j>t->cols-1)) continue; |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,i,j)==INSIDE) { |
||||
dist = min4(FastMarching_solve(i-1,j,i,j-1,f,t), |
||||
FastMarching_solve(i+1,j,i,j-1,f,t), |
||||
FastMarching_solve(i-1,j,i,j+1,f,t), |
||||
FastMarching_solve(i+1,j,i,j+1,f,t)); |
||||
CV_MAT_ELEM(*t,float,i,j) = dist; |
||||
|
||||
for (color=0; color<=2; color++) { |
||||
CvPoint2D32f gradI,r; |
||||
float Ia=0,s=1.0e-20f,w,dst,dir; |
||||
|
||||
for (k=i-range; k<=i+range; k++) { |
||||
int km=k-1+(k==1),kp=k-1-(k==f->rows-2); |
||||
for (l=j-range; l<=j+range; l++) { |
||||
int lm=l-1+(l==1),lp=l-1-(l==f->cols-2); |
||||
if (k>0&&l>0&&k<f->rows-1&&l<f->cols-1) { |
||||
if ((CV_MAT_ELEM(*f,uchar,k,l)!=INSIDE)&& |
||||
((l-j)*(l-j)+(k-i)*(k-i)<=range*range)) { |
||||
r.y=(float)(k-i); |
||||
r.x=(float)(l-j); |
||||
|
||||
dst = 1/(VectorLength(r)*VectorLength(r)+1); |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,k+1,l)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,k-1,l)!=INSIDE) { |
||||
gradI.x=(float)(abs(CV_MAT_3COLOR_ELEM(*out,uchar,kp+1,lm,color)-CV_MAT_3COLOR_ELEM(*out,uchar,kp,lm,color))+ |
||||
abs(CV_MAT_3COLOR_ELEM(*out,uchar,kp,lm,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km-1,lm,color))); |
||||
} else { |
||||
gradI.x=(float)(abs(CV_MAT_3COLOR_ELEM(*out,uchar,kp+1,lm,color)-CV_MAT_3COLOR_ELEM(*out,uchar,kp,lm,color)))*2.0f; |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,k-1,l)!=INSIDE) { |
||||
gradI.x=(float)(abs(CV_MAT_3COLOR_ELEM(*out,uchar,kp,lm,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km-1,lm,color)))*2.0f; |
||||
} else { |
||||
gradI.x=0; |
||||
} |
||||
} |
||||
if (CV_MAT_ELEM(*f,uchar,k,l+1)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,k,l-1)!=INSIDE) { |
||||
gradI.y=(float)(abs(CV_MAT_3COLOR_ELEM(*out,uchar,km,lp+1,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km,lm,color))+ |
||||
abs(CV_MAT_3COLOR_ELEM(*out,uchar,km,lm,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km,lm-1,color))); |
||||
} else { |
||||
gradI.y=(float)(abs(CV_MAT_3COLOR_ELEM(*out,uchar,km,lp+1,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km,lm,color)))*2.0f; |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,k,l-1)!=INSIDE) { |
||||
gradI.y=(float)(abs(CV_MAT_3COLOR_ELEM(*out,uchar,km,lm,color)-CV_MAT_3COLOR_ELEM(*out,uchar,km,lm-1,color)))*2.0f; |
||||
} else { |
||||
gradI.y=0; |
||||
} |
||||
} |
||||
|
||||
gradI.x=-gradI.x; |
||||
dir=VectorScalMult(r,gradI); |
||||
|
||||
if (fabs(dir)<=0.01) { |
||||
dir=0.000001f; |
||||
} else { |
||||
dir = (float)fabs(VectorScalMult(r,gradI)/sqrt(VectorLength(r)*VectorLength(gradI))); |
||||
} |
||||
w = dst*dir; |
||||
Ia += (float)w * (float)(CV_MAT_3COLOR_ELEM(*out,uchar,km,lm,color)); |
||||
s += w; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
CV_MAT_3COLOR_ELEM(*out,uchar,i-1,j-1,color) = cv::saturate_cast<uchar>((double)Ia/s); |
||||
} |
||||
|
||||
CV_MAT_ELEM(*f,uchar,i,j) = BAND; |
||||
Heap->Push(i,j,dist); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} else if (CV_MAT_CN(out->type)==1) { |
||||
|
||||
while (Heap->Pop(&ii,&jj)) { |
||||
|
||||
CV_MAT_ELEM(*f,uchar,ii,jj) = KNOWN; |
||||
for(q=0; q<4; q++) { |
||||
if (q==0) {i=ii-1; j=jj;} |
||||
else if(q==1) {i=ii; j=jj-1;} |
||||
else if(q==2) {i=ii+1; j=jj;} |
||||
else if(q==3) {i=ii; j=jj+1;} |
||||
if ((i<=1)||(j<=1)||(i>t->rows-1)||(j>t->cols-1)) continue; |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,i,j)==INSIDE) { |
||||
dist = min4(FastMarching_solve(i-1,j,i,j-1,f,t), |
||||
FastMarching_solve(i+1,j,i,j-1,f,t), |
||||
FastMarching_solve(i-1,j,i,j+1,f,t), |
||||
FastMarching_solve(i+1,j,i,j+1,f,t)); |
||||
CV_MAT_ELEM(*t,float,i,j) = dist; |
||||
|
||||
{ |
||||
CvPoint2D32f gradI,r; |
||||
float Ia=0,s=1.0e-20f,w,dst,dir; |
||||
|
||||
for (k=i-range; k<=i+range; k++) { |
||||
int km=k-1+(k==1),kp=k-1-(k==t->rows-2); |
||||
for (l=j-range; l<=j+range; l++) { |
||||
int lm=l-1+(l==1),lp=l-1-(l==t->cols-2); |
||||
if (k>0&&l>0&&k<t->rows-1&&l<t->cols-1) { |
||||
if ((CV_MAT_ELEM(*f,uchar,k,l)!=INSIDE)&& |
||||
((l-j)*(l-j)+(k-i)*(k-i)<=range*range)) { |
||||
r.y=(float)(i-k); |
||||
r.x=(float)(j-l); |
||||
|
||||
dst = 1/(VectorLength(r)*VectorLength(r)+1); |
||||
|
||||
if (CV_MAT_ELEM(*f,uchar,k+1,l)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,k-1,l)!=INSIDE) { |
||||
gradI.x=(float)(abs(CV_MAT_ELEM(*out,uchar,kp+1,lm)-CV_MAT_ELEM(*out,uchar,kp,lm))+ |
||||
abs(CV_MAT_ELEM(*out,uchar,kp,lm)-CV_MAT_ELEM(*out,uchar,km-1,lm))); |
||||
} else { |
||||
gradI.x=(float)(abs(CV_MAT_ELEM(*out,uchar,kp+1,lm)-CV_MAT_ELEM(*out,uchar,kp,lm)))*2.0f; |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,k-1,l)!=INSIDE) { |
||||
gradI.x=(float)(abs(CV_MAT_ELEM(*out,uchar,kp,lm)-CV_MAT_ELEM(*out,uchar,km-1,lm)))*2.0f; |
||||
} else { |
||||
gradI.x=0; |
||||
} |
||||
} |
||||
if (CV_MAT_ELEM(*f,uchar,k,l+1)!=INSIDE) { |
||||
if (CV_MAT_ELEM(*f,uchar,k,l-1)!=INSIDE) { |
||||
gradI.y=(float)(abs(CV_MAT_ELEM(*out,uchar,km,lp+1)-CV_MAT_ELEM(*out,uchar,km,lm))+ |
||||
abs(CV_MAT_ELEM(*out,uchar,km,lm)-CV_MAT_ELEM(*out,uchar,km,lm-1))); |
||||
} else { |
||||
gradI.y=(float)(abs(CV_MAT_ELEM(*out,uchar,km,lp+1)-CV_MAT_ELEM(*out,uchar,km,lm)))*2.0f; |
||||
} |
||||
} else { |
||||
if (CV_MAT_ELEM(*f,uchar,k,l-1)!=INSIDE) { |
||||
gradI.y=(float)(abs(CV_MAT_ELEM(*out,uchar,km,lm)-CV_MAT_ELEM(*out,uchar,km,lm-1)))*2.0f; |
||||
} else { |
||||
gradI.y=0; |
||||
} |
||||
} |
||||
|
||||
gradI.x=-gradI.x; |
||||
dir=VectorScalMult(r,gradI); |
||||
|
||||
if (fabs(dir)<=0.01) { |
||||
dir=0.000001f; |
||||
} else { |
||||
dir = (float)fabs(VectorScalMult(r,gradI)/sqrt(VectorLength(r)*VectorLength(gradI))); |
||||
} |
||||
w = dst*dir; |
||||
Ia += (float)w * (float)(CV_MAT_ELEM(*out,uchar,km,lm)); |
||||
s += w; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
CV_MAT_ELEM(*out,uchar,i-1,j-1) = cv::saturate_cast<uchar>((double)Ia/s); |
||||
} |
||||
|
||||
CV_MAT_ELEM(*f,uchar,i,j) = BAND; |
||||
Heap->Push(i,j,dist); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
#define SET_BORDER1_C1(image,type,value) {\ |
||||
int i,j;\
|
||||
for(j=0; j<image->cols; j++) {\
|
||||
CV_MAT_ELEM(*image,type,0,j) = value;\
|
||||
}\
|
||||
for (i=1; i<image->rows-1; i++) {\
|
||||
CV_MAT_ELEM(*image,type,i,0) = CV_MAT_ELEM(*image,type,i,image->cols-1) = value;\
|
||||
}\
|
||||
for(j=0; j<image->cols; j++) {\
|
||||
CV_MAT_ELEM(*image,type,erows-1,j) = value;\
|
||||
}\
|
||||
} |
||||
|
||||
#define COPY_MASK_BORDER1_C1(src,dst,type) {\ |
||||
int i,j;\
|
||||
for (i=0; i<src->rows; i++) {\
|
||||
for(j=0; j<src->cols; j++) {\
|
||||
if (CV_MAT_ELEM(*src,type,i,j)!=0)\
|
||||
CV_MAT_ELEM(*dst,type,i+1,j+1) = INSIDE;\
|
||||
}\
|
||||
}\
|
||||
} |
||||
|
||||
namespace cv { |
||||
template<> void cv::Ptr<IplConvKernel>::delete_obj() |
||||
{ |
||||
cvReleaseStructuringElement(&obj); |
||||
} |
||||
} |
||||
|
||||
void |
||||
cvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_img, |
||||
double inpaintRange, int flags ) |
||||
{ |
||||
cv::Ptr<CvMat> mask, band, f, t, out; |
||||
cv::Ptr<CvPriorityQueueFloat> Heap, Out; |
||||
cv::Ptr<IplConvKernel> el_cross, el_range; |
||||
|
||||
CvMat input_hdr, mask_hdr, output_hdr; |
||||
CvMat* input_img, *inpaint_mask, *output_img; |
||||
int range=cvRound(inpaintRange); |
||||
int erows, ecols; |
||||
|
||||
input_img = cvGetMat( _input_img, &input_hdr ); |
||||
inpaint_mask = cvGetMat( _inpaint_mask, &mask_hdr ); |
||||
output_img = cvGetMat( _output_img, &output_hdr ); |
||||
|
||||
if( !CV_ARE_SIZES_EQ(input_img,output_img) || !CV_ARE_SIZES_EQ(input_img,inpaint_mask)) |
||||
CV_Error( CV_StsUnmatchedSizes, "All the input and output images must have the same size" ); |
||||
|
||||
if( (CV_MAT_TYPE(input_img->type) != CV_8UC1 && |
||||
CV_MAT_TYPE(input_img->type) != CV_8UC3) || |
||||
!CV_ARE_TYPES_EQ(input_img,output_img) ) |
||||
CV_Error( CV_StsUnsupportedFormat, |
||||
"Only 8-bit 1-channel and 3-channel input/output images are supported" ); |
||||
|
||||
if( CV_MAT_TYPE(inpaint_mask->type) != CV_8UC1 ) |
||||
CV_Error( CV_StsUnsupportedFormat, "The mask must be 8-bit 1-channel image" ); |
||||
|
||||
range = MAX(range,1); |
||||
range = MIN(range,100); |
||||
|
||||
ecols = input_img->cols + 2; |
||||
erows = input_img->rows + 2; |
||||
|
||||
f = cvCreateMat(erows, ecols, CV_8UC1); |
||||
t = cvCreateMat(erows, ecols, CV_32FC1); |
||||
band = cvCreateMat(erows, ecols, CV_8UC1); |
||||
mask = cvCreateMat(erows, ecols, CV_8UC1); |
||||
el_cross = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_CROSS,NULL); |
||||
|
||||
cvCopy( input_img, output_img ); |
||||
cvSet(mask,cvScalar(KNOWN,0,0,0)); |
||||
COPY_MASK_BORDER1_C1(inpaint_mask,mask,uchar); |
||||
SET_BORDER1_C1(mask,uchar,0); |
||||
cvSet(f,cvScalar(KNOWN,0,0,0)); |
||||
cvSet(t,cvScalar(1.0e6f,0,0,0)); |
||||
cvDilate(mask,band,el_cross,1); // image with narrow band
|
||||
Heap=new CvPriorityQueueFloat; |
||||
if (!Heap->Init(band)) |
||||
return; |
||||
cvSub(band,mask,band,NULL); |
||||
SET_BORDER1_C1(band,uchar,0); |
||||
if (!Heap->Add(band)) |
||||
return; |
||||
cvSet(f,cvScalar(BAND,0,0,0),band); |
||||
cvSet(f,cvScalar(INSIDE,0,0,0),mask); |
||||
cvSet(t,cvScalar(0,0,0,0),band); |
||||
|
||||
if( flags == cv::INPAINT_TELEA ) |
||||
{ |
||||
out = cvCreateMat(erows, ecols, CV_8UC1); |
||||
el_range = cvCreateStructuringElementEx(2*range+1,2*range+1, |
||||
range,range,CV_SHAPE_RECT,NULL); |
||||
cvDilate(mask,out,el_range,1); |
||||
cvSub(out,mask,out,NULL); |
||||
Out=new CvPriorityQueueFloat; |
||||
if (!Out->Init(out)) |
||||
return; |
||||
if (!Out->Add(band)) |
||||
return; |
||||
cvSub(out,band,out,NULL); |
||||
SET_BORDER1_C1(out,uchar,0); |
||||
icvCalcFMM(out,t,Out,true); |
||||
icvTeleaInpaintFMM(mask,t,output_img,range,Heap); |
||||
} |
||||
else if (flags == cv::INPAINT_NS) { |
||||
icvNSInpaintFMM(mask,t,output_img,range,Heap); |
||||
} else { |
||||
CV_Error( cv::Error::StsBadArg, "The flags argument must be one of CV_INPAINT_TELEA or CV_INPAINT_NS" ); |
||||
} |
||||
} |
||||
|
||||
void cv::inpaint( InputArray _src, InputArray _mask, OutputArray _dst, |
||||
double inpaintRange, int flags ) |
||||
{ |
||||
Mat src = _src.getMat(), mask = _mask.getMat(); |
||||
_dst.create( src.size(), src.type() ); |
||||
CvMat c_src = src, c_mask = mask, c_dst = _dst.getMat(); |
||||
cvInpaint( &c_src, &c_mask, &c_dst, inpaintRange, flags ); |
||||
} |
@ -0,0 +1,45 @@ |
||||
#include "opencv2/opencv.hpp" |
||||
|
||||
namespace cv { |
||||
namespace optim { |
||||
|
||||
class Solver : public Algorithm /* Algorithm is base OpenCV class */ |
||||
{ |
||||
class Function |
||||
{ |
||||
public: |
||||
virtual ~Function() {} |
||||
virtual double calc(InputArray args) const = 0; |
||||
virtual double calc(InputArgs, OutputArray grad) const = 0; |
||||
}; |
||||
|
||||
// could be reused for all the generic algorithms like downhill simplex.
|
||||
virtual void solve(InputArray x0, OutputArray result) const = 0; |
||||
|
||||
virtual void setTermCriteria(const TermCriteria& criteria) = 0; |
||||
virtual TermCriteria getTermCriteria() = 0; |
||||
|
||||
// more detailed API to be defined later ...
|
||||
}; |
||||
|
||||
class LPSolver : public Solver |
||||
{ |
||||
public: |
||||
virtual void solve(InputArray coeffs, InputArray constraints, OutputArray result) const = 0; |
||||
// ...
|
||||
}; |
||||
|
||||
Ptr<LPSolver> createLPSimplexSolver(); |
||||
|
||||
}} |
||||
|
||||
/*===============
|
||||
Hill climbing solver is more generic one:*/ |
||||
/*
|
||||
class DownhillSolver : public Solver |
||||
{ |
||||
public: |
||||
// various setters and getters, if needed
|
||||
}; |
||||
|
||||
Ptr<DownhillSolver> createDownhillSolver(const Ptr<Solver::Function>& func);*/ |
@ -1,44 +0,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 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 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 "precomp.hpp" |
||||
|
||||
/* End of file. */ |
@ -1,53 +0,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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, 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_PRECOMP_H__ |
||||
#define __OPENCV_PRECOMP_H__ |
||||
|
||||
#include "opencv2/photo.hpp" |
||||
#include "opencv2/core/private.hpp" |
||||
|
||||
#ifdef HAVE_TEGRA_OPTIMIZATION |
||||
#include "opencv2/photo/photo_tegra.hpp" |
||||
#endif |
||||
|
||||
#endif |
Loading…
Reference in new issue