// Get the following Laplacian matrix // 0 1 0 // 1 -4 1 // 0 1 0 Mat PoissonBlending::getLaplacian() { Mat lap = Mat::zeros(3, 3, CV_32FC1); lap.ATF(0, 1) = 1.0; lap.ATF(1, 0) = 1.0; lap.ATF(1, 2) = 1.0; lap.ATF(2, 1) = 1.0; lap.ATF(1, 1) = -4.0; return lap; }
// get Matrix A. Mat PoissonBlending::getA(Mat &roiMask,vector<Point> &Points) { Mat A = Mat::eye(Points.size(), Points.size(), CV_32FC1); A *= -4; #pragma omp parallel for for (int i = 0; i < A.rows; i++) { #pragma omp parallel for for (int j = 0; j < A.cols; j++) { if (i == j) A.ATF(i, j) = -4.0; else if (isAdjacent(roiMask,Points, i, j)) { A.ATF(i, j) = 1.0; } } } return A; }
// Calculate b // using convolution. Mat PoissonBlending::getB1(Mat &src, Mat &dst, Mat &roiMask,vector<Point>&Points,Point loc, Rect ROI) { Mat lapMat; int mh = roiMask.rows; int mw = roiMask.cols; filter2D(src, lapMat, -1, getLaplacian()); Mat B = Mat::zeros(Points.size(), 1, CV_32FC1); for (int i = 0; i < Points.size(); i++) { Point pt = Points[i]; double tmp = 0.0; tmp = lapMat.ATF(ROI.y + pt.y, ROI.x + pt.x); if (pt.y>0 && roiMask.ATU(pt.y - 1, pt.x) != 255) tmp -= dst.ATF(pt.y + loc.y - 1, pt.x + loc.x); if (pt.y+1 <mh && roiMask.ATU(pt.y + 1, pt.x) != 255) tmp -= dst.ATF(pt.y + loc.y + 1, pt.x + loc.x); if (pt.x + 1<mw && roiMask.ATU(pt.y, pt.x + 1) != 255) tmp -= dst.ATF(pt.y + loc.y, pt.x + loc.x + 1); if (pt.x>0 && roiMask.ATU(pt.y , pt.x-1) != 255) tmp -= dst.ATF(pt.y + loc.y, pt.x + loc.x - 1); B.ATF(i, 0) = tmp; } return B; }
// Calculate b // using Gradients Mixing. Mat PoissonBlending::getB3(Mat &src, Mat &dst, Mat &roiMask, vector<Point>&Points, Point loc, Rect ROI) { Mat gradMat = getGradient(src) + getGradient(dst); int mh = roiMask.rows; int mw = roiMask.cols; Mat B = Mat::zeros(Points.size(), 1, CV_32FC1); for (int i = 0; i < Points.size(); i++) { Point pt = Points[i]; double tmp = 0.0; tmp = gradMat.ATF(ROI.y + pt.y, ROI.x + pt.x); if (pt.y>0 && roiMask.ATU(pt.y - 1, pt.x) != 255) tmp -= dst.ATF(pt.y + loc.y - 1, pt.x + loc.x); if (pt.y + 1<mh && roiMask.ATU(pt.y + 1, pt.x) != 255) tmp -= dst.ATF(pt.y + loc.y + 1, pt.x + loc.x); if (pt.x + 1<mw && roiMask.ATU(pt.y, pt.x + 1) != 255) tmp -= dst.ATF(pt.y + loc.y, pt.x + loc.x + 1); if (pt.x>0 && roiMask.ATU(pt.y, pt.x - 1) != 255) tmp -= dst.ATF(pt.y + loc.y, pt.x + loc.x - 1); B.ATF(i, 0) = tmp; } return B; }