18 #ifndef PIC_ALGORITHMS_POISSON_IMAGE_EDITING_HPP 19 #define PIC_ALGORITHMS_POISSON_IMAGE_EDITING_HPP 23 #include "../base.hpp" 24 #include "../image.hpp" 25 #include "../util/std_util.hpp" 26 #include "../filtering/filter_laplacian.hpp" 28 #ifndef PIC_DISABLE_EIGEN 30 #ifndef PIC_EIGEN_NOT_BUNDLED 31 #include "../externals/Eigen/Sparse" 32 #include "../externals/Eigen/src/SparseCore/SparseMatrix.h" 34 #include <Eigen/Sparse> 35 #include <Eigen/src/SparseCore/SparseMatrix.h> 42 #ifndef PIC_DISABLE_EIGEN 53 if((source == NULL) || (target == NULL) || (mask == NULL)) {
59 ret = target->
clone();
62 int width = target->
width;
63 int height = target->
height;
66 printf(
"Init matrix...");
71 std::vector< Eigen::Triplet< double > > tL;
74 int *index =
new int[width * height];
76 for(
int i = 0; i < height; i++) {
79 for(
int j = 0; j < width; j++) {
93 for(
int i = 0; i < height; i++) {
96 for(
int j = 0; j < width; j++) {
100 if((j + 1) < (width - 1)) {
102 tL.push_back(Eigen::Triplet< double > (count, index[indI + 1], -1.0));
108 tL.push_back(Eigen::Triplet< double > (count, index[indI - 1], -1.0));
112 if((i + 1) < (height - 1)) {
113 if(mask[indI + width]) {
114 tL.push_back(Eigen::Triplet< double > (count, index[indI + width], -1.0));
119 if(mask[indI - width]) {
120 tL.push_back(Eigen::Triplet< double > (count, index[indI - width], -1.0));
124 tL.push_back(Eigen::Triplet< double > (count, count , 4.0));
132 Eigen::SparseMatrix<double> A = Eigen::SparseMatrix<double>(tot, tot);
133 A.setFromTriplets(tL.begin(), tL.end());
140 Eigen::SimplicialCholesky<Eigen::SparseMatrix<double> > solver(A);
142 for(
int k=0; k< target->
channels; k++) {
144 Eigen::VectorXd b, x;
145 b = Eigen::VectorXd::Zero(tot);
149 for(
int i = 0; i < height; i++) {
150 int tmpI = i * width;
152 for(
int j = 0; j < width; j++) {
153 int indI = (tmpI + j);
157 b[count] = -(*lap_source)(j, i)[k];
159 if((j + 1) < (width - 1)) {
160 if(!mask[indI + 1]) {
161 b[count] += (*target)(j + 1, i)[k];
166 if(!mask[indI - 1]) {
167 b[count] += (*target)(j - 1, i)[k];
171 if((i + 1) < (height - 1)) {
172 if(!mask[indI + width]) {
173 b[count] += (*target)(j, i + 1)[k];
178 if(!mask[indI - width]) {
179 b[count] += (*target)(j, i - 1)[k];
190 if(solver.info() != Eigen::Success) {
192 printf(
"SOLVER FAILED!\n");
199 printf(
"SOLVER SUCCESS!\n");
203 for(
int i = 0; i < height; i++) {
204 int tmpI = i * width;
206 for(
int j = 0; j < width; j++) {
207 int indI = (tmpI + j);
210 float val = float(x(count));
211 (*ret)(j, i)[k] = val > 0.0f ? val : 0.0f;
int channels
Definition: image.hpp:80
T * delete_s(T *data)
delete_s
Definition: std_util.hpp:123
T * delete_vec_s(T *data)
delete_vec_s
Definition: std_util.hpp:138
static Image * execute(Image *imgIn, Image *imgOut)
execute
Definition: filter_laplacian.hpp:79
#define PIC_INLINE
Definition: base.hpp:33
The Image class stores an image as buffer of float.
Definition: image.hpp:60
Image * clone() const
Clone creates a deep copy of the calling instance.
PIC_INLINE Image * computePoissonImageEditing(Image *source, Image *target, bool *mask, Image *ret=NULL)
computePoissonImageEditing
Definition: poisson_image_editing.hpp:51
Definition: bilateral_separation.hpp:25
int width
Definition: image.hpp:80
int height
Definition: image.hpp:80