Commit bc5d9c51 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #92 from Bellaktris/inpainting

Inpainting
parents f07e304d 63c308a9
......@@ -6,6 +6,8 @@
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc/types_c.h"
#include <ctime>
#include <iostream>
const char* keys =
{
......@@ -54,9 +56,15 @@ int main( int argc, const char** argv )
printf( "Cannot read image file: %s\n", maskFilename.c_str() );
return -1;
}
cv::threshold(mask, mask, 128, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
cv::Mat res(src.size(), src.type());
int time = clock();
cv::xphoto::inpaint( src, mask, res, cv::xphoto::INPAINT_SHIFTMAP );
std::cout << "time = " << (clock() - time)
/ double(CLOCKS_PER_SEC) << std::endl;
cv::cvtColor(res, res, CV_Lab2RGB);
if ( outFilename == "" )
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// * Redistribution'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 __ADVANCED_TYPES_HPP__
#define __ADVANCED_TYPES_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
/********************* Functions *********************/
namespace cv
{
template <typename _Tp, typename _Tp2> static inline
cv::Size_<_Tp> operator * (const _Tp2 x, const cv::Size_<_Tp> &sz)
{
return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(x*sz.width), cv::saturate_cast<_Tp>(x*sz.height));
}
template <typename _Tp, typename _Tp2> static inline
cv::Size_<_Tp> operator / (const cv::Size_<_Tp> &sz, const _Tp2 x)
{
return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(sz.width/x), cv::saturate_cast<_Tp>(sz.height/x));
}
} // cv
#endif
#endif /* __ADVANCED_TYPES_HPP__ */
\ No newline at end of file
......@@ -40,6 +40,16 @@
#ifndef __ANNF_HPP__
#define __ANNF_HPP__
#include <vector>
#include <stack>
#include <limits>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <fstream>
#include <time.h>
#include <functional>
#include "norm2.hpp"
#include "whs.hpp"
......@@ -95,11 +105,12 @@ public:
};
template <typename Tp, int cn> int KDTree <Tp, cn>::
getMaxSpreadN(const int _left, const int _right) const
getMaxSpreadN(const int left, const int right) const
{
cv::Vec<Tp, cn> maxValue = data[ idx[_left] ],
minValue = data[ idx[_left] ];
for (int i = _left + 1; i < _right; i += cn)
cv::Vec<Tp, cn> maxValue = data[ idx[left] ],
minValue = data[ idx[left] ];
for (int i = left + 1; i < right; ++i)
for (int j = 0; j < cn; ++j)
{
minValue[j] = std::min( minValue[j], data[idx[i]][j] );
......@@ -143,6 +154,7 @@ KDTree(const cv::Mat &img, const int _leafNumber, const int _zeroThresh)
}
int nth = _left + (_right - _left)/2;
int dimIdx = getMaxSpreadN(_left, _right);
KDTreeComparator comp( this, dimIdx );
......@@ -168,8 +180,8 @@ updateDist(const int leaf, const int &idx0, int &bestIdx, double &dist)
if (abs(ny - y) < zeroThresh &&
abs(nx - x) < zeroThresh)
continue;
if (nx > width - 1 || nx < 1 ||
ny > height - 1 || ny > 1 )
if (nx >= width - 1 || nx < 1 ||
ny >= height - 1 || ny < 1 )
continue;
double ndist = norm2(data[idx0], data[idx[k]]);
......@@ -184,9 +196,12 @@ updateDist(const int leaf, const int &idx0, int &bestIdx, double &dist)
/************************** ANNF search **************************/
static void dominantTransforms(const cv::Mat &img, std::vector <cv::Matx33f> &transforms,
static void dominantTransforms(const cv::Mat &img, std::vector <cv::Point2i> &transforms,
const int nTransform, const int psize)
{
const int zeroThresh = 2*psize;
const int leafNum = 64;
/** Walsh-Hadamard Transformation **/
std::vector <cv::Mat> channels;
......@@ -204,7 +219,7 @@ static void dominantTransforms(const cv::Mat &img, std::vector <cv::Matx33f> &tr
cv::Mat whs; // Walsh-Hadamard series
cv::merge(channels, whs);
KDTree <float, 24> kdTree(whs, 16, 32);
KDTree <float, 24> kdTree(whs, leafNum, zeroThresh);
std::vector <int> annf( whs.total(), 0 );
/** Propagation-assisted kd-tree search **/
......@@ -217,13 +232,13 @@ static void dominantTransforms(const cv::Mat &img, std::vector <cv::Matx33f> &tr
int dy[] = {0, 1, 0}, dx[] = {0, 0, 1};
for (int k = 0; k < int( sizeof(dy)/sizeof(int) ); ++k)
if (i - dy[k] >= 0 && j - dx[k] >= 0)
if ( i - dy[k] >= 0 && j - dx[k] >= 0 )
{
int neighbor = (i - dy[k])*whs.cols + (j - dx[k]);
int leafIdx = k == 0 ? neighbor :
annf[neighbor] + dy[k]*whs.cols + dx[k];
int leafIdx = (dx[k] == 0 && dy[k] == 0)
? neighbor : annf[neighbor] + dy[k]*whs.cols + dx[k];
kdTree.updateDist(leafIdx, current,
annf[i*whs.cols + j], dist);
annf[i*whs.cols + j], dist);
}
}
......@@ -232,8 +247,8 @@ static void dominantTransforms(const cv::Mat &img, std::vector <cv::Matx33f> &tr
cv::Mat_<double> 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 - 1,
(annf[i] - int(i))%whs.cols + whs.cols - 1 );
++annfHist( annf[i]/whs.cols - int(i)/whs.cols + whs.rows - 1,
annf[i]%whs.cols - int(i)%whs.cols + whs.cols - 1 );
cv::GaussianBlur( annfHist, annfHist,
cv::Size(0, 0), std::sqrt(2.0), 0.0, cv::BORDER_CONSTANT);
......@@ -264,9 +279,7 @@ static void dominantTransforms(const cv::Mat &img, std::vector <cv::Matx33f> &tr
for (int i = 0; i < nTransform; ++i)
{
int idx = amount[i].second;
transforms[i] = cv::Matx33f(1, 0, float(shiftM[idx].x),
0, 1, float(shiftM[idx].y),
0, 0, 1 );
transforms[i] = cv::Point2i( shiftM[idx].x, shiftM[idx].y );
}
}
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// * Redistribution'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 __BLENDING_HPP__
#define __BLENDING_HPP__
#endif /* __BLENDING_HPP__ */
\ No newline at end of file
......@@ -254,7 +254,7 @@ TWeight GCGraph<TWeight>::maxFlow()
minWeight = MIN(minWeight, weight);
CV_Assert( minWeight > 0 );
}
weight = fabs(v->weight);
weight = abs( TWeight(v->weight) );
minWeight = MIN(minWeight, weight);
CV_Assert( minWeight > 0 );
}
......
This diff is collapsed.
......@@ -40,52 +40,34 @@
#ifndef __NORM2_HPP__
#define __NORM2_HPP__
/************************ General template *************************/
template<bool B, class T = void> struct iftype {};
template<class T> struct iftype<true, T> { typedef T type; }; // enable_if
template <typename Tp> static inline Tp sqr(Tp x) { return x*x; }
template<class T, T v> struct int_const { // integral_constant
static const T value = v;
typedef T value_type;
typedef int_const type;
operator value_type() const { return value; }
value_type operator()() const { return value; }
};
template <typename Tp, int cn> static inline Tp sqr( cv::Vec<Tp, cn> x) { return x.dot(x); }
typedef int_const<bool,true> ttype; // true_type
typedef int_const<bool,false> ftype; // false_type
template <typename Tp> static inline Tp norm2(const Tp &a, const Tp &b) { return sqr(a - b); }
template <class T, class U> struct same_as : ftype {};
template <class T> struct same_as<T, T> : ttype {}; // is_same
template <typename Tp, int cn> static inline
Tp norm2(const cv::Vec <Tp, cn> &a, const cv::Vec<Tp, cn> &b) { return sqr(a - b); }
template <typename _Tp> struct is_norm2_type :
int_const<bool, !same_as<_Tp, char>::value
&& !same_as<_Tp, uchar>::value
&& !same_as<_Tp, ushort>::value
&& !same_as<_Tp, uint>::value>{};
template <typename _Tp, int cn> static inline typename iftype< is_norm2_type<_Tp>::value, _Tp >::
type norm2(cv::Vec<_Tp, cn> a, cv::Vec<_Tp, cn> b) { return (a - b).dot(a - b); }
/******************* uchar, char, ushort, uint *********************/
static inline int norm2(const uchar &a, const uchar &b) { return sqr(int(a) - int(b)); }
template <int cn> static inline
int norm2(const cv::Vec <uchar, cn> &a, const cv::Vec<uchar, cn> &b)
{
return sqr( cv::Vec<int, cn>(a) - cv::Vec<int, cn>(b) );
}
static inline int norm2(const char &a, const char &b) { return sqr(int(a) - int(b)); }
template <int cn> static inline
int norm2(const cv::Vec <char, cn> &a, const cv::Vec<char, cn> &b)
{
return sqr( cv::Vec<int, cn>(a) - cv::Vec<int, cn>(b) );
}
static inline short norm2(const ushort &a, const ushort &b) { return sqr <short>(short(a) - short(b)); }
template <int cn> static inline
short norm2(const cv::Vec <ushort, cn> &a, const cv::Vec<ushort, cn> &b)
{
return sqr( cv::Vec<short, cn>(a) - cv::Vec<short, cn>(b) );
}
static inline int norm2(const uint &a, const uint &b) { return sqr(int(a) - int(b)); }
template <int cn> static inline
int norm2(const cv::Vec <uint, cn> &a, const cv::Vec<uint, cn> &b)
{
return sqr( cv::Vec<int, cn>(a) - cv::Vec<int, cn>(b) );
}
template <typename _Tp> static inline typename iftype< is_norm2_type<_Tp>::value, _Tp >::
type norm2(const _Tp &a, const _Tp &b) { return (a - b)*(a - b); }
#endif /* __NORM2_HPP__ */
\ No newline at end of file
This diff is collapsed.
......@@ -137,8 +137,11 @@ static void rgb2whs(const cv::Mat &src, cv::Mat &dst, const int nProjections, co
nextProjection(projections, snake_idx[i - 1],
snake_idx[i], npsize);
int pad = 0;
cv::merge(projections, img);
img(cv::Rect(npsize, npsize, src.cols, src.rows)).copyTo(dst);
img(cv::Rect(npsize + pad, npsize + pad, src.cols - pad,
src.rows - pad)).copyTo(dst);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment