From f2afe64521223e601ec26a89434a993d27a158ac Mon Sep 17 00:00:00 2001 From: Alex Leontiev Date: Mon, 17 Jun 2013 18:16:30 +0300 Subject: [PATCH] Starting implement simplex algorithm. --- modules/optim/CMakeLists.txt | 4 +- modules/optim/src/arrays.hpp | 161 ---- modules/optim/src/denoising.cpp | 242 ------ .../src/fast_nlmeans_denoising_invoker.hpp | 334 ------- ...fast_nlmeans_denoising_invoker_commons.hpp | 115 --- .../fast_nlmeans_multi_denoising_invoker.hpp | 383 -------- modules/optim/src/inpaint.cpp | 817 ------------------ modules/optim/src/lpsolver.cpp | 45 + modules/optim/src/precomp.cpp | 44 - modules/optim/src/precomp.hpp | 53 -- 10 files changed, 47 insertions(+), 2151 deletions(-) delete mode 100644 modules/optim/src/arrays.hpp delete mode 100644 modules/optim/src/denoising.cpp delete mode 100644 modules/optim/src/fast_nlmeans_denoising_invoker.hpp delete mode 100644 modules/optim/src/fast_nlmeans_denoising_invoker_commons.hpp delete mode 100644 modules/optim/src/fast_nlmeans_multi_denoising_invoker.hpp delete mode 100644 modules/optim/src/inpaint.cpp create mode 100644 modules/optim/src/lpsolver.cpp delete mode 100644 modules/optim/src/precomp.cpp delete mode 100644 modules/optim/src/precomp.hpp diff --git a/modules/optim/CMakeLists.txt b/modules/optim/CMakeLists.txt index 08a72ea92..b5de99de0 100644 --- a/modules/optim/CMakeLists.txt +++ b/modules/optim/CMakeLists.txt @@ -1,2 +1,2 @@ -set(the_description "Computational Photography") -ocv_define_module(photo opencv_imgproc) +set(the_description "Generic optimization") +ocv_define_module(optim) diff --git a/modules/optim/src/arrays.hpp b/modules/optim/src/arrays.hpp deleted file mode 100644 index ae01e9af8..000000000 --- a/modules/optim/src/arrays.hpp +++ /dev/null @@ -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 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 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 operator [] (int i) { - Array2d 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 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 operator [] (int i) { - Array3d 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 - - diff --git a/modules/optim/src/denoising.cpp b/modules/optim/src/denoising.cpp deleted file mode 100644 index 4d3e6c8f9..000000000 --- a/modules/optim/src/denoising.cpp +++ /dev/null @@ -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( - src, dst, templateWindowSize, searchWindowSize, h)); - break; - case CV_8UC2: - parallel_for(cv::BlockedRange(0, src.rows), - FastNlMeansDenoisingInvoker( - src, dst, templateWindowSize, searchWindowSize, h)); - break; - case CV_8UC3: - parallel_for(cv::BlockedRange(0, src.rows), - FastNlMeansDenoisingInvoker( - 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& 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 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( - srcImgs, imgToDenoiseIndex, temporalWindowSize, - dst, templateWindowSize, searchWindowSize, h)); - break; - case CV_8UC2: - parallel_for(cv::BlockedRange(0, srcImgs[0].rows), - FastNlMeansMultiDenoisingInvoker( - srcImgs, imgToDenoiseIndex, temporalWindowSize, - dst, templateWindowSize, searchWindowSize, h)); - break; - case CV_8UC3: - parallel_for(cv::BlockedRange(0, srcImgs[0].rows), - FastNlMeansMultiDenoisingInvoker( - 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 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 src_lab(src_imgs_size); - std::vector l(src_imgs_size); - std::vector 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); -} - - diff --git a/modules/optim/src/fast_nlmeans_denoising_invoker.hpp b/modules/optim/src/fast_nlmeans_denoising_invoker.hpp deleted file mode 100644 index 232dba88d..000000000 --- a/modules/optim/src/fast_nlmeans_denoising_invoker.hpp +++ /dev/null @@ -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 - -#include "fast_nlmeans_denoising_invoker_commons.hpp" -#include "arrays.hpp" - -using namespace cv; - -template -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 almost_dist2weight_; - - void calcDistSumsForFirstElementInRow( - int i, - Array2d& dist_sums, - Array3d& col_dist_sums, - Array3d& up_col_dist_sums) const; - - void calcDistSumsForElementInFirstRow( - int i, - int j, - int first_col_num, - Array2d& dist_sums, - Array3d& col_dist_sums, - Array3d& up_col_dist_sums) const; -}; - -inline int getNearestPowerOf2(int value) -{ - int p = 0; - while( 1 << p < value) ++p; - return p; -} - -template -FastNlMeansDenoisingInvoker::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::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 -void FastNlMeansDenoisingInvoker::operator() (const BlockedRange& range) const { - int row_from = range.begin(); - int row_to = range.end() - 1; - - Array2d dist_sums(search_window_size_, search_window_size_); - - // for lazy calc optimization - Array3d col_dist_sums(template_window_size_, search_window_size_, search_window_size_); - - int first_col_num = -1; - Array3d 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(ay - template_window_half_size_ - 1, ax); - T a_down = extended_src_.at(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(start_by - template_window_half_size_ - 1 + y); - - const T* b_down_ptr = - extended_src_.ptr(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(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(i,j) = saturateCastFromArray(estimation); - } - } -} - -template -inline void FastNlMeansDenoisingInvoker::calcDistSumsForFirstElementInRow( - int i, - Array2d& dist_sums, - Array3d& col_dist_sums, - Array3d& 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(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 -inline void FastNlMeansDenoisingInvoker::calcDistSumsForElementInFirstRow( - int i, - int j, - int first_col_num, - Array2d& dist_sums, - Array3d& col_dist_sums, - Array3d& 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(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 diff --git a/modules/optim/src/fast_nlmeans_denoising_invoker_commons.hpp b/modules/optim/src/fast_nlmeans_denoising_invoker_commons.hpp deleted file mode 100644 index 978f3170c..000000000 --- a/modules/optim/src/fast_nlmeans_denoising_invoker_commons.hpp +++ /dev/null @@ -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 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 static inline int calcDist(const Mat& m, int i1, int j1, int i2, int j2) { - const T a = m.at(i1, j1); - const T b = m.at(i2, j2); - return calcDist(a,b); -} - -template 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 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 static inline T saturateCastFromArray(int* estimation); - -template <> inline uchar saturateCastFromArray(int* estimation) { - return saturate_cast(estimation[0]); -} - -template <> inline Vec2b saturateCastFromArray(int* estimation) { - Vec2b res; - res[0] = saturate_cast(estimation[0]); - res[1] = saturate_cast(estimation[1]); - return res; -} - -template <> inline Vec3b saturateCastFromArray(int* estimation) { - Vec3b res; - res[0] = saturate_cast(estimation[0]); - res[1] = saturate_cast(estimation[1]); - res[2] = saturate_cast(estimation[2]); - return res; -} - -#endif diff --git a/modules/optim/src/fast_nlmeans_multi_denoising_invoker.hpp b/modules/optim/src/fast_nlmeans_multi_denoising_invoker.hpp deleted file mode 100644 index ee7d3bc7f..000000000 --- a/modules/optim/src/fast_nlmeans_multi_denoising_invoker.hpp +++ /dev/null @@ -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 - -#include "fast_nlmeans_denoising_invoker_commons.hpp" -#include "arrays.hpp" - -using namespace cv; - -template -struct FastNlMeansMultiDenoisingInvoker { - public: - FastNlMeansMultiDenoisingInvoker( - const std::vector& 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 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 almost_dist2weight; - - void calcDistSumsForFirstElementInRow( - int i, - Array3d& dist_sums, - Array4d& col_dist_sums, - Array4d& up_col_dist_sums) const; - - void calcDistSumsForElementInFirstRow( - int i, - int j, - int first_col_num, - Array3d& dist_sums, - Array4d& col_dist_sums, - Array4d& up_col_dist_sums) const; -}; - -template -FastNlMeansMultiDenoisingInvoker::FastNlMeansMultiDenoisingInvoker( - const std::vector& 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::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 -void FastNlMeansMultiDenoisingInvoker::operator() (const BlockedRange& range) const { - int row_from = range.begin(); - int row_to = range.end() - 1; - - Array3d dist_sums(temporal_window_size_, search_window_size_, search_window_size_); - - // for lazy calc optimization - Array4d col_dist_sums( - template_window_size_, temporal_window_size_, search_window_size_, search_window_size_); - - int first_col_num = -1; - - Array4d 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(ay - template_window_half_size_ - 1, ax); - T a_down = main_extended_src_.at(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 cur_dist_sums = dist_sums[d]; - Array2d cur_col_dist_sums = col_dist_sums[first_col_num][d]; - Array2d 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(start_by - template_window_half_size_ - 1 + y); - const T* b_down_ptr = - cur_extended_src.ptr(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(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(i,j) = saturateCastFromArray(estimation); - - } - } -} - -template -inline void FastNlMeansMultiDenoisingInvoker::calcDistSumsForFirstElementInRow( - int i, - Array3d& dist_sums, - Array4d& col_dist_sums, - Array4d& 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( - main_extended_src_.at( - border_size_ + i + ty, border_size_ + j + tx), - cur_extended_src.at( - 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 -inline void FastNlMeansMultiDenoisingInvoker::calcDistSumsForElementInFirstRow( - int i, - int j, - int first_col_num, - Array3d& dist_sums, - Array4d& col_dist_sums, - Array4d& 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( - main_extended_src_.at(ay + ty, ax), - cur_extended_src.at(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 diff --git a/modules/optim/src/inpaint.cpp b/modules/optim/src/inpaint.cpp deleted file mode 100644 index ec91e3c1b..000000000 --- a/modules/optim/src/inpaint.cpp +++ /dev/null @@ -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; irows; i++) { - for (j=0; jcols; 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; irows; i++) { - for(j=0; jcols; 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&&krows-1&&lcols-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(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&&krows-1&&lcols-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(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&&krows-1&&lcols-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((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&&krows-1&&lcols-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((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; jcols; j++) {\ - CV_MAT_ELEM(*image,type,0,j) = value;\ - }\ - for (i=1; irows-1; i++) {\ - CV_MAT_ELEM(*image,type,i,0) = CV_MAT_ELEM(*image,type,i,image->cols-1) = value;\ - }\ - for(j=0; jcols; j++) {\ - CV_MAT_ELEM(*image,type,erows-1,j) = value;\ - }\ - } - -#define COPY_MASK_BORDER1_C1(src,dst,type) {\ - int i,j;\ - for (i=0; irows; i++) {\ - for(j=0; jcols; 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::delete_obj() -{ - cvReleaseStructuringElement(&obj); -} -} - -void -cvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_img, - double inpaintRange, int flags ) -{ - cv::Ptr mask, band, f, t, out; - cv::Ptr Heap, Out; - cv::Ptr 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 ); -} diff --git a/modules/optim/src/lpsolver.cpp b/modules/optim/src/lpsolver.cpp new file mode 100644 index 000000000..7fb62e01f --- /dev/null +++ b/modules/optim/src/lpsolver.cpp @@ -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 createLPSimplexSolver(); + +}} + +/*=============== +Hill climbing solver is more generic one:*/ +/* +class DownhillSolver : public Solver +{ +public: + // various setters and getters, if needed +}; + +Ptr createDownhillSolver(const Ptr& func);*/ diff --git a/modules/optim/src/precomp.cpp b/modules/optim/src/precomp.cpp deleted file mode 100644 index 3e0ec42de..000000000 --- a/modules/optim/src/precomp.cpp +++ /dev/null @@ -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. */ diff --git a/modules/optim/src/precomp.hpp b/modules/optim/src/precomp.hpp deleted file mode 100644 index 60cc99b19..000000000 --- a/modules/optim/src/precomp.hpp +++ /dev/null @@ -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