@@ -93,7 +93,53 @@ void computeWeightedGradientVectorField(cv::InputArray background,
93
93
cv::addWeighted (vyf, weightForeground, vyb, 1 .f - weightForeground, 0 , vy);
94
94
}
95
95
96
-
96
+ void seamlessCloneNaive (cv::InputArray background,
97
+ cv::InputArray foreground,
98
+ cv::InputArray foregroundMask,
99
+ int offsetX,
100
+ int offsetY,
101
+ cv::OutputArray destination,
102
+ CloneType type)
103
+ {
104
+ // Copy original background as we only solve for the overlapping area of the translated foreground mask.
105
+ background.getMat ().copyTo (destination);
106
+
107
+ // Find overlapping region. We will only perform on this region
108
+ cv::Rect rbg, rfg;
109
+ if (!findOverlap (background, foreground, offsetX, offsetY, rbg, rfg))
110
+ return ;
111
+
112
+ // Compute the guidance vector field
113
+ cv::Mat vx, vy;
114
+ computeWeightedGradientVectorField (background.getMat ()(rbg),foreground.getMat ()(rfg), vx, vy, 1 .f );
115
+
116
+
117
+ // For the Poisson equation the divergence of the guidance field is necessary.
118
+ cv::Mat vxx, vyy;
119
+ cv::Mat kernelx = (cv::Mat_<float >(1 , 3 ) << -0.5 , 0 , 0.5 );
120
+ cv::Mat kernely = (cv::Mat_<float >(3 , 1 ) << -0.5 , 0 , 0.5 );
121
+ cv::filter2D (vx, vxx, CV_32F, kernelx);
122
+ cv::filter2D (vy, vyy, CV_32F, kernely);
123
+
124
+ cv::Mat f = vxx + vyy;
125
+
126
+ cv::Mat boundaryMask (rfg.size (), CV_8UC1);
127
+ cv::threshold (foregroundMask.getMat ()(rfg), boundaryMask, UNKNOWN, DIRICHLET_BD, cv::THRESH_BINARY_INV);
128
+ cv::rectangle (boundaryMask, cv::Rect (0 , 0 , boundaryMask.cols , boundaryMask.rows ), DIRICHLET_BD, 1 );
129
+
130
+ cv::Mat boundaryValues (rfg.size (), CV_MAKETYPE (CV_32F, background.channels ()));
131
+ background.getMat ()(rbg).convertTo (boundaryValues, CV_32F);
132
+ // Solve Poisson equation
133
+ cv::Mat result;
134
+ solvePoissonEquations (f,
135
+ boundaryMask,
136
+ boundaryValues,
137
+ result);
138
+
139
+ // Copy result to destination image.
140
+ result.convertTo (destination.getMat ()(rbg), CV_8U);
141
+ }
142
+
97
143
void seamlessClone (cv::InputArray background,
98
144
cv::InputArray foreground,
99
145
cv::InputArray foregroundMask,
@@ -126,27 +172,6 @@ void seamlessClone(cv::InputArray background,
126
172
127
173
cv::Mat foreValues (rfg.size (), CV_MAKETYPE (CV_32F, foreground.channels ()));
128
174
foreground.getMat ()(rfg).convertTo (foreValues, CV_32F);
129
- /*
130
- cv::Mat image = boundaryMask;
131
- int nr=image.rows;
132
- int nc=image.cols;
133
- if(image.isContinuous())
134
- {
135
- nr=1;
136
- nc=nc*image.rows*image.channels();
137
- }
138
- for(int i=0;i<nr;i++)
139
- {
140
- const uchar* inData=image.ptr<uchar>(i);
141
- for(int j=0;j<nc;j++)
142
- {
143
- std::cout<<int(*inData++)<<std::endl;
144
-
145
- }
146
- }
147
- */
148
-
149
-
150
175
151
176
// Solve Poisson equation
152
177
cv::Mat result;
0 commit comments