Modify findTransformECC to support a mask of pixels to consider
Tests of the mask are also included. This is useful for registering a non-square image against a non-square template. This also needs to relax a sanity check as per https://github.com/Itseez/opencv/pull/3851
This commit is contained in:
@@ -317,7 +317,8 @@ double cv::findTransformECC(InputArray templateImage,
|
||||
InputArray inputImage,
|
||||
InputOutputArray warpMatrix,
|
||||
int motionType,
|
||||
TermCriteria criteria)
|
||||
TermCriteria criteria,
|
||||
InputArray inputMask)
|
||||
{
|
||||
|
||||
|
||||
@@ -397,13 +398,26 @@ double cv::findTransformECC(InputArray templateImage,
|
||||
Mat templateFloat = Mat(hs, ws, CV_32F);// to store the (smoothed) template
|
||||
Mat imageFloat = Mat(hd, wd, CV_32F);// to store the (smoothed) input image
|
||||
Mat imageWarped = Mat(hs, ws, CV_32F);// to store the warped zero-mean input image
|
||||
Mat allOnes = Mat::ones(hd, wd, CV_8U); //to use it for mask warping
|
||||
Mat imageMask = Mat(hs, ws, CV_8U); //to store the final mask
|
||||
|
||||
Mat inputMaskMat = inputMask.getMat();
|
||||
//to use it for mask warping
|
||||
Mat preMask =
|
||||
inputMaskMat.empty() ? Mat::ones(hd, wd, CV_8U) : inputMaskMat;
|
||||
|
||||
//gaussian filtering is optional
|
||||
src.convertTo(templateFloat, templateFloat.type());
|
||||
GaussianBlur(templateFloat, templateFloat, Size(5, 5), 0, 0);//is in-place filtering slower?
|
||||
|
||||
Mat preMaskFloat = Mat(hd, wd, CV_32F);
|
||||
preMask.convertTo(preMaskFloat, preMaskFloat.type());
|
||||
GaussianBlur(preMaskFloat, preMaskFloat, Size(5, 5), 0, 0);//is in-place filtering slower?
|
||||
// Change threshold.
|
||||
preMaskFloat *= (0.5/0.95);
|
||||
// Rounding conversion.
|
||||
preMaskFloat.convertTo(preMask, preMask.type());
|
||||
preMask.convertTo(preMaskFloat, preMaskFloat.type());
|
||||
|
||||
dst.convertTo(imageFloat, imageFloat.type());
|
||||
GaussianBlur(imageFloat, imageFloat, Size(5, 5), 0, 0);
|
||||
|
||||
@@ -420,6 +434,8 @@ double cv::findTransformECC(InputArray templateImage,
|
||||
filter2D(imageFloat, gradientX, -1, dx);
|
||||
filter2D(imageFloat, gradientY, -1, dx.t());
|
||||
|
||||
gradientX = gradientX.mul(preMaskFloat);
|
||||
gradientY = gradientY.mul(preMaskFloat);
|
||||
|
||||
// matrices needed for solving linear equation system for maximizing ECC
|
||||
Mat jacobian = Mat(hs, ws*numberOfParameters, CV_32F);
|
||||
@@ -449,22 +465,22 @@ double cv::findTransformECC(InputArray templateImage,
|
||||
warpAffine(imageFloat, imageWarped, map, imageWarped.size(), imageFlags);
|
||||
warpAffine(gradientX, gradientXWarped, map, gradientXWarped.size(), imageFlags);
|
||||
warpAffine(gradientY, gradientYWarped, map, gradientYWarped.size(), imageFlags);
|
||||
warpAffine(allOnes, imageMask, map, imageMask.size(), maskFlags);
|
||||
warpAffine(preMask, imageMask, map, imageMask.size(), maskFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
warpPerspective(imageFloat, imageWarped, map, imageWarped.size(), imageFlags);
|
||||
warpPerspective(gradientX, gradientXWarped, map, gradientXWarped.size(), imageFlags);
|
||||
warpPerspective(gradientY, gradientYWarped, map, gradientYWarped.size(), imageFlags);
|
||||
warpPerspective(allOnes, imageMask, map, imageMask.size(), maskFlags);
|
||||
warpPerspective(preMask, imageMask, map, imageMask.size(), maskFlags);
|
||||
}
|
||||
|
||||
|
||||
Scalar imgMean, imgStd, tmpMean, tmpStd;
|
||||
meanStdDev(imageWarped, imgMean, imgStd, imageMask);
|
||||
meanStdDev(templateFloat, tmpMean, tmpStd, imageMask);
|
||||
|
||||
subtract(imageWarped, imgMean, imageWarped, imageMask);//zero-mean input
|
||||
templateZM = Mat::zeros(templateZM.rows, templateZM.cols, templateZM.type());
|
||||
subtract(templateFloat, tmpMean, templateZM, imageMask);//zero-mean template
|
||||
|
||||
const double tmpNorm = std::sqrt(countNonZero(imageMask)*(tmpStd.val[0])*(tmpStd.val[0]));
|
||||
@@ -496,6 +512,9 @@ double cv::findTransformECC(InputArray templateImage,
|
||||
// calculate enhanced correlation coefficiont (ECC)->rho
|
||||
last_rho = rho;
|
||||
rho = correlation/(imgNorm*tmpNorm);
|
||||
if (isnan(rho)) {
|
||||
CV_Error(Error::StsNoConv, "NaN encountered.");
|
||||
}
|
||||
|
||||
// project images into jacobian
|
||||
project_onto_jacobian_ECC( jacobian, imageWarped, imageProjection);
|
||||
|
||||
Reference in New Issue
Block a user