Skip to content

Commit 2e70bb1

Browse files
the last commit to the program
1 parent 5220a9f commit 2e70bb1

33 files changed

+417
-48
lines changed

clone.cpp

+47-22
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,53 @@ void computeWeightedGradientVectorField(cv::InputArray background,
9393
cv::addWeighted(vyf, weightForeground, vyb, 1.f - weightForeground, 0, vy);
9494
}
9595

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+
97143
void seamlessClone(cv::InputArray background,
98144
cv::InputArray foreground,
99145
cv::InputArray foregroundMask,
@@ -126,27 +172,6 @@ void seamlessClone(cv::InputArray background,
126172

127173
cv::Mat foreValues(rfg.size(), CV_MAKETYPE(CV_32F, foreground.channels()));
128174
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-
150175

151176
// Solve Poisson equation
152177
cv::Mat result;

clone.h

+7
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,12 @@ void seamlessClone(cv::InputArray background,
6767
cv::OutputArray destination,
6868
CloneType type);
6969

70+
void seamlessCloneNaive(cv::InputArray background,
71+
cv::InputArray foreground,
72+
cv::InputArray foregroundMask,
73+
int offsetX,
74+
int offsetY,
75+
cv::OutputArray destination,
76+
CloneType type);
7077

7178
#endif

0 commit comments

Comments
 (0)