diff --git a/modules/xphoto/src/annf.hpp b/modules/xphoto/src/annf.hpp index b89179b45..38775d07e 100644 --- a/modules/xphoto/src/annf.hpp +++ b/modules/xphoto/src/annf.hpp @@ -77,7 +77,8 @@ private: }; const int height, width; - const int leafNumber; + const int leafNumber; // maximum number of point per leaf + const int zeroThresh; // radius of prohibited shifts std::vector > data; std::vector idx; @@ -89,7 +90,7 @@ private: public: void updateDist(const int leaf, const int &idx0, int &bestIdx, double &dist); - KDTree(const cv::Mat &data, const int leafNumber = 8); + KDTree(const cv::Mat &data, const int leafNumber = 8, const int zeroThresh = 16); ~KDTree(){}; }; @@ -111,11 +112,13 @@ getMaxSpreadN(const int _left, const int _right) const } template KDTree :: -KDTree(const cv::Mat &img, const int _leafNumber) +KDTree(const cv::Mat &img, const int _leafNumber, const int _zeroThresh) : height(img.rows), width(img.cols), - leafNumber(_leafNumber) + leafNumber(_leafNumber), zeroThresh(_zeroThresh) /////////////////////////////////////////////////// { + CV_Assert( img.isContinuous() ); + std::copy( (cv::Vec *) img.data, (cv::Vec *) img.data + img.total(), std::back_inserter(data) ); @@ -162,9 +165,11 @@ updateDist(const int leaf, const int &idx0, int &bestIdx, double &dist) int y = idx0/width, ny = idx[k]/width; int x = idx0%width, nx = idx[k]%width; - if (abs(ny - y) + abs(nx - x) < 32) + if (abs(ny - y) < zeroThresh && + abs(nx - x) < zeroThresh) continue; - if (nx == width - 1 || ny == height - 1) + if (nx > width - 1 || nx < 1 || + ny > height - 1 || ny > 1 ) continue; double ndist = norm2(data[idx0], data[idx[k]]); @@ -199,7 +204,7 @@ static void dominantTransforms(const cv::Mat &img, std::vector &tr cv::Mat whs; // Walsh-Hadamard series cv::merge(channels, whs); - KDTree kdTree(whs); + KDTree kdTree(whs, 16, 32); std::vector annf( whs.total(), 0 ); /** Propagation-assisted kd-tree search **/ @@ -224,14 +229,14 @@ static void dominantTransforms(const cv::Mat &img, std::vector &tr /** Local maxima extraction **/ - cv::Mat_ annfHist(2*whs.rows, 2*whs.cols, 0.0), - _annfHist(2*whs.rows, 2*whs.cols, 0.0); + cv::Mat_ annfHist(2*whs.rows - 1, 2*whs.cols - 1, 0.0), + _annfHist(2*whs.rows - 1, 2*whs.cols - 1, 0.0); for (size_t i = 0; i < annf.size(); ++i) - ++annfHist( (annf[i] - int(i))/whs.cols + whs.rows, - (annf[i] - int(i))%whs.cols + whs.cols ); + ++annfHist( (annf[i] - int(i))/whs.cols + whs.rows - 1, + (annf[i] - int(i))%whs.cols + whs.cols - 1 ); cv::GaussianBlur( annfHist, annfHist, - cv::Size(9, 9), 1.41, 0.0, cv::BORDER_CONSTANT); + cv::Size(0, 0), std::sqrt(2.0), 0.0, cv::BORDER_CONSTANT); cv::dilate( annfHist, _annfHist, cv::Matx::ones() ); @@ -247,8 +252,8 @@ static void dominantTransforms(const cv::Mat &img, std::vector &tr if ( pAnnfHist[j] != 0 && pAnnfHist[j] == _pAnnfHist[j] ) { amount.push_back( std::make_pair(pAnnfHist[j], t++) ); - shiftM.push_back(cv::Point2i(j - whs.cols, - i - whs.rows)); + shiftM.push_back( cv::Point2i(j - whs.cols + 1, + i - whs.rows + 1) ); } } diff --git a/modules/xphoto/src/inpainting.cpp b/modules/xphoto/src/inpainting.cpp index 5bb882155..f1619d989 100644 --- a/modules/xphoto/src/inpainting.cpp +++ b/modules/xphoto/src/inpainting.cpp @@ -59,7 +59,6 @@ #include "opencv2/highgui.hpp" - namespace xphotoInternal { # include "photomontage.hpp" diff --git a/modules/xphoto/src/photomontage.hpp b/modules/xphoto/src/photomontage.hpp index 0777e7ca5..504e4e14e 100644 --- a/modules/xphoto/src/photomontage.hpp +++ b/modules/xphoto/src/photomontage.hpp @@ -45,6 +45,7 @@ #include "gcgraph.hpp" #define GCInfinity 10*1000*1000*1000.0 +#define eps 0.02 template static int min_idx(std::vector vec) { @@ -163,8 +164,8 @@ singleExpansion(const int alpha) for (int j = 0; j < width; ++j) graph.addTermWeights( graph.addVtx(), - maskAlphaRow[j] ? 0 : GCInfinity, - masks[ labelRow[j] ].template at(i, j) ? 0 : GCInfinity ); + maskAlphaRow[j] ? 0 : GCInfinity, + masks[ labelRow[j] ].template at(i, j) ? 0 : GCInfinity ); } /** Neighbor links **/ @@ -199,7 +200,8 @@ singleExpansion(const int alpha) int *outRow = (int *) labelings[alpha].template ptr (i); for (int j = 0; j < width; ++j) - outRow[j] = graph.inSourceSegment(i*width + j) ? inRow[j] : alpha; + outRow[j] = graph.inSourceSegment(i*width + j) + ? inRow[j] : alpha; } return result; @@ -218,7 +220,7 @@ gradientDescent() int minIndex = min_idx(distances); double minValue = distances[minIndex]; - if (minValue < 0.98*optValue) + if (minValue < (1.00 - eps)*optValue) optValue = distances[num = minIndex]; if (num == -1)