mirror of
https://github.com/opencv/opencv.git
synced 2025-06-12 20:42:53 +08:00
Merge pull request #12220 from sturkmen72:update_seamless_cloning
This commit is contained in:
commit
828cb4286d
@ -62,12 +62,12 @@ void cv::seamlessClone(InputArray _src, InputArray _dst, InputArray _mask, Point
|
|||||||
int h = mask.size().height;
|
int h = mask.size().height;
|
||||||
int w = mask.size().width;
|
int w = mask.size().width;
|
||||||
|
|
||||||
Mat gray = Mat(mask.size(),CV_8UC1);
|
Mat gray;
|
||||||
|
|
||||||
if(mask.channels() == 3)
|
if(mask.channels() == 3)
|
||||||
cvtColor(mask, gray, COLOR_BGR2GRAY );
|
cvtColor(mask, gray, COLOR_BGR2GRAY );
|
||||||
else
|
else
|
||||||
gray = mask;
|
mask.copyTo(gray);
|
||||||
|
|
||||||
for(int i=0;i<h;i++)
|
for(int i=0;i<h;i++)
|
||||||
{
|
{
|
||||||
@ -105,7 +105,7 @@ void cv::seamlessClone(InputArray _src, InputArray _dst, InputArray _mask, Point
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::colorChange(InputArray _src, InputArray _mask, OutputArray _dst, float r, float g, float b)
|
void cv::colorChange(InputArray _src, InputArray _mask, OutputArray _dst, float red, float green, float blue)
|
||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION()
|
CV_INSTRUMENT_REGION()
|
||||||
|
|
||||||
@ -114,18 +114,12 @@ void cv::colorChange(InputArray _src, InputArray _mask, OutputArray _dst, float
|
|||||||
_dst.create(src.size(), src.type());
|
_dst.create(src.size(), src.type());
|
||||||
Mat blend = _dst.getMat();
|
Mat blend = _dst.getMat();
|
||||||
|
|
||||||
float red = r;
|
Mat gray, cs_mask;
|
||||||
float green = g;
|
|
||||||
float blue = b;
|
|
||||||
|
|
||||||
Mat gray = Mat::zeros(mask.size(),CV_8UC1);
|
|
||||||
|
|
||||||
if(mask.channels() == 3)
|
if(mask.channels() == 3)
|
||||||
cvtColor(mask, gray, COLOR_BGR2GRAY );
|
cvtColor(mask, gray, COLOR_BGR2GRAY );
|
||||||
else
|
else
|
||||||
gray = mask;
|
mask.copyTo(gray);
|
||||||
|
|
||||||
Mat cs_mask = Mat::zeros(src.size(),CV_8UC3);
|
|
||||||
|
|
||||||
src.copyTo(cs_mask,gray);
|
src.copyTo(cs_mask,gray);
|
||||||
|
|
||||||
@ -133,26 +127,21 @@ void cv::colorChange(InputArray _src, InputArray _mask, OutputArray _dst, float
|
|||||||
obj.localColorChange(src,cs_mask,gray,blend,red,green,blue);
|
obj.localColorChange(src,cs_mask,gray,blend,red,green,blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::illuminationChange(InputArray _src, InputArray _mask, OutputArray _dst, float a, float b)
|
void cv::illuminationChange(InputArray _src, InputArray _mask, OutputArray _dst, float alpha, float beta)
|
||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION()
|
CV_INSTRUMENT_REGION()
|
||||||
|
|
||||||
|
|
||||||
Mat src = _src.getMat();
|
Mat src = _src.getMat();
|
||||||
Mat mask = _mask.getMat();
|
Mat mask = _mask.getMat();
|
||||||
_dst.create(src.size(), src.type());
|
_dst.create(src.size(), src.type());
|
||||||
Mat blend = _dst.getMat();
|
Mat blend = _dst.getMat();
|
||||||
float alpha = a;
|
|
||||||
float beta = b;
|
|
||||||
|
|
||||||
Mat gray = Mat::zeros(mask.size(),CV_8UC1);
|
Mat gray, cs_mask;
|
||||||
|
|
||||||
if(mask.channels() == 3)
|
if(mask.channels() == 3)
|
||||||
cvtColor(mask, gray, COLOR_BGR2GRAY );
|
cvtColor(mask, gray, COLOR_BGR2GRAY );
|
||||||
else
|
else
|
||||||
gray = mask;
|
mask.copyTo(gray);
|
||||||
|
|
||||||
Mat cs_mask = Mat::zeros(src.size(),CV_8UC3);
|
|
||||||
|
|
||||||
src.copyTo(cs_mask,gray);
|
src.copyTo(cs_mask,gray);
|
||||||
|
|
||||||
@ -166,20 +155,16 @@ void cv::textureFlattening(InputArray _src, InputArray _mask, OutputArray _dst,
|
|||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION()
|
CV_INSTRUMENT_REGION()
|
||||||
|
|
||||||
|
|
||||||
Mat src = _src.getMat();
|
Mat src = _src.getMat();
|
||||||
Mat mask = _mask.getMat();
|
Mat mask = _mask.getMat();
|
||||||
_dst.create(src.size(), src.type());
|
_dst.create(src.size(), src.type());
|
||||||
Mat blend = _dst.getMat();
|
Mat blend = _dst.getMat();
|
||||||
|
Mat gray, cs_mask;
|
||||||
Mat gray = Mat::zeros(mask.size(),CV_8UC1);
|
|
||||||
|
|
||||||
if(mask.channels() == 3)
|
if(mask.channels() == 3)
|
||||||
cvtColor(mask, gray, COLOR_BGR2GRAY );
|
cvtColor(mask, gray, COLOR_BGR2GRAY );
|
||||||
else
|
else
|
||||||
gray = mask;
|
mask.copyTo(gray);
|
||||||
|
|
||||||
Mat cs_mask = Mat::zeros(src.size(),CV_8UC3);
|
|
||||||
|
|
||||||
src.copyTo(cs_mask,gray);
|
src.copyTo(cs_mask,gray);
|
||||||
|
|
||||||
|
@ -66,7 +66,6 @@ namespace cv
|
|||||||
void poisson(const cv::Mat &destination);
|
void poisson(const cv::Mat &destination);
|
||||||
void evaluate(const cv::Mat &I, const cv::Mat &wmask, const cv::Mat &cloned);
|
void evaluate(const cv::Mat &I, const cv::Mat &wmask, const cv::Mat &cloned);
|
||||||
void dst(const Mat& src, Mat& dest, bool invert = false);
|
void dst(const Mat& src, Mat& dest, bool invert = false);
|
||||||
void idst(const Mat& src, Mat& dest);
|
|
||||||
void solve(const Mat &img, Mat& mod_diff, Mat &result);
|
void solve(const Mat &img, Mat& mod_diff, Mat &result);
|
||||||
|
|
||||||
void poissonSolver(const cv::Mat &img, cv::Mat &gxx , cv::Mat &gyy, cv::Mat &result);
|
void poissonSolver(const cv::Mat &img, cv::Mat &gxx , cv::Mat &gyy, cv::Mat &result);
|
||||||
|
@ -147,15 +147,9 @@ void Cloning::dst(const Mat& src, Mat& dest, bool invert)
|
|||||||
split(complex, planes2);
|
split(complex, planes2);
|
||||||
|
|
||||||
temp = planes2[1].t();
|
temp = planes2[1].t();
|
||||||
dest = Mat::zeros(src.size(), CV_32F);
|
|
||||||
temp(Rect( 0, 1, src.cols, src.rows)).copyTo(dest);
|
temp(Rect( 0, 1, src.cols, src.rows)).copyTo(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cloning::idst(const Mat& src, Mat& dest)
|
|
||||||
{
|
|
||||||
dst(src, dest, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cloning::solve(const Mat &img, Mat& mod_diff, Mat &result)
|
void Cloning::solve(const Mat &img, Mat& mod_diff, Mat &result)
|
||||||
{
|
{
|
||||||
const int w = img.cols;
|
const int w = img.cols;
|
||||||
@ -173,7 +167,7 @@ void Cloning::solve(const Mat &img, Mat& mod_diff, Mat &result)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
idst(res, mod_diff);
|
dst(res, mod_diff, true);
|
||||||
|
|
||||||
unsigned char * resLinePtr = result.ptr<unsigned char>(0);
|
unsigned char * resLinePtr = result.ptr<unsigned char>(0);
|
||||||
const unsigned char * imgLinePtr = img.ptr<unsigned char>(0);
|
const unsigned char * imgLinePtr = img.ptr<unsigned char>(0);
|
||||||
@ -221,9 +215,7 @@ void Cloning::poissonSolver(const Mat &img, Mat &laplacianX , Mat &laplacianY, M
|
|||||||
const int w = img.cols;
|
const int w = img.cols;
|
||||||
const int h = img.rows;
|
const int h = img.rows;
|
||||||
|
|
||||||
Mat lap = Mat(img.size(),CV_32FC1);
|
Mat lap = laplacianX + laplacianY;
|
||||||
|
|
||||||
lap = laplacianX + laplacianY;
|
|
||||||
|
|
||||||
Mat bound = img.clone();
|
Mat bound = img.clone();
|
||||||
|
|
||||||
@ -264,19 +256,19 @@ void Cloning::initVariables(const Mat &destination, const Mat &binaryMask)
|
|||||||
|
|
||||||
void Cloning::computeDerivatives(const Mat& destination, const Mat &patch, const Mat &binaryMask)
|
void Cloning::computeDerivatives(const Mat& destination, const Mat &patch, const Mat &binaryMask)
|
||||||
{
|
{
|
||||||
initVariables(destination,binaryMask);
|
initVariables(destination, binaryMask);
|
||||||
|
|
||||||
computeGradientX(destination,destinationGradientX);
|
computeGradientX(destination, destinationGradientX);
|
||||||
computeGradientY(destination,destinationGradientY);
|
computeGradientY(destination, destinationGradientY);
|
||||||
|
|
||||||
computeGradientX(patch,patchGradientX);
|
computeGradientX(patch, patchGradientX);
|
||||||
computeGradientY(patch,patchGradientY);
|
computeGradientY(patch, patchGradientY);
|
||||||
|
|
||||||
Mat Kernel(Size(3, 3), CV_8UC1);
|
Mat Kernel(Size(3, 3), CV_8UC1);
|
||||||
Kernel.setTo(Scalar(1));
|
Kernel.setTo(Scalar(1));
|
||||||
erode(binaryMask, binaryMask, Kernel, Point(-1,-1), 3);
|
erode(binaryMask, binaryMask, Kernel, Point(-1,-1), 3);
|
||||||
|
|
||||||
binaryMask.convertTo(binaryMaskFloat,CV_32FC1,1.0/255.0);
|
binaryMask.convertTo(binaryMaskFloat, CV_32FC1, 1.0/255.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cloning::scalarProduct(Mat mat, float r, float g, float b)
|
void Cloning::scalarProduct(Mat mat, float r, float g, float b)
|
||||||
@ -305,11 +297,8 @@ void Cloning::arrayProduct(const cv::Mat& lhs, const cv::Mat& rhs, cv::Mat& resu
|
|||||||
|
|
||||||
void Cloning::poisson(const Mat &destination)
|
void Cloning::poisson(const Mat &destination)
|
||||||
{
|
{
|
||||||
Mat laplacianX = Mat(destination.size(),CV_32FC3);
|
Mat laplacianX = destinationGradientX + patchGradientX;
|
||||||
Mat laplacianY = Mat(destination.size(),CV_32FC3);
|
Mat laplacianY = destinationGradientY + patchGradientY;
|
||||||
|
|
||||||
laplacianX = destinationGradientX + patchGradientX;
|
|
||||||
laplacianY = destinationGradientY + patchGradientY;
|
|
||||||
|
|
||||||
computeLaplacianX(laplacianX,laplacianX);
|
computeLaplacianX(laplacianX,laplacianX);
|
||||||
computeLaplacianY(laplacianY,laplacianY);
|
computeLaplacianY(laplacianY,laplacianY);
|
||||||
@ -331,8 +320,8 @@ void Cloning::evaluate(const Mat &I, const Mat &wmask, const Mat &cloned)
|
|||||||
|
|
||||||
wmask.convertTo(binaryMaskFloatInverted,CV_32FC1,1.0/255.0);
|
wmask.convertTo(binaryMaskFloatInverted,CV_32FC1,1.0/255.0);
|
||||||
|
|
||||||
arrayProduct(destinationGradientX,binaryMaskFloatInverted, destinationGradientX);
|
arrayProduct(destinationGradientX, binaryMaskFloatInverted, destinationGradientX);
|
||||||
arrayProduct(destinationGradientY,binaryMaskFloatInverted, destinationGradientY);
|
arrayProduct(destinationGradientY, binaryMaskFloatInverted, destinationGradientY);
|
||||||
|
|
||||||
poisson(I);
|
poisson(I);
|
||||||
|
|
||||||
@ -351,8 +340,8 @@ void Cloning::normalClone(const Mat &destination, const Mat &patch, const Mat &b
|
|||||||
switch(flag)
|
switch(flag)
|
||||||
{
|
{
|
||||||
case NORMAL_CLONE:
|
case NORMAL_CLONE:
|
||||||
arrayProduct(patchGradientX,binaryMaskFloat, patchGradientX);
|
arrayProduct(patchGradientX, binaryMaskFloat, patchGradientX);
|
||||||
arrayProduct(patchGradientY,binaryMaskFloat, patchGradientY);
|
arrayProduct(patchGradientY, binaryMaskFloat, patchGradientY);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIXED_CLONE:
|
case MIXED_CLONE:
|
||||||
@ -392,7 +381,7 @@ void Cloning::normalClone(const Mat &destination, const Mat &patch, const Mat &b
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MONOCHROME_TRANSFER:
|
case MONOCHROME_TRANSFER:
|
||||||
Mat gray = Mat(patch.size(),CV_8UC1);
|
Mat gray;
|
||||||
cvtColor(patch, gray, COLOR_BGR2GRAY );
|
cvtColor(patch, gray, COLOR_BGR2GRAY );
|
||||||
|
|
||||||
computeGradientX(gray,patchGradientX);
|
computeGradientX(gray,patchGradientX);
|
||||||
@ -429,7 +418,7 @@ void Cloning::illuminationChange(Mat &I, Mat &mask, Mat &wmask, Mat &cloned, flo
|
|||||||
arrayProduct(patchGradientX,binaryMaskFloat, patchGradientX);
|
arrayProduct(patchGradientX,binaryMaskFloat, patchGradientX);
|
||||||
arrayProduct(patchGradientY,binaryMaskFloat, patchGradientY);
|
arrayProduct(patchGradientY,binaryMaskFloat, patchGradientY);
|
||||||
|
|
||||||
Mat mag = Mat(I.size(),CV_32FC3);
|
Mat mag;
|
||||||
magnitude(patchGradientX,patchGradientY,mag);
|
magnitude(patchGradientX,patchGradientY,mag);
|
||||||
|
|
||||||
Mat multX, multY, multx_temp, multy_temp;
|
Mat multX, multY, multx_temp, multy_temp;
|
||||||
@ -457,11 +446,10 @@ void Cloning::textureFlatten(Mat &I, Mat &mask, Mat &wmask, float low_threshold,
|
|||||||
{
|
{
|
||||||
computeDerivatives(I,mask,wmask);
|
computeDerivatives(I,mask,wmask);
|
||||||
|
|
||||||
Mat out = Mat(mask.size(),CV_8UC1);
|
Mat out;
|
||||||
Canny(mask,out,low_threshold,high_threshold,kernel_size);
|
Canny(mask,out,low_threshold,high_threshold,kernel_size);
|
||||||
|
|
||||||
Mat zeros(patchGradientX.size(), CV_32FC3);
|
Mat zeros = Mat::zeros(patchGradientX.size(), CV_32FC3);
|
||||||
zeros.setTo(0);
|
|
||||||
Mat zerosMask = (out != 255);
|
Mat zerosMask = (out != 255);
|
||||||
zeros.copyTo(patchGradientX, zerosMask);
|
zeros.copyTo(patchGradientX, zerosMask);
|
||||||
zeros.copyTo(patchGradientY, zerosMask);
|
zeros.copyTo(patchGradientY, zerosMask);
|
||||||
|
Loading…
Reference in New Issue
Block a user